diff --git a/rce/Makefile b/rce/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3f5e59c4cb5cb8982b8d2b31fe016dec5db82de4 --- /dev/null +++ b/rce/Makefile @@ -0,0 +1,9 @@ + +include Makefile.inc +default: .server .gpib +clean: + rm -rf $(RELEASE_DIR)/build + + + + diff --git a/rce/Makefile.inc b/rce/Makefile.inc new file mode 100644 index 0000000000000000000000000000000000000000..b6044202ad1bc792f1c37e3d85db5fe98a642b0f --- /dev/null +++ b/rce/Makefile.inc @@ -0,0 +1,64 @@ +# Checks +# ------ +# Check release location variables +# number of parallel make jobs +ifneq ($(JOBS),) +JOBS:=16 +endif + +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD) +endif + +export RCE_CORE := /daq/slc5/opt/rcecore/$(RCE_CORE_VERSION) +# Includes +# -------- + +ifeq ($(RCE_CORE_VERSION),2.2) +.coredep: + mkdir -p $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/configuration $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/oldPpi $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/platform $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/service $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/tool $(RELEASE_DIR)/build +else +.coredep: + mkdir -p $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/rce $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/rceusr $(RELEASE_DIR)/build + ln -sfn $(RCE_CORE)/build/rceapp $(RELEASE_DIR)/build +endif + + + +.softlinks: .coredep + ln -sfn $(RTEMS) $(RELEASE_DIR)/build/rtems + ln -sfn $(ROOTSYS) $(RELEASE_DIR)/build + +.idl: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/idl $(RCE_ARCH) $(HOST_ARCH) + + + +.HW: .softlinks .idl + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/HW $(RCE_ARCH) $(HOST_ARCH) +.eudaq: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/eudaq $(RCE_ARCH) $(HOST_ARCH) +.dataproc: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/dataproc $(RCE_ARCH) $(HOST_ARCH) +.profiler: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/profiler $(RCE_ARCH) $(HOST_ARCH) +.scanctrl: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/scanctrl $(RCE_ARCH) $(HOST_ARCH) +.analysis: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/analysis $(RCE_ARCH) $(HOST_ARCH) +.config: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/config $(RCE_ARCH) $(HOST_ARCH) +.util: + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/util $(RCE_ARCH) $(HOST_ARCH) +.server: .HW .eudaq .dataproc .profiler .scanctrl .analysis .config .util + +$(MAKE) -j$(JOBS) -C $(RELEASE_DIR)/rcecalib/server $(RCE_ARCH) $(HOST_ARCH) +.gpib: .server + +$(MAKE) -j$(JOBS) -C rcedcs/gpib $(HOST_ARCH) +# +$(MAKE) -j$(JOBS) $(RELEASE_DIR)/rcedcs/labjack $(HOST_ARCH) diff --git a/rce/Makefile_nonparallel b/rce/Makefile_nonparallel new file mode 100644 index 0000000000000000000000000000000000000000..dd8ec9b9e60c6728e23c5106566ebed34cfeca68 --- /dev/null +++ b/rce/Makefile_nonparallel @@ -0,0 +1,40 @@ +# Top level makefile +# ------------------ +%.mk:; + + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD) +endif + + + +export RCE_CORE := /daq/slc5/opt/rcecore/$(RCE_CORE_VERSION) + +all: + $(MAKE) $(RCE_ARCH) $(HOST_ARCH) +clean: + $(MAKE) $(RCE_ARCH).clean $(HOST_ARCH).clean + + + +# Includes +# -------- +include make/share/setup.mk +include projects.mk +include make/share/release.mk + + + +#doxygen target +doxygen: + cd doxygen; doxygen Doxyfile + +.PHONY: doxygen + + + + diff --git a/rce/fw-hsio/.gitignore b/rce/fw-hsio/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..567609b1234a9b8806c5a05da6c866e480aa148d --- /dev/null +++ b/rce/fw-hsio/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/rce/fw-hsio/Readme.txt b/rce/fw-hsio/Readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..dbc0d2afbe6715c286cd0bdf0381a1d677b7da40 --- /dev/null +++ b/rce/fw-hsio/Readme.txt @@ -0,0 +1,23 @@ +This is the COB DPM top level directory. + +The modules directory contains the generic modules +that are used in multiple DPM projects. + +The projects directory contains the specific design +files for each DPM project. + +The top level generic makefile 'system.mk' is contained +in this directory. + +In order to build a project go to the project's directory +and type gmake. See the Readme.txt file in the project +directory for more information. + +A local build directory must be created in order to compile designs. +The build directory can either be a local directory or a link to +a directory located on a scratch disk: + +mkdir build +or +ln -s /u1/build build + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_adder_16_16.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_adder_16_16.xco new file mode 100644 index 0000000000000000000000000000000000000000..31dc5fd5935830cfed09e1c69ea6dfd4ad868906 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_adder_16_16.xco @@ -0,0 +1,66 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Oct 30 22:57:30 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Adder_Subtracter family Xilinx,_Inc. 7.0 +# END Select +# BEGIN Parameters +CSET async_init_value=0 +CSET asynchronous_settings=none +CSET bypass=false +CSET bypass_sense=active_high +CSET carry_borrow_input=false +CSET carry_borrow_output=false +CSET ce_override_for_bypass=true +CSET ce_overrides=sync_controls_override_ce +CSET clock_enable=false +CSET component_name=pgp_adder_16_16 +CSET create_rpm=true +CSET latency=0 +CSET operation=add +CSET output_options=non_registered +CSET output_width=16 +CSET overflow_output=false +CSET port_a_sign=unsigned +CSET port_a_width=16 +CSET port_b_constant=false +CSET port_b_constant_value=0 +CSET port_b_sign=unsigned +CSET port_b_width=16 +CSET set_clear_priority=clear_overrides_set +CSET sync_init_value=0 +CSET synchronous_settings=none +# END Parameters +GENERATE +# CRC: 9fee80ef + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_afifo_20x511.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_afifo_20x511.xco new file mode 100644 index 0000000000000000000000000000000000000000..10983cac509ffea305d524a6b0cad183a3e0def8 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_afifo_20x511.xco @@ -0,0 +1,77 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Oct 30 23:01:31 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 3.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp_afifo_20x511 +CSET data_count=false +CSET data_count_width=9 +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_threshold_assert_value=510 +CSET full_threshold_negate_value=509 +CSET input_data_width=20 +CSET input_depth=512 +CSET output_data_width=20 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=100 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=100 +CSET write_data_count=true +CSET write_data_count_width=9 +# END Parameters +GENERATE +# CRC: ace9941 + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_dpram_51x256.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_dpram_51x256.xco new file mode 100644 index 0000000000000000000000000000000000000000..9f170a6c2e5cd3d8348e67bff259098bc3806737 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_dpram_51x256.xco @@ -0,0 +1,75 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Oct 30 23:04:53 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Dual_Port_Block_Memory family Xilinx,_Inc. 6.3 +# END Select +# BEGIN Parameters +CSET component_name=pgp_dpram_51x256 +CSET configuration_port_a=Write_Only +CSET configuration_port_b=Read_And_Write +CSET depth_a=256 +CSET depth_b=256 +CSET disable_warning_messages=true +CSET global_init_value=0 +CSET load_init_file=false +CSET port_a_active_clock_edge=Rising_Edge_Triggered +CSET port_a_additional_output_pipe_stages=0 +CSET port_a_enable_pin=false +CSET port_a_enable_pin_polarity=Active_High +CSET port_a_handshaking_pins=false +CSET port_a_init_pin=false +CSET port_a_init_value=0 +CSET port_a_initialization_pin_polarity=Active_High +CSET port_a_register_inputs=false +CSET port_a_write_enable_polarity=Active_High +CSET port_b_active_clock_edge=Rising_Edge_Triggered +CSET port_b_additional_output_pipe_stages=0 +CSET port_b_enable_pin=false +CSET port_b_enable_pin_polarity=Active_High +CSET port_b_handshaking_pins=false +CSET port_b_init_pin=false +CSET port_b_init_value=0 +CSET port_b_initialization_pin_polarity=Active_High +CSET port_b_register_inputs=false +CSET port_b_write_enable_polarity=Active_High +CSET primitive_selection=Optimize_For_Area +CSET select_primitive=32kx1 +CSET width_a=51 +CSET width_b=51 +CSET write_mode_port_a=Read_After_Write +CSET write_mode_port_b=Read_After_Write +# END Parameters +GENERATE +# CRC: 3d2f768 + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_20x512.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_20x512.xco new file mode 100644 index 0000000000000000000000000000000000000000..532c8358e8d5abbf85157952bd45a0aa6eb7530b --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_20x512.xco @@ -0,0 +1,77 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Nov 27 21:31:02 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 3.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp_fifo_20x512 +CSET data_count=true +CSET data_count_width=9 +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_threshold_assert_value=510 +CSET full_threshold_negate_value=509 +CSET input_data_width=20 +CSET input_depth=512 +CSET output_data_width=20 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=100 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=100 +CSET write_data_count=false +CSET write_data_count_width=9 +# END Parameters +GENERATE +# CRC: ff734927 + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_21x512.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_21x512.xco new file mode 100644 index 0000000000000000000000000000000000000000..e796c930e2d678e680e9cbaa5eab2e5bffe67581 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_21x512.xco @@ -0,0 +1,77 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Nov 20 21:00:35 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 3.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp_fifo_21x512 +CSET data_count=true +CSET data_count_width=9 +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_threshold_assert_value=510 +CSET full_threshold_negate_value=509 +CSET input_data_width=21 +CSET input_depth=512 +CSET output_data_width=21 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=100 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=100 +CSET write_data_count=false +CSET write_data_count_width=9 +# END Parameters +GENERATE +# CRC: fc18e96b + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_8x256.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_8x256.xco new file mode 100644 index 0000000000000000000000000000000000000000..63ac4e4cc03fc910b6ffbfff3ff835c03fb10c69 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_8x256.xco @@ -0,0 +1,77 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Oct 30 23:11:26 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 3.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp_fifo_8x256 +CSET data_count=false +CSET data_count_width=8 +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_threshold_assert_value=254 +CSET full_threshold_negate_value=253 +CSET input_data_width=8 +CSET input_depth=256 +CSET output_data_width=8 +CSET output_depth=256 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=100 +CSET read_data_count=false +CSET read_data_count_width=8 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=100 +CSET write_data_count=false +CSET write_data_count_width=8 +# END Parameters +GENERATE +# CRC: 6c912950 + diff --git a/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_9x256.xco b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_9x256.xco new file mode 100644 index 0000000000000000000000000000000000000000..b22d04ece0753a755bde53f386a3567b2a41c13f --- /dev/null +++ b/rce/fw-hsio/modules/pgp/coregen/pgp_fifo_9x256.xco @@ -0,0 +1,77 @@ +############################################################## +# +# Xilinx Core Generator version IP3_J.9 +# Date: Tue Oct 30 23:13:10 2007 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 3.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp_fifo_9x256 +CSET data_count=false +CSET data_count_width=8 +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_threshold_assert_value=254 +CSET full_threshold_negate_value=253 +CSET input_data_width=9 +CSET input_depth=256 +CSET output_data_width=9 +CSET output_depth=256 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=100 +CSET read_data_count=false +CSET read_data_count_width=8 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=100 +CSET write_data_count=false +CSET write_data_count_width=8 +# END Parameters +GENERATE +# CRC: 6aa03d9 + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpAckRx.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpAckRx.vhd new file mode 100644 index 0000000000000000000000000000000000000000..61fb19a8d0d39e6f50987d1c57004afa1ba5a092 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpAckRx.vhd @@ -0,0 +1,759 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, ACK/NACK Receive & Timer Logic +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpAckRx.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- ACK/NACK receive module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 06/15/2007: Added register state before ACK FIFO. Needed for timing. +-- 07/25/2007: Changed cell CRC error to cell receive error. +-- 09/21/2007: Ack timeout converted to generic. +-- 09/29/2007: Changed name of coregen blocks +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpAckRx is + generic ( + AckTimeout : natural := 8 -- Ack/Nack Not Received Timeout, 8.192uS Steps + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- PIB Interface + pibLinkReady : in std_logic; -- PIB Link Ready + + -- Error Indication + seqFifoEmpty : out std_logic; -- Sequence number fifo is empty + nackCountInc : out std_logic; -- Nack received count increment + + -- Cell Receiver Interface + cellRxDone : in std_logic; -- Cell reception done + cellRxCellError : in std_logic; -- Cell receieve error + cellRxSeq : in std_logic_vector(7 downto 0); -- Cell receieve sequence + cellRxAck : in std_logic; -- Cell receieve ACK + cellRxNAck : in std_logic; -- Cell receieve NACK + + -- Transmit Schedular Interface + cidReady : out std_logic; -- CID Engine is ready + cidTimerStart : in std_logic; -- CID timer start + cellTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + cidSave : in std_logic; -- CID value store signal + + -- Cell Transmit logic + cellTxSOF : in std_logic; -- Cell contained SOF + cellTxDataSeq : out std_logic_vector(7 downto 0); -- Transmit sequence number + + -- User logic interface + vc0FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc0FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc0FrameTxAck : out std_logic; -- PGP ACK/NACK + vc1FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc1FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc1FrameTxAck : out std_logic; -- PGP ACK/NACK + vc2FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc2FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc2FrameTxAck : out std_logic; -- PGP ACK/NACK + vc3FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc3FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc3FrameTxAck : out std_logic -- PGP ACK/NACK + ); + +end PgpAckRx; + + +-- Define architecture +architecture PgpAckRx of PgpAckRx is + + -- Active context ID memory + component pgp_dpram_51x256 port ( + addra: IN std_logic_VECTOR(7 downto 0); + addrb: IN std_logic_VECTOR(7 downto 0); + clka: IN std_logic; + clkb: IN std_logic; + dina: IN std_logic_VECTOR(50 downto 0); + dinb: IN std_logic_VECTOR(50 downto 0); + doutb: OUT std_logic_VECTOR(50 downto 0); + wea: IN std_logic; + web: IN std_logic + ); end component; + + -- Seq number FIFO + component pgp_fifo_8x256 port ( + clk: IN std_logic; + rst: IN std_logic; + din: IN std_logic_VECTOR(7 downto 0); + wr_en: IN std_logic; + rd_en: IN std_logic; + dout: OUT std_logic_VECTOR(7 downto 0); + full: OUT std_logic; + empty: OUT std_logic + ); end component; + + -- Adder 16+16=16 + component pgp_adder_16_16 + port ( + A : IN std_logic_VECTOR(15 downto 0); + B : IN std_logic_VECTOR(15 downto 0); + S : OUT std_logic_VECTOR(15 downto 0) + ); + end component; + + + -- Local Signals + signal seqNumber : std_logic_vector(7 downto 0); + signal seqNumberInc : std_logic; + signal seqAddrSel : std_logic; + signal seqFifoDin : std_logic_vector(7 downto 0); + signal seqFifoWr : std_logic; + signal seqFifoRd : std_logic; + signal seqFifoRst : std_logic; + signal seqFifoDout : std_logic_vector(7 downto 0); + signal seqFifoDoutVal : std_logic; + signal seqFifoFull : std_logic; + signal intSeqFifoEmpty : std_logic; + signal intCidReady : std_logic; + signal startSeqNum : std_logic_vector(7 downto 0); + signal cidMemAddrA : std_logic_vector(7 downto 0); + signal cidMemAddrB : std_logic_vector(7 downto 0); + signal cidMemDinA : std_logic_vector(50 downto 0); + signal cidMemWrA : std_logic; + signal cidMemWrAReq : std_logic; + signal cidMemWrANext : std_logic; + signal cidMemWrB : std_logic; + signal cidMemRdB : std_logic; + signal cidMemDoutB : std_logic_vector(50 downto 0); + signal intFrameTxAckCid : std_logic_vector(31 downto 0); + signal intFrameTxAckEn : std_logic_vector(3 downto 0); + signal intFrameTxAck : std_logic; + signal nxtFrameTxAckEn : std_logic_vector(3 downto 0); + signal nxtFrameTxAck : std_logic; + signal seqRxFlag : std_logic; + signal dlyRxFlag : std_logic; + signal seqRxFlagClr : std_logic; + signal locCellRxSeq : std_logic_vector(7 downto 0); + signal locCellRxAck : std_logic; + signal ackTimer : std_logic_vector(15 downto 0); + signal ackTimerSum : std_logic_vector(15 downto 0); + signal ackTimerInc : std_logic; + signal muxVcSeq : std_logic_vector(7 downto 0); + signal intVc0Seq : std_logic_vector(7 downto 0); + signal intVc1Seq : std_logic_vector(7 downto 0); + signal intVc2Seq : std_logic_vector(7 downto 0); + signal intVc3Seq : std_logic_vector(7 downto 0); + signal muxFrameTxCid : std_logic_vector(31 downto 0); + signal cidSaveData : std_logic_vector(31 downto 0); + signal regFifoDin : std_logic_vector(7 downto 0); + signal regFifoWr : std_logic; + signal intTimeout : std_logic_vector(15 downto 0); + + -- Context state machine + signal seqState : std_logic_vector(7 downto 0); + signal nxtState : std_logic_vector(7 downto 0); + constant ST_INIT : std_logic_vector(7 downto 0) := "00000001"; + constant ST_WAIT : std_logic_vector(7 downto 0) := "00000010"; + constant ST_FILL : std_logic_vector(7 downto 0) := "00000100"; + constant ST_TIME_RD : std_logic_vector(7 downto 0) := "00001000"; + constant ST_TIME_CHK : std_logic_vector(7 downto 0) := "00010000"; + constant ST_ACK_RD : std_logic_vector(7 downto 0) := "00100000"; + constant ST_ACK_RET : std_logic_vector(7 downto 0) := "01000000"; + constant ST_CID_START : std_logic_vector(7 downto 0) := "10000000"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_dpram_51x256 : component is TRUE; + attribute syn_noprune of pgp_dpram_51x256 : component is TRUE; + attribute syn_black_box of pgp_fifo_8x256 : component is TRUE; + attribute syn_noprune of pgp_fifo_8x256 : component is TRUE; + attribute syn_black_box of pgp_adder_16_16 : component is TRUE; + attribute syn_noprune of pgp_adder_16_16 : component is TRUE; + +begin + + -- Convert Ack Timeout Value + intTimeout <= conv_std_logic_vector(AckTimeout,16); + + -- Sequence number FIFO is empty + seqFifoEmpty <= intSeqFifoEmpty; + cellTxDataSeq <= seqFifoDout; + + -- Nack counter increment + nackCountInc <= '0' when intFrameTxAckEn = "0000" else (not intFrameTxAck); + + -- CID FIFO is ready + cidReady <= seqFifoDoutVal; + + -- Context ID, VC 0 + vc0FrameTxAckCid <= intFrameTxAckCid; + vc0FrameTxAckEn <= intFrameTxAckEn(0); + vc0FrameTxAck <= intFrameTxAck; + + -- Context ID, VC 1 + vc1FrameTxAckCid <= intFrameTxAckCid; + vc1FrameTxAckEn <= intFrameTxAckEn(1); + vc1FrameTxAck <= intFrameTxAck; + + -- Context ID, VC 2 + vc2FrameTxAckCid <= intFrameTxAckCid; + vc2FrameTxAckEn <= intFrameTxAckEn(2); + vc2FrameTxAck <= intFrameTxAck; + + -- Context ID, VC 3 + vc3FrameTxAckCid <= intFrameTxAckCid; + vc3FrameTxAckEn <= intFrameTxAckEn(3); + vc3FrameTxAck <= intFrameTxAck; + + + -- Interface for sechedular to read available seq number values + -- from the seq number FIFO. Also provide interface for the + -- schedular to start the timer for a previously allocated sequence number. + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + seqFifoDoutVal <= '0' after tpd; + seqFifoRd <= '0' after tpd; + startSeqNum <= (others=>'0') after tpd; + cidMemDinA <= (others=>'0') after tpd; + cidMemWrA <= '0' after tpd; + cidMemWrAReq <= '0' after tpd; + intVc0Seq <= (others=>'0') after tpd; + intVc1Seq <= (others=>'0') after tpd; + intVc2Seq <= (others=>'0') after tpd; + intVc3Seq <= (others=>'0') after tpd; + cidSaveData <= (others=>'0') after tpd; + + elsif rising_edge(pgpClk) then + + -- Reset data out on link down + if intCidReady = '0' then + seqFifoDoutVal <= '0' after tpd; + seqFifoRd <= '0' after tpd; + + -- We just read from FIFO + elsif seqFifoRd = '1' then + seqFifoRd <= '0' after tpd; + seqFifoDoutVal <= '1' after tpd; + + -- Scheduler just read seq number + elsif cellTxSOF = '1' then + + -- Clear valid flag, read next sequence number + seqFifoDoutVal <= '0' after tpd; + seqFifoRd <= not intSeqFifoEmpty after tpd; + + -- Store sequence number associted with VC + case cellTxDataVc is + when "00" => intVc0Seq <= seqFifoDout after tpd; + when "01" => intVc1Seq <= seqFifoDout after tpd; + when "10" => intVc2Seq <= seqFifoDout after tpd; + when "11" => intVc3Seq <= seqFifoDout after tpd; + when others => + end case; + + -- Load next value if none is waiting + elsif seqFifoDoutVal = '0' then + seqFifoRd <= not intSeqFifoEmpty after tpd; + end if; + + -- Schedular is passing CID value at the start of a cell. Store the + -- data for now just in case this cell contains an EOF. + if cidSave = '1' then + cidSaveData <= muxFrameTxCid after tpd; + end if; + + -- Memory write occured, clear request + if cidMemWrA = '1' then + cidMemWrAReq <= '0' after tpd; + + -- Schedular has indicated that the timer should start for the + -- current VC. + elsif cidTimerStart = '1' then + startSeqNum <= muxVcSeq after tpd; + cidMemDinA(50) <= '1' after tpd; + cidMemDinA(49 downto 48) <= cellTxDataVc after tpd; + cidMemDinA(47 downto 32) <= ackTimerSum after tpd; + cidMemDinA(31 downto 0) <= cidSaveData after tpd; + cidMemWrAReq <= '1' after tpd; + end if; + + -- Drive write to memory when it is safe, one clock after timer read + cidMemWrA <= cidMemWrAReq and cidMemWrANext after tpd; + + end if; + end process; + + + -- Mux for vc related data + process (cellTxDataVc, intVc0Seq, intVc1Seq, intVc2Seq, intVc3Seq, + vc0FrameTxCid, vc1FrameTxCid, vc2FrameTxCid, vc3FrameTxCid ) begin + case cellTxDataVc is + when "00" => muxVcSeq <= intVc0Seq; muxFrameTxCid <= vc0FrameTxCid; + when "01" => muxVcSeq <= intVc1Seq; muxFrameTxCid <= vc1FrameTxCid; + when "10" => muxVcSeq <= intVc2Seq; muxFrameTxCid <= vc2FrameTxCid; + when "11" => muxVcSeq <= intVc3Seq; muxFrameTxCid <= vc3FrameTxCid; + when others => muxVcSeq <= (others=>'0'); muxFrameTxCid <= (others=>'0'); + end case; + end process; + + + -- Sequence number input state machine. This engine pre-fills the + -- sequence number FIFO when the link goes active, adds received + -- sequence numbers back into the FIFO, removes recieved sequence numbers + -- from the active context memory. This engine will also handle + -- timeouts for the currently active contexts. The timeout values for each + -- of the 256 memory locations are serviced once every 4 clocks. This results + -- in every timer processed every 1024 clocks or 8.192uS. + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + seqState <= ST_INIT after tpd; + seqRxFlag <= '0' after tpd; + dlyRxFlag <= '0' after tpd; + locCellRxSeq <= (others=>'0') after tpd; + locCellRxAck <= '0' after tpd; + seqNumber <= (others=>'0') after tpd; + ackTimer <= (others=>'0') after tpd; + intFrameTxAckCid <= (others=>'0') after tpd; + intFrameTxAck <= '0' after tpd; + intFrameTxAckEn <= "0000" after tpd; + + elsif rising_edge(pgpClk) then + + -- Force back to INIT state when link goes down + if pibLinkReady = '0' then + seqState <= ST_INIT after tpd; + + -- State transition + else + seqState <= nxtState after tpd; + end if; + + -- Clear sequence address value + if pibLinkReady = '0' then + seqNumber <= (others=>'0') after tpd; + + -- Increment address value + elsif seqNumberInc = '1' then + seqNumber <= seqNumber + 1 after tpd; + end if; + + -- Register ack/nack data passed from frame receiver. Mark + -- a flag to indicate pending request. Clear when state machine + -- processes. + if cellRxDone = '1' and cellRxCellError = '0' then + locCellRxSeq <= cellRxSeq after tpd; + locCellRxAck <= cellRxAck after tpd; + seqRxFlag <= cellRxAck or cellRxNack after tpd; + elsif seqRxFlagClr = '1' then + seqRxFlag <= '0' after tpd; + end if; + + -- Delayed copy of receive flag. This is needed to ensure we look at + -- the non delayed flag only once in the state machine. + dlyRxFlag <= seqRxFlag after tpd; + + -- Reset Ack timer + if pibLinkReady = '0' then + ackTimer <= (others=>'0') after tpd; + + -- Increment Ack timer value + elsif ackTimerInc = '1' then + ackTimer <= ackTimer + 1 after tpd; + end if; + + -- Drive outgoing CID ack/nack signals + intFrameTxAckCid <= cidMemDoutB(31 downto 0) after tpd; + intFrameTxAck <= nxtFrameTxAck after tpd; + intFrameTxAckEn <= nxtFrameTxAckEn after tpd; + + end if; + end process; + + + -- State transition control. The following signals are driven in each state: + -- intCidReady : Indicates to schedular that memory init is complete + -- seqFifoWr : Controls writes into the available seq number FIFO + -- cidMemWrB : Controls writes to context memory + -- cidMemRdB : Controls reads from context memory + -- seqAddrSel : Chooses between seq num counter (value=0) and returned seq number + -- seqNumberInc : Increment the seq number counter + -- seqRxFlagClr : Clear the flag indicating a seq number has been passed + -- nxtFrameTxAck : Next outgoing frame ack signal + -- nxtFrameTxAckEn : Next outgoing frame ack signal enable + -- ackTimerInc : Ack timer increment + -- nxtState : Defines which state to proceed to + process ( seqState, seqNumber, cidMemDoutB, ackTimer, + seqFifoFull, seqRxFlag, dlyRxFlag, locCellRxAck ) begin + case seqState is + + -- INIT conect memory and sequence FIFO + when ST_INIT => + + -- Not ready + intCidReady <= '0'; + + -- Fifo is being reset, no mem reads or writes + seqFifoWr <= '0'; + cidMemWrB <= '0'; + cidMemRdB <= '0'; + + -- Seq nubmer is being cleared. Clear any pending receive flags + seqAddrSel <= '0'; + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '1'; + + -- No ACK/NACK output + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Start fill of data + nxtState <= ST_WAIT; + + -- Wait for FIFO to be ready following reset + when ST_WAIT => + + -- Not ready + intCidReady <= '0'; + + -- No mem reads or writes + seqFifoWr <= '0'; + cidMemWrB <= '0'; + cidMemRdB <= '0'; + + -- Seq nubmer is being cleared. Clear any pending receive flags + seqAddrSel <= '0'; + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '0'; + + -- No ACK/NACK output + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Start fill of data when FIFO full flag de-asserts + if seqFifoFull = '0' then + nxtState <= ST_FILL; + else + nxtState <= seqState; + end if; + + -- Fill sequence FIFO and clear each context memory location + when ST_FILL => + + -- Not ready + intCidReady <= '0'; + + -- Store current count value into sequence number FIFO, clear context mem location + seqFifoWr <= '1'; + cidMemWrB <= '1'; + cidMemRdB <= '0'; + seqAddrSel <= '0'; + seqRxFlagClr <= '0'; + seqNumberInc <= '1'; + ackTimerInc <= '0'; + + -- No ACK/NACK output + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Stop after writing 256 bytes + if seqNumber = 255 then + nxtState <= ST_TIME_RD; + else + nxtState <= seqState; + end if; + + -- Read currnt timer value from current location + when ST_TIME_RD => + + -- Block is ready + intCidReady <= '1'; + + -- Read from current context memory location + seqAddrSel <= '0'; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + cidMemRdB <= '1'; + + -- Don't Increment sequence number + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '0'; + + -- No ACK/NACK output + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Go to check state + nxtState <= ST_TIME_CHK; + + -- Check for expired timer in current location + when ST_TIME_CHK => + + -- Block is ready + intCidReady <= '1'; + + -- No memory read + seqAddrSel <= '0'; + cidMemRdB <= '0'; + + -- Increment sequence number + seqNumberInc <= '1'; + seqRxFlagClr <= '0'; + + -- Increment timer if we just read from seq address 255 + if seqNumber = 255 then + ackTimerInc <= '1'; + else + ackTimerInc <= '0'; + end if; + + -- Entry is active and timer expire value matches + if cidMemDoutB(50) = '1' and cidMemDoutB(47 downto 32) = ackTimer(15 downto 0) then + + -- Drive nack output + nxtFrameTxAck <= '0'; + + -- Select dest for ack enable + case cidMemDoutB(49 downto 48) is + when "00" => nxtFrameTxAckEn <= "0001"; + when "01" => nxtFrameTxAckEn <= "0010"; + when "10" => nxtFrameTxAckEn <= "0100"; + when "11" => nxtFrameTxAckEn <= "1000"; + when others => nxtFrameTxAckEn <= "0000"; + end case; + + -- Return seq number to FIFO, Clear context memory + seqFifoWr <= '1'; + cidMemWrB <= '1'; + + -- No Timeout + else + + -- No NACK/ACK + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + end if; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Go to Ack received state + nxtState <= ST_ACK_RD; + + -- Read from context memory if pending ack is ready + when ST_ACK_RD => + + -- Block is ready + intCidReady <= '1'; + + -- Read from current context memory location if ack is pending + seqAddrSel <= '1'; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + cidMemRdB <= seqRxFlag; + + -- Don't Increment sequence number + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '0'; + + -- No ACK/NACK output + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Go to check return state + nxtState <= ST_ACK_RET; + + -- Return ack/nack to user if context memory location is active, clear + -- context memory location + when ST_ACK_RET => + + -- Block is ready + intCidReady <= '1'; + + -- No memory read, select return ack value as address + seqAddrSel <= '1'; + cidMemRdB <= '0'; + + -- No timer increments + seqNumberInc <= '0'; + ackTimerInc <= '0'; + + -- Clear rx flag if valid on previous clock + seqRxFlagClr <= dlyRxFlag; + + -- Entry is active and rx flag was valid on previous clock + if dlyRxFlag = '1' and cidMemDoutB(50) = '1' then + + -- Drive ack output + nxtFrameTxAck <= locCellRxAck; + + -- Select dest + case cidMemDoutB(49 downto 48) is + when "00" => nxtFrameTxAckEn <= "0001"; + when "01" => nxtFrameTxAckEn <= "0010"; + when "10" => nxtFrameTxAckEn <= "0100"; + when "11" => nxtFrameTxAckEn <= "1000"; + when others => nxtFrameTxAckEn <= "0000"; + end case; + + -- Return seq number to FIFO, Clear context memory + seqFifoWr <= '1'; + cidMemWrB <= '1'; + + -- Not Active + else + + -- No NACK/ACK + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + end if; + + -- CID Memory write enable + cidMemWrANext <= '0'; + + -- Go to Ack received state + nxtState <= ST_CID_START; + + + -- Timeslot for CID entry creation in memory through port A + when ST_CID_START => + + -- Block is ready + intCidReady <= '1'; + + -- No memory read or timer increments + seqAddrSel <= '0'; + cidMemRdB <= '0'; + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '0'; + + -- No NACK/ACK + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + + -- CID Memory write enable + cidMemWrANext <= '1'; + + -- Go to Ack received state + nxtState <= ST_TIME_RD; + + + -- Just in case + when others => + intCidReady <= '0'; + seqAddrSel <= '0'; + cidMemRdB <= '0'; + cidMemWrANext <= '0'; + seqNumberInc <= '0'; + ackTimerInc <= '0'; + seqRxFlagClr <= '0'; + nxtFrameTxAck <= '0'; + nxtFrameTxAckEn <= "0000"; + seqFifoWr <= '0'; + cidMemWrB <= '0'; + nxtState <= ST_INIT; + end case; + end process; + + + + -- Determine which address to use for FIFO input and context memory + -- port B. Chooses between running counter and returned sequence value. + -- Reset the FIFO when the link is not ready + seqFifoDin <= seqNumber when seqAddrSel = '0' else locCellRxSeq; + seqFifoRst <= not pibLinkReady; + + + -- Pipeline writes to FIFO, needed for timing purposes + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + regFifoDin <= (others=>'0') after tpd; + regFifoWr <= '0' after tpd; + elsif rising_edge(pgpClk) then + regFifoDin <= seqFifoDin after tpd; + regFifoWr <= seqFifoWr after tpd; + end if; + end process; + + + -- Sequence number FIFO + U_SeqNumFifo : pgp_fifo_8x256 port map ( + clk => pgpClk, rst => seqFifoRst, + din => regFifoDin, wr_en => regFifoWr, + rd_en => seqFifoRd, dout => seqFifoDout, + full => seqFifoFull, empty => intSeqFifoEmpty + ); + + + -- Keep addresses from lining up, addresses can never match in Xilinx DPRAM + cidMemAddrA <= startSeqNum when cidMemWrA = '1' else not seqFifoDin; + cidMemAddrB <= seqFifoDin when cidMemWrA = '0' else not startSeqNum; + + + -- Active context ID memory + -- Bits 31-0 = cidValue, bits 47-32 = cidTimer, bits 49-48 = VC num, bit 50 is en + -- Writes to port B will always be zero + U_CidMemory : pgp_dpram_51x256 port map ( + clka => pgpClk, clkb => pgpClk, + addra => cidMemAddrA, addrb => cidMemAddrB, + dina => cidMemDinA, dinb => (others=>'0'), + wea => cidMemWrA, web => cidMemWrB, + doutb => cidMemDoutB + ); + + + -- Adder to calculate timeout value for newly created context timers + U_TimerSum : pgp_adder_16_16 port map ( + A => ackTimer, + B => intTimeout, + S => ackTimerSum + ); + +end PgpAckRx; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpCellRx.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpCellRx.vhd new file mode 100755 index 0000000000000000000000000000000000000000..595a0c5203145479d2f8d1fbac4a729fb9e3d0f5 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpCellRx.vhd @@ -0,0 +1,719 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Cell Receive Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpCellRx.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Cell Receive interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 04/18/2007: Added support to track the number of cells in a frame to detect +-- dropped cells. +-- 04/19/2007: Set initial states of buffer status bits to bad +-- 07/19/2007: Removed support to track the number of cells in a frame to detect +-- dropped cells. +-- 07/25/2007: Added support to terminate in progress frames on missed cell. Also +-- added ability to detect missing cells. +-- 09/18/2007: Data is only output for a VC if the VC is currently in frame. +-- Abort flag from rx tracker will end a cell if SOF is received +-- for a VC that is already in frame. SOF of new frame is blocked. +-- 09/18/2007: Added forceCellSize signal to make sure all outgoing cells are +-- 512 bytes unless they are the last in a frame. Frame will be +-- ended with error if this occurs. +-- 09/19/2007: Changed force cell size signal to PIC mode signal +-- Add feature where the following cell after an errored cell will +-- be dropped as well. This ensures the PIC interface code has +-- enough clocks to abort all VCs. +-- 09/20/2007: Added fix so SOF is only aserted for received VC during certain +-- abort situations. SOF can only be asserted in a way that does not +-- violate the SOF-EOF ordering to external logic. +-- 09/21/2007: Converted PIC mode to generic. +-- 10/17/2007: CrcNotZero signal is now registered. +-- 10/24/2007: Fixed error where SOF was not clearing after first word. +-- 11/06/2007: Added cellRxShort flag to indicate to tracking logic that EOFE +-- was generated due to short cell. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpCellRx is + generic ( + PicMode : integer := 0 -- PIC Interface Mode, 1=PIC, 0=Normal + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + + -- Receive Tracking Block + cellRxSOF : out std_logic; -- Cell contained SOF + cellRxDataVc : out std_logic_vector(1 downto 0); -- Cell virtual channel + cellRxEOF : out std_logic; -- Cell contained EOF + cellRxEOFE : out std_logic; -- Cell contained EOFE + cellRxEmpty : out std_logic; -- Cell was empty + cellVcInFrame : in std_logic_vector(3 downto 0); -- Cell VC in frame status + cellVcAbort : in std_logic; -- Cell abort flag for current VC + cellRxStart : out std_logic; -- Cell reception start + cellRxDone : out std_logic; -- Cell reception done + cellRxCellError : out std_logic; -- Cell receieve CRC error + cellRxShort : out std_logic; -- Cell receieve is short (PIC Mode) + cellRxSeq : out std_logic_vector(7 downto 0); -- Cell receieve sequence + cellRxAck : out std_logic; -- Cell receieve ACK + cellRxNAck : out std_logic; -- Cell receieve NACK + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxWidth : out std_logic; -- PGP frame data width + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxWidth : out std_logic; -- PGP frame data width + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc2FrameRxWidth : out std_logic; -- PGP frame data width + vc2FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc2FrameRxEOFE : out std_logic; -- PGP frame data error + vc2FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc3FrameRxWidth : out std_logic; -- PGP frame data width + vc3FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc3FrameRxEOFE : out std_logic; -- PGP frame data error + vc3FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- Receive CRC Interface + crcRxIn : out std_logic_vector(15 downto 0); -- Receive data for CRC + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxWidth : out std_logic; -- Receive data for CRC width + crcRxOut : in std_logic_vector(31 downto 0); -- Receive calculated CRC value + + -- Cell Receive Interface + pibRxSOC : in std_logic; -- Cell data start of cell + pibRxWidth : in std_logic; -- Cell data width + pibRxEOC : in std_logic; -- Cell data end of cell + pibRxEOF : in std_logic; -- Cell data end of frame + pibRxEOFE : in std_logic; -- Cell data end of frame error + pibRxData : in std_logic_vector(15 downto 0) -- Cell data data + ); + +end PgpCellRx; + + +-- Define architecture +architecture PgpCellRx of PgpCellRx is + + -- Local Signals + signal dly0SOC : std_logic; + signal dly0Width : std_logic; + signal dly0EOC : std_logic; + signal dly0EOF : std_logic; + signal dly0EOFE : std_logic; + signal dly0Data : std_logic_vector(15 downto 0); + signal dly1SOC : std_logic; + signal dly1Width : std_logic; + signal dly1EOC : std_logic; + signal dly1EOF : std_logic; + signal dly1EOFE : std_logic; + signal dly1Data : std_logic_vector(15 downto 0); + signal dly2SOC : std_logic; + signal dly2Width : std_logic; + signal dly2EOC : std_logic; + signal dly2EOF : std_logic; + signal dly2EOFE : std_logic; + signal dly2Data : std_logic_vector(15 downto 0); + signal dly3SOC : std_logic; + signal dly3Width : std_logic; + signal dly3EOC : std_logic; + signal dly3EOF : std_logic; + signal dly3EOFE : std_logic; + signal dly3Data : std_logic_vector(15 downto 0); + signal dly4SOC : std_logic; + signal dly4EOC : std_logic; + signal dly4Data : std_logic_vector(15 downto 0); + signal dly5SOC : std_logic; + signal dly5Data : std_logic_vector(15 downto 0); + signal dly6SOC : std_logic; + signal dly7SOC : std_logic; + signal inCellCrc : std_logic; + signal crcNotZero : std_logic; + signal intCellRxSOF : std_logic; + signal intCellRxEmpty : std_logic; + signal intCellRxDataVc : std_logic_vector(1 downto 0); + signal intBuffAFull : std_logic_vector(3 downto 0); + signal intBuffFull : std_logic_vector(3 downto 0); + signal intFrameRxValid : std_logic_vector(3 downto 0); + signal muxFrameRxValid : std_logic_vector(3 downto 0); + signal muxFrameRxSOF : std_logic_vector(3 downto 0); + signal intFrameRxSOF : std_logic_vector(3 downto 0); + signal intFrameRxWidth : std_logic; + signal intFrameRxEOF : std_logic; + signal intFrameRxEOFE : std_logic; + signal intFrameRxData : std_logic_vector(15 downto 0); + signal interCellCount : std_logic_vector(4 downto 0); + signal expSerial : std_logic_vector(1 downto 0); + signal cellSerial : std_logic_vector(1 downto 0); + signal inCellRx : std_logic; + signal linkReadyDly : std_logic; + signal intRxCellError : std_logic; + signal firstCellRx : std_logic; + signal cellRxSize : std_logic_vector(7 downto 0); + signal dropNextCell : std_logic; + signal intMode : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Convert Pic Mode Generic + intMode <= '0' when PicMode = 0 else '1'; + + -- Interface to CRC calculator + crcRxInit <= pibRxSOC; + crcRxValid <= pibRxSOC or inCellCrc; + crcRxWidth <= pibRxWidth and not pibRxSOC; + --crcNotZero <= '0' when crcRxOut = 0 else '1'; + + -- Crc data may be switched + crcRxIn(7 downto 0) <= pibRxData(7 downto 0) when pibRxSOC='0' else pibRxData(15 downto 8); + crcRxIn(15 downto 8) <= pibRxData(15 downto 8) when pibRxSOC='0' else pibRxData(7 downto 0); + + -- Outputs to tracking blocks + cellRxStart <= dly6SOC; + cellRxEOF <= intFrameRxEOF; + cellRxEOFE <= intFrameRxEOFE; + cellRxEmpty <= intCellRxEmpty; + cellRxDataVc <= intCellRxDataVc; + cellRxSOF <= intCellRxSOF; + cellRxCellError <= intRxCellError; + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid <= intFrameRxValid(0); + vc0FrameRxSOF <= intFrameRxSOF(0); + vc0FrameRxWidth <= intFrameRxWidth; + vc0FrameRxEOF <= intFrameRxEOF; + vc0FrameRxEOFE <= intFrameRxEOFE; + vc0FrameRxData <= intFrameRxData; + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid <= intFrameRxValid(1); + vc1FrameRxSOF <= intFrameRxSOF(1); + vc1FrameRxWidth <= intFrameRxWidth; + vc1FrameRxEOF <= intFrameRxEOF; + vc1FrameRxEOFE <= intFrameRxEOFE; + vc1FrameRxData <= intFrameRxData; + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid <= intFrameRxValid(2); + vc2FrameRxSOF <= intFrameRxSOF(2); + vc2FrameRxWidth <= intFrameRxWidth; + vc2FrameRxEOF <= intFrameRxEOF; + vc2FrameRxEOFE <= intFrameRxEOFE; + vc2FrameRxData <= intFrameRxData; + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid <= intFrameRxValid(3); + vc3FrameRxSOF <= intFrameRxSOF(3); + vc3FrameRxWidth <= intFrameRxWidth; + vc3FrameRxEOF <= intFrameRxEOF; + vc3FrameRxEOFE <= intFrameRxEOFE; + vc3FrameRxData <= intFrameRxData; + + + -- Delay stages to line up data with CRC calculation + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + dly0SOC <= '0' after tpd; + dly0Width <= '0' after tpd; + dly0EOC <= '0' after tpd; + dly0EOF <= '0' after tpd; + dly0EOFE <= '0' after tpd; + dly0Data <= (others=>'0') after tpd; + dly1SOC <= '0' after tpd; + dly1Width <= '0' after tpd; + dly1EOC <= '0' after tpd; + dly1EOF <= '0' after tpd; + dly1EOFE <= '0' after tpd; + dly1Data <= (others=>'0') after tpd; + dly2SOC <= '0' after tpd; + dly2Width <= '0' after tpd; + dly2EOC <= '0' after tpd; + dly2EOF <= '0' after tpd; + dly2EOFE <= '0' after tpd; + dly2Data <= (others=>'0') after tpd; + dly3SOC <= '0' after tpd; + dly3Width <= '0' after tpd; + dly3EOC <= '0' after tpd; + dly3EOF <= '0' after tpd; + dly3EOFE <= '0' after tpd; + dly3Data <= (others=>'0') after tpd; + dly4SOC <= '0' after tpd; + dly4EOC <= '0' after tpd; + dly4Data <= (others=>'0') after tpd; + dly5SOC <= '0' after tpd; + dly5Data <= (others=>'0') after tpd; + dly6SOC <= '0' after tpd; + dly7SOC <= '0' after tpd; + inCellCrc <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- CRC Enable + if pibRxSOC = '1' then + inCellCrc <= '1' after tpd; + elsif pibRxEOC = '1' then + inCellCrc <= '0' after tpd; + end if; + + -- Delay stage 0 + dly0SOC <= pibRxSOC after tpd; + dly0Width <= pibRxWidth after tpd; + dly0EOC <= pibRxEOC after tpd; + dly0EOF <= pibRxEOF after tpd; + dly0EOFE <= pibRxEOFE after tpd; + dly0Data <= pibRxData after tpd; + + -- Delay stage 1 + dly1SOC <= dly0SOC after tpd; + dly1Width <= dly0Width after tpd; + dly1EOC <= dly0EOC after tpd; + dly1EOF <= dly0EOF after tpd; + dly1EOFE <= dly0EOFE after tpd; + dly1Data <= dly0Data after tpd; + + -- Delay stage 2 + dly2SOC <= dly1SOC after tpd; + dly2Width <= dly1Width after tpd; + dly2EOC <= dly1EOC after tpd; + dly2EOF <= dly1EOF after tpd; + dly2EOFE <= dly1EOFE after tpd; + dly2Data <= dly1Data after tpd; + + -- Delay stage 3 + dly3SOC <= dly2SOC after tpd; + dly3Width <= dly2Width after tpd; + dly3EOC <= dly2EOC after tpd; + dly3EOF <= dly2EOF after tpd; + dly3EOFE <= dly2EOFE after tpd; + dly3Data <= dly2Data after tpd; + + -- Delay stage 4 + dly4SOC <= dly3SOC after tpd; + dly4EOC <= dly3EOC after tpd; + dly4Data <= dly3Data after tpd; + + -- Delay stage 5 + dly5SOC <= dly4SOC after tpd; + dly5Data <= dly4Data after tpd; + + -- Delay stage 6 & 7, extra for SOC to drop header + dly6SOC <= dly5SOC after tpd; + dly7SOC <= dly6SOC after tpd; + end if; + end process; + + + -- MUX in frame status bits for transmit. + -- Valid is asserted if current VC is active or the abort flag + -- has been asserted. + process ( intCellRxDataVc, cellVcInFrame, cellVcAbort ) begin + case intCellRxDataVc is + when "00" => + muxFrameRxValid(0) <= cellVcInFrame(0) or cellVcAbort; + muxFrameRxValid(1) <= '0'; + muxFrameRxValid(2) <= '0'; + muxFrameRxValid(3) <= '0'; + when "01" => + muxFrameRxValid(0) <= '0'; + muxFrameRxValid(1) <= cellVcInFrame(1) or cellVcAbort; + muxFrameRxValid(2) <= '0'; + muxFrameRxValid(3) <= '0'; + when "10" => + muxFrameRxValid(0) <= '0'; + muxFrameRxValid(1) <= '0'; + muxFrameRxValid(2) <= cellVcInFrame(2) or cellVcAbort; + muxFrameRxValid(3) <= '0'; + when "11" => + muxFrameRxValid(0) <= '0'; + muxFrameRxValid(1) <= '0'; + muxFrameRxValid(2) <= '0'; + muxFrameRxValid(3) <= cellVcInFrame(3) or cellVcAbort; + when others => muxFrameRxValid <= "0000"; + end case; + end process; + + + -- MUX SOF status bits for transmit. + -- SOF is asserted if this is an SOF cell, the current VC is active + -- and the abort flag has not been asserted. + process ( intCellRxDataVc, cellVcInFrame, cellVcAbort, intCellRxSOF ) begin + case intCellRxDataVc is + when "00" => + muxFrameRxSOF(0) <= cellVcInFrame(0) and intCellRxSOF and not cellVcAbort; + muxFrameRxSOF(1) <= '0'; + muxFrameRxSOF(2) <= '0'; + muxFrameRxSOF(3) <= '0'; + when "01" => + muxFrameRxSOF(0) <= '0'; + muxFrameRxSOF(1) <= cellVcInFrame(1) and intCellRxSOF and not cellVcAbort; + muxFrameRxSOF(2) <= '0'; + muxFrameRxSOF(3) <= '0'; + when "10" => + muxFrameRxSOF(0) <= '0'; + muxFrameRxSOF(1) <= '0'; + muxFrameRxSOF(2) <= cellVcInFrame(2) and intCellRxSOF and not cellVcAbort; + muxFrameRxSOF(3) <= '0'; + when "11" => + muxFrameRxSOF(0) <= '0'; + muxFrameRxSOF(1) <= '0'; + muxFrameRxSOF(2) <= '0'; + muxFrameRxSOF(3) <= cellVcInFrame(3) and intCellRxSOF and not cellVcAbort; + when others => muxFrameRxSOF <= "0000"; + end case; + end process; + + + -- Receive cell tracking + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intCellRxSOF <= '0' after tpd; + intCellRxDataVc <= "00" after tpd; + intCellRxEmpty <= '0' after tpd; + cellRxSeq <= (others=>'0') after tpd; + cellRxAck <= '0' after tpd; + cellRxNAck <= '0' after tpd; + intBuffAFull <= (others=>'0') after tpd; + intBuffFull <= (others=>'0') after tpd; + cellSerial <= "00" after tpd; + intFrameRxValid <= "0000" after tpd; + intFrameRxSOF <= "0000" after tpd; + intFrameRxEOF <= '0' after tpd; + intFrameRxEOFE <= '0' after tpd; + intFrameRxWidth <= '0' after tpd; + intFrameRxData <= (others=>'0') after tpd; + cellRxDone <= '0' after tpd; + intRxCellError <= '0' after tpd; + interCellCount <= (others=>'0') after tpd; + expSerial <= "00" after tpd; + inCellRx <= '0' after tpd; + linkReadyDly <= '0' after tpd; + firstCellRx <= '0' after tpd; + cellRxSize <= (others=>'0') after tpd; + dropNextCell <= '0' after tpd; + crcNotZero <= '0' after tpd; + cellRxShort <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- CRC Error + if crcRxOut = 0 then + crcNotZero <= '0' after tpd; + else + crcNotZero <= '1' after tpd; + end if; + + -- Delayed copy of link ready + linkReadyDly <= pibLinkready after tpd; + + -- Register header data when enough data has been received + if dly5SOC = '1' then + + -- Frame type, + -- Force empty flag if cell is marked to be dropped + case dly5Data(15 downto 14) is + when "00" => -- IDLE + intCellRxSOF <= '0' after tpd; + intCellRxEmpty <= '1' after tpd; + cellRxAck <= dly5Data(13) after tpd; + cellRxNAck <= dly5Data(12) after tpd; + when "01" => -- Payload + intCellRxSOF <= '0' after tpd; + intCellRxEmpty <= dropNextCell after tpd; + cellRxAck <= dly5Data(13) after tpd; + cellRxNAck <= dly5Data(12) after tpd; + when "10" => -- Reserved + intCellRxSOF <= '0' after tpd; + intCellRxEmpty <= '1' after tpd; + cellRxAck <= '0' after tpd; + cellRxNAck <= '0' after tpd; + when "11" => -- SOF + intCellRxSOF <= '1' after tpd; + intCellRxEmpty <= dropNextCell after tpd; + cellRxAck <= '0' after tpd; + cellRxNAck <= '0' after tpd; + when others => + intCellRxSOF <= '0' after tpd; + intCellRxEmpty <= '0' after tpd; + cellRxAck <= '0' after tpd; + cellRxNAck <= '0' after tpd; + end case; + + -- Cell Flags + intCellRxDataVc <= dly5Data(11 downto 10) after tpd; + cellSerial <= dly5Data(9 downto 8) after tpd; + cellRxSeq <= dly4Data(7 downto 0) after tpd; + + -- VC Flags + intBuffFull <= dly4Data(15 downto 12) after tpd; + intBuffAFull <= dly4Data(11 downto 8) after tpd; + end if; + + -- Inter cell counter, don't start count until first cell is received. + if pibLinkReady = '0' then + interCellCount <= (others=>'0') after tpd; + firstCellRx <= '0' after tpd; + elsif inCellRx = '1' then + interCellCount <= (others=>'0') after tpd; + firstCellRx <= '1' after tpd; + elsif interCellCount /= 27 and firstCellRx = '1' then + interCellCount <= interCellCount + 1 after tpd; + end if; + + -- Count size of each cell received + if inCellRx = '1' then + cellRxSize <= cellRxSize + 1 after tpd; + else + cellRxSize <= (others=>'0') after tpd; + end if; + + -- Link is down. + if pibLinkReady = '0' then + + -- Reset expected serial + expSerial <= "00" after tpd; + inCellRx <= '0' after tpd; + dropNextCell <= '0' after tpd; + intFrameRxSOF <= "0000" after tpd; + + -- Link just went down. Send EOFE to all active VCs + if linkReadyDly = '1' then + intFrameRxValid <= cellVcInFrame after tpd; + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + else + intFrameRxValid <= "0000" after tpd; + intFrameRxEOF <= '0' after tpd; + intFrameRxEOFE <= '0' after tpd; + end if; + + -- Special case for 1 or 2 byte cells. SOC in delay 7 pos and + -- EOC in delay 3 pos. + elsif dly7SOC = '1' and dly3EOC = '1' then + + -- Mark in frame + inCellRx <= '1' after tpd; + + -- Receive is done + cellRxDone <= '1' after tpd; + + -- Look for large gap between cells or cell number mismatch + -- Mark all inFrame VCs as active and output error + -- Set drop next cell flag if in pic mode + -- Mark SOF for current VC if SOF Cell + if interCellCount = 27 or expSerial /= cellSerial then + intFrameRxValid <= cellVcInFrame after tpd; + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + intRxCellError <= '1' after tpd; + expSerial <= cellSerial after tpd; + dropNextCell <= intMode after tpd; + intFrameRxSOF <= muxFrameRxSOF after tpd; + + -- CRC Error, Mark all in frame VCs as active output EOF with error + -- Set drop next cell flag if in pic mode + -- Mark SOF for current VC if SOF Cell + -- even if VC is in error, rx track will generate correct SOF + -- which won't confuse external logic + elsif crcNotZero = '1' then + intFrameRxValid <= cellVcInFrame after tpd; + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + intRxCellError <= '1' after tpd; + dropNextCell <= intMode after tpd; + intFrameRxSOF <= muxFrameRxSOF after tpd; + + -- Non-Errored Frame Reception, + else + + -- Choose active VC if cell is not empty. + if intCellRxEmpty = '0' then + intFrameRxValid <= muxFrameRxValid after tpd; + intFrameRxSOF <= muxFrameRxSOF after tpd; + end if; + + -- Clear drop next cell flag + dropNextCell <= '0'; + + -- Cell size enforecement. If cell is not an EOF and force cell + -- size is asserted then end frame in error + if intMode = '1' and dly3EOF = '0' and intCellRxEmpty = '0' then + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + cellRxShort <= '1' after tpd; + + -- Set EOF and EOFE, force EOF and EOFE if abort is asserted + else + intFrameRxEOF <= dly3EOF or cellVcAbort after tpd; + intFrameRxEOFE <= dly3EOFE or cellVcAbort after tpd; + end if; + end if; + + -- Start of data movement when SOC is in delay 7 position. + elsif dly7SOC = '1' then + + -- Mark in frame + inCellRx <= '1' after tpd; + + -- Look for large gap between cells or cell number mismatch + -- Mark cell as in error and do not output to any VCs + -- Mark SOF for current VC if SOF Cell + if interCellCount = 27 or expSerial /= cellSerial then + intFrameRxValid <= "0000" after tpd; + intRxCellError <= '1' after tpd; + expSerial <= cellSerial after tpd; + intFrameRxSOF <= muxFrameRxSOF after tpd; + + -- Normal cell reception, Choose active VC + else + + -- Choose active VC if cell is not empty + if intCellRxEmpty = '0' then + intFrameRxValid <= muxFrameRxValid after tpd; + intFrameRxSOF <= muxFrameRxSOF after tpd; + end if; + + -- Clear drop next cell flag + dropNextCell <= '0'; + end if; + + -- EOC arrives in delay position 3 when cell is done + elsif dly3EOC = '1' then + + -- Receive is done + cellRxDone <= '1' after tpd; + intFrameRxSOF <= "0000" after tpd; + + -- End of frame forced by error, all active VCs get EOFE + -- Set drop next cell flag if in pic mode + if crcNotZero = '1' or intRxCellError = '1' then + intFrameRxValid <= cellVcInFrame after tpd; + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + intRxCellError <= '1' after tpd; + dropNextCell <= intMode after tpd; + + -- Cell size enforecement. If cell is not full, EOF is not asserted + -- and force cell size is asserted then end frame in error + elsif intMode = '1' and dly3EOF = '0' and + cellRxSize /= 254 and intCellRxEmpty = '0' then + intFrameRxEOF <= '1' after tpd; + intFrameRxEOFE <= '1' after tpd; + cellRxShort <= '1' after tpd; + + -- Normal End of frame detected + -- Set EOF and EOFE, force EOF and EOFE if abort is asserted + else + intFrameRxEOF <= dly3EOF or cellVcAbort after tpd; + intFrameRxEOFE <= dly3EOFE or cellVcAbort after tpd; + end if; + + -- Detect End Of Frame, clear flags + elsif dly4EOC = '1' then + + -- Increment expected serial number for next cell + expSerial <= expSerial + 1 after tpd; + + -- Clear EOF, Done, error and valid signals + inCellRx <= '0' after tpd; + intFrameRxSOF <= "0000" after tpd; + intFrameRxEOF <= '0' after tpd; + intFrameRxEOFE <= '0' after tpd; + cellRxDone <= '0' after tpd; + intRxCellError <= '0' after tpd; + intFrameRxValid <= "0000" after tpd; + cellRxShort <= '0' after tpd; + + -- Clear SOF after first byte + else + intFrameRxSOF <= "0000" after tpd; + end if; + + -- Data output, width follows delay 4 + intFrameRxWidth <= dly3Width after tpd; + intFrameRxData <= dly5Data after tpd; + + end if; + end process; + + + -- Update buffer status on successfull cell reception + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vc0RemBuffAFull <= '1' after tpd; + vc0RemBuffFull <= '1' after tpd; + vc1RemBuffAFull <= '1' after tpd; + vc1RemBuffFull <= '1' after tpd; + vc2RemBuffAFull <= '1' after tpd; + vc2RemBuffFull <= '1' after tpd; + vc3RemBuffAFull <= '1' after tpd; + vc3RemBuffFull <= '1' after tpd; + elsif rising_edge(pgpClk) then + + -- Link is not ready, force buffer states to bad + if pibLinkReady = '0' then + vc0RemBuffAFull <= '1' after tpd; + vc0RemBuffFull <= '1' after tpd; + vc1RemBuffAFull <= '1' after tpd; + vc1RemBuffFull <= '1' after tpd; + vc2RemBuffAFull <= '1' after tpd; + vc2RemBuffFull <= '1' after tpd; + vc3RemBuffAFull <= '1' after tpd; + vc3RemBuffFull <= '1' after tpd; + + -- Update buffer status if there was no CRC error + elsif dly3EOC = '1' and crcNotZero = '0' then + vc0RemBuffAFull <= intBuffAFull(0) after tpd; + vc0RemBuffFull <= intBuffFull(0) after tpd; + vc1RemBuffAFull <= intBuffAFull(1) after tpd; + vc1RemBuffFull <= intBuffFull(1) after tpd; + vc2RemBuffAFull <= intBuffAFull(2) after tpd; + vc2RemBuffFull <= intBuffFull(2) after tpd; + vc3RemBuffAFull <= intBuffAFull(3) after tpd; + vc3RemBuffFull <= intBuffFull(3) after tpd; + end if; + end if; + end process; + +end PgpCellRx; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpCellTx.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpCellTx.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2752a4b97658ecf1230fc31ab83e881b515c8c74 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpCellTx.vhd @@ -0,0 +1,702 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Cell Transmit Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpCellTx.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Cell Transmit interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 04/16/2007: Modified to a more pipelined design alloing back to back cell +-- tranmission as well as fixing some bugs related to short frames +-- 04/18/2007: Added support to track the number of cells in a frame to detect +-- dropped cells. +-- 06/19/2007: Moved rand data logic into this block. +-- 07/19/2007: Removed support to track the number of cells in a frame. Added +-- cell sequence number. +-- 09/18/2007: Added logic to force error if width='0' without EOF +-- 09/21/2007: Removed payload imput +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpCellTx is port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- PIB Interface + pibLinkReady : in std_logic; -- PIB Link Ready + + -- Transmit Scheduler Interface + cellTxDataSeq : in std_logic_vector(7 downto 0); -- Transmit sequence number + cellTxSOF : out std_logic; -- Cell contained SOF + cellTxEOF : out std_logic; -- Cell contained EOF + cellTxIdle : in std_logic; -- Force IDLE transmit + cellTxReq : in std_logic; -- Cell transmit request + cellTxInp : out std_logic; -- Cell transmit in progress + cellTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + + -- ACK/NACK Transmit Logic + cellTxNAck : in std_logic; -- Cell transmit NACK request + cellTxAck : in std_logic; -- Cell transmit ACK request + cellTxAckSeq : in std_logic_vector(7 downto 0); -- Cell transmit ACK sequence + cellTxAcked : out std_logic; -- Cell transmit ACK was sent + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxWidth : in std_logic; -- User frame data width + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxWidth : in std_logic; -- User frame data width + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxWidth : in std_logic; -- User frame data width + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxWidth : in std_logic; -- User frame data width + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- PHY Interface + pibTxSOC : out std_logic; -- Cell data start of cell + pibTxWidth : out std_logic; -- Cell data width + pibTxEOC : out std_logic; -- Cell data end of cell + pibTxEOF : out std_logic; -- Cell data end of frame + pibTxEOFE : out std_logic; -- Cell data end of frame error + pibTxData : out std_logic_vector(15 downto 0); -- Cell data data + + -- Transmit CRC Interface + crcTxIn : out std_logic_vector(15 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxWidth : out std_logic; -- Transmit data for CRC width + crcTxOut : in std_logic_vector(31 downto 0) -- Transmit calculated CRC value + ); + +end PgpCellTx; + + +-- Define architecture +architecture PgpCellTx of PgpCellTx is + + -- Local Signals + signal muxFrameTxValid : std_logic; + signal muxFrameTxSOF : std_logic; + signal muxFrameTxWidth : std_logic; + signal muxFrameTxEOF : std_logic; + signal muxFrameTxEOFE : std_logic; + signal muxFrameTxData : std_logic_vector(15 downto 0); + signal dlyFrameTxData : std_logic_vector(15 downto 0); + signal dlyFrameTxEOF : std_logic; + signal dlyFrameTxEOFE : std_logic; + signal dlyFrameTxWidth : std_logic; + signal selSOC : std_logic; + signal selValid : std_logic; + signal selWidth : std_logic; + signal selEOF : std_logic; + signal selEOFE : std_logic; + signal selCrcMask : std_logic_vector(3 downto 0); + signal selData : std_logic_vector(15 downto 0); + signal frameReadyOut : std_logic; + signal payloadCount : std_logic_vector(8 downto 0); + signal dly1TxSOC : std_logic; + signal dly1TxEOF : std_logic; + signal dly1TxEOFE : std_logic; + signal dly1CrcMask : std_logic_vector(3 downto 0); + signal dly1TxData : std_logic_vector(15 downto 0); + signal dly2TxSOC : std_logic; + signal dly2TxEOF : std_logic; + signal dly2TxEOFE : std_logic; + signal dly2CrcMask : std_logic_vector(3 downto 0); + signal dly2TxData : std_logic_vector(15 downto 0); + signal dly3TxSOC : std_logic; + signal dly3TxEOF : std_logic; + signal dly3TxEOFE : std_logic; + signal dly3CrcMask : std_logic_vector(3 downto 0); + signal dly3TxData : std_logic_vector(15 downto 0); + signal dly4TxSOC : std_logic; + signal dly4TxEOF : std_logic; + signal dly4TxEOFE : std_logic; + signal dly4CrcMask : std_logic_vector(3 downto 0); + signal dly4TxData : std_logic_vector(15 downto 0); + signal nextAcked : std_logic; + signal randData : std_logic_vector(15 downto 0); + signal cellSerial : std_logic_vector(1 downto 0); + + -- Transmit states + signal txState : std_logic_vector(2 downto 0); + constant ST_IDLE : std_logic_vector(2 downto 0) := "000"; + constant ST_HEAD0 : std_logic_vector(2 downto 0) := "001"; + constant ST_HEAD1 : std_logic_vector(2 downto 0) := "010"; + constant ST_PAYLD : std_logic_vector(2 downto 0) := "011"; + constant ST_CRC01 : std_logic_vector(2 downto 0) := "100"; + constant ST_CRC23 : std_logic_vector(2 downto 0) := "101"; + constant ST_CRC12 : std_logic_vector(2 downto 0) := "110"; + constant ST_CRC3 : std_logic_vector(2 downto 0) := "111"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Interface to CRC calculator + crcTxInit <= selSOC; + crcTxValid <= selValid; + crcTxWidth <= selWidth; + + -- Crc data may be switched + crcTxIn(7 downto 0) <= selData(7 downto 0) when selSOC = '0' else selData(15 downto 8); + crcTxIn(15 downto 8) <= selData(15 downto 8) when selSOC = '0' else selData(7 downto 0); + + + -- Mux incoming data depending on squence number, drive outgoing ready + process ( cellTxDataVc, vc0FrameTxValid, vc0FrameTxSOF, vc0FrameTxWidth, + vc0FrameTxEOF, vc0FrameTxEOFE, vc0FrameTxData, vc1FrameTxValid, + vc1FrameTxSOF, vc1FrameTxWidth, vc1FrameTxEOF, vc1FrameTxEOFE, + vc1FrameTxData, vc2FrameTxValid, vc2FrameTxSOF, vc2FrameTxWidth, + vc2FrameTxEOF, vc2FrameTxEOFE, vc2FrameTxData, vc3FrameTxValid, + vc3FrameTxSOF, vc3FrameTxWidth, vc3FrameTxEOF, vc3FrameTxEOFE, + vc3FrameTxData, frameReadyOut, cellTxIdle, randData ) begin + + -- Use random data when not transmitting a frame or when + -- transmitting the payload of an IDLE cell + if cellTxIdle = '1' then + muxFrameTxValid <= '1'; + muxFrameTxSOF <= '0'; + muxFrameTxWidth <= '1'; + muxFrameTxEOF <= '0'; + muxFrameTxEOFE <= '0'; + muxFrameTxData <= randData; + vc0FrameTxReady <= '0'; + vc1FrameTxReady <= '0'; + vc2FrameTxReady <= '0'; + vc3FrameTxReady <= '0'; + + -- Choose virtual channel when not transmitting IDLE cell and when + -- scheduler wants a frame transmitted. + else case cellTxDataVc is + when "00" => + muxFrameTxValid <= vc0FrameTxValid; + muxFrameTxSOF <= vc0FrameTxSOF; + muxFrameTxWidth <= vc0FrameTxWidth; + muxFrameTxEOF <= vc0FrameTxEOF; + muxFrameTxEOFE <= vc0FrameTxEOFE; + muxFrameTxData <= vc0FrameTxData; + vc0FrameTxReady <= frameReadyOut; + vc1FrameTxReady <= '0'; + vc2FrameTxReady <= '0'; + vc3FrameTxReady <= '0'; + when "01" => + muxFrameTxValid <= vc1FrameTxValid; + muxFrameTxSOF <= vc1FrameTxSOF; + muxFrameTxWidth <= vc1FrameTxWidth; + muxFrameTxEOF <= vc1FrameTxEOF; + muxFrameTxEOFE <= vc1FrameTxEOFE; + muxFrameTxData <= vc1FrameTxData; + vc0FrameTxReady <= '0'; + vc1FrameTxReady <= frameReadyOut; + vc2FrameTxReady <= '0'; + vc3FrameTxReady <= '0'; + when "10" => + muxFrameTxValid <= vc2FrameTxValid; + muxFrameTxSOF <= vc2FrameTxSOF; + muxFrameTxWidth <= vc2FrameTxWidth; + muxFrameTxEOF <= vc2FrameTxEOF; + muxFrameTxEOFE <= vc2FrameTxEOFE; + muxFrameTxData <= vc2FrameTxData; + vc0FrameTxReady <= '0'; + vc1FrameTxReady <= '0'; + vc2FrameTxReady <= frameReadyOut; + vc3FrameTxReady <= '0'; + when "11" => + muxFrameTxValid <= vc3FrameTxValid; + muxFrameTxSOF <= vc3FrameTxSOF; + muxFrameTxWidth <= vc3FrameTxWidth; + muxFrameTxEOF <= vc3FrameTxEOF; + muxFrameTxEOFE <= vc3FrameTxEOFE; + muxFrameTxData <= vc3FrameTxData; + vc0FrameTxReady <= '0'; + vc1FrameTxReady <= '0'; + vc2FrameTxReady <= '0'; + vc3FrameTxReady <= frameReadyOut; + when others => + muxFrameTxValid <= '0'; + muxFrameTxSOF <= '0'; + muxFrameTxWidth <= '0'; + muxFrameTxEOF <= '0'; + muxFrameTxEOFE <= '0'; + muxFrameTxData <= (others=>'0'); + vc0FrameTxReady <= '0'; + vc1FrameTxReady <= '0'; + vc2FrameTxReady <= '0'; + vc3FrameTxReady <= '0'; + end case; + end if; + end process; + + + -- Payload counter used to limit payload size of frames + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + payloadCount <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + if txState = ST_PAYLD then + payloadCount <= payloadCount + 1 after tpd; + else + payloadCount <= (others=>'0') after tpd; + end if; + end if; + end process; + + + -- Simple state machine to control transmission of data frames + -- Control input state of delay chain + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + dlyFrameTxData <= (others=>'0') after tpd; + dlyFrameTxEOF <= '0' after tpd; + dlyFrameTxEOFE <= '0' after tpd; + dlyFrameTxWidth <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxInp <= '0' after tpd; + cellTxAcked <= '0' after tpd; + nextAcked <= '0' after tpd; + frameReadyOut <= '0' after tpd; + selSOC <= '0' after tpd; + selValid <= '0' after tpd; + selWidth <= '0' after tpd; + selEOF <= '0' after tpd; + selEOFE <= '0' after tpd; + selCrcMask <= "0000" after tpd; + selData <= (others=>'0') after tpd; + txState <= ST_IDLE after tpd; + cellSerial <= "00" after tpd; + + elsif rising_edge(pgpClk) then + + -- Muxed data delay stage + dlyFrameTxData <= muxFrameTxData after tpd; + dlyFrameTxEOF <= muxFrameTxEOF after tpd; + dlyFrameTxEOFE <= muxFrameTxEOFE after tpd; + dlyFrameTxWidth <= muxFrameTxWidth after tpd; + + -- Delayed version of acked + cellTxAcked <= nextAcked; + + -- Link is not ready + if pibLinkReady = '0' then + cellTxSOF <= '0' after tpd; + cellTxEOF <= '0' after tpd; + nextAcked <= '0' after tpd; + selValid <= '0' after tpd; + selWidth <= '0' after tpd; + selSOC <= '0' after tpd; + selEOF <= '0' after tpd; + selEOFE <= '0' after tpd; + selCrcMask <= "0000" after tpd; + selData <= (others=>'0') after tpd; + frameReadyOut <= '0' after tpd; + cellTxInp <= '0' after tpd; + cellSerial <= "00" after tpd; + txState <= ST_IDLE after tpd; + + -- Transmit state engine + else case txState is + + -- IDLE, waiting for frame, no data on sel + when ST_IDLE => + + -- Clear Flags + cellTxEOF <= '0' after tpd; + nextAcked <= '0' after tpd; + frameReadyOut <= '0' after tpd; + + -- No Data + selValid <= '0' after tpd; + selWidth <= '0' after tpd; + selEOF <= '0' after tpd; + selEOFE <= '0' after tpd; + selCrcMask <= "0000" after tpd; + selData <= randData after tpd; + + -- Wait for transmit control from scheduler + if cellTxReq = '1' then + + -- Set in frame mode + txState <= ST_HEAD0 after tpd; + cellTxInp <= '1' after tpd; + + -- Assert SOF, payload flags as early as possible + cellTxSOF <= not cellTxIdle and muxFrameTxSOF after tpd; + else + cellTxInp <= '0' after tpd; + cellTxSOF <= '0' after tpd; + end if; + + -- Header 0, data is SOC placeholder and header byte 0 + when ST_HEAD0 => + + -- Assert ready + selSOC <= '1' after tpd; + cellTxSOF <= '0' after tpd; + + -- Assert flags to external blocks, some fields depend on frame type + -- IDLE cell + if cellTxIdle = '1' then + frameReadyOut <= '0' after tpd; + nextAcked <= cellTxAck or cellTxNack after tpd; + selData(15 downto 14) <= "00" after tpd; -- Cell Type + selData(13) <= cellTxAck after tpd; -- Ack Bit + selData(12) <= cellTxNAck after tpd; -- Nack Bit + selData(11 downto 10) <= "00" after tpd; -- VC + + -- SOF Frame + elsif muxFrameTxSOF = '1' then + frameReadyOut <= '1' after tpd; + nextAcked <= '0' after tpd; + selData(15 downto 14) <= "11" after tpd; -- Cell Type + selData(13) <= '0' after tpd; -- Ack Bit + selData(12) <= '0' after tpd; -- Nack Bit + selData(11 downto 10) <= cellTxDataVc after tpd; -- VC + + -- Payload + else + frameReadyOut <= '1' after tpd; + nextAcked <= cellTxAck or cellTxNack after tpd; + selData(15 downto 14) <= "01" after tpd; -- Cell Type + selData(13) <= cellTxAck after tpd; -- Ack Bit + selData(12) <= cellTxNAck after tpd; -- Nack Bit + selData(11 downto 10) <= cellTxDataVc after tpd; -- VC + end if; + + -- Delay pipeline input + selValid <= '1' after tpd; + selWidth <= '0' after tpd; + selData(9 downto 8) <= cellSerial after tpd; -- Cell serial number + + -- Increment serial number + cellSerial <= cellSerial + 1 after tpd; + + -- Go to header 1 state + txState <= ST_HEAD1 after tpd; + + -- Header 1, data is header bytes 1 & 2 + when ST_HEAD1 => + + -- Clear flags + selSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + nextAcked <= '0' after tpd; + + -- Delay pipeline input + selWidth <= '1' after tpd; + selData(15) <= vc3LocBuffFull after tpd; + selData(14) <= vc2LocBuffFull after tpd; + selData(13) <= vc1LocBuffFull after tpd; + selData(12) <= vc0LocBuffFull after tpd; + selData(11) <= vc3LocBuffAFull after tpd; + selData(10) <= vc2LocBuffAFull after tpd; + selData(9) <= vc1LocBuffAFull after tpd; + selData(8) <= vc0LocBuffAFull after tpd; + + -- Lower byte depends on frame type + if nextAcked = '1' then + selData(7 downto 0) <= cellTxAckSeq after tpd; -- Ack/Nack seq num + else + selData(7 downto 0) <= cellTxDataSeq after tpd; -- Data frame seq num + end if; + + -- EOF is passed at input + if muxFrameTxEOF = '1' then + frameReadyOut <= '0' after tpd; + end if; + + -- Process payload data + txState <= ST_PAYLD after tpd; + + -- Payload data + when ST_PAYLD => + + -- Delay pipeline input + selValid <= '1' after tpd; + + -- EOF + if dlyFrameTxEOF = '1' then + + -- Store error flag for later + selEOF <= '1' after tpd; + selEOFE <= dlyFrameTxEOFE after tpd; + + -- Width = 0, overwrite upper byte with CRC byte 0 + if dlyFrameTxWidth = '0' then + selData <= dlyFrameTxData after tpd; + txState <= ST_CRC12 after tpd; + selCrcMask <= "0001" after tpd; + selWidth <= '0' after tpd; + + -- Width = 1 + else + selData <= dlyFrameTxData after tpd; + txState <= ST_CRC01 after tpd; + selCrcMask <= "0000" after tpd; + selWidth <= '1' after tpd; + end if; + + -- Ready de-asserted by user or valid de-asserted by local logic + elsif frameReadyOut = '0' or muxFrameTxValid = '0' then + selData <= dlyFrameTxData after tpd; + txState <= ST_CRC01 after tpd; + selCrcMask <= "0000" after tpd; + selWidth <= '1' after tpd; + + -- Normal data. Pass width flag to CRC generator. This will ensure an + -- error occurs if user de-asserts width flag without EOF. + else + selData <= dlyFrameTxData after tpd; + selCrcMask <= "0000" after tpd; + selWidth <= dlyFrameTxWidth after tpd; + end if; + + -- EOF is passed at input or user has de-asserted valid + if muxFrameTxValid = '0' or muxFrameTxEOF = '1' then + frameReadyOut <= '0' after tpd; + + -- Payload size exceeded or idle size has been reached + elsif payloadCount = 254 or (payloadCount = 4 and cellTxIdle = '1') then + frameReadyOut <= '0' after tpd; + end if; + + -- CRC bytes 01, even alignment + when ST_CRC01 => + selWidth <= '1' after tpd; + selValid <= '0' after tpd; + selCrcMask <= "0011" after tpd; + txState <= ST_CRC23 after tpd; + + -- CRC bytes 23, even alignment + when ST_CRC23 => + selWidth <= '1' after tpd; + selValid <= '0' after tpd; + selCrcMask <= "1100" after tpd; + cellTxEOF <= selEOF after tpd; + txState <= ST_IDLE after tpd; + + -- CRC bytes 12, odd alignment + when ST_CRC12 => + selWidth <= '1' after tpd; + selValid <= '0' after tpd; + selCrcMask <= "0110" after tpd; + txState <= ST_CRC3 after tpd; + + -- CRC byte 3, odd alignment + when ST_CRC3 => + selWidth <= '0' after tpd; + selValid <= '0' after tpd; + selCrcMask <= "1000" after tpd; + cellTxEOF <= selEOF after tpd; + txState <= ST_IDLE after tpd; + + -- Just in case + when others => txState <= ST_IDLE after tpd; + end case; + end if; + end if; + end process; + + + -- The rest of the delay chain. A delay is required in order to compensate + -- for the latency of the CRC generator. + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + dly1TxSOC <= '0' after tpd; + dly1TxEOF <= '0' after tpd; + dly1TxEOFE <= '0' after tpd; + dly1CrcMask <= "0000" after tpd; + dly1TxData <= (others=>'0') after tpd; + dly2TxSOC <= '0' after tpd; + dly2TxEOF <= '0' after tpd; + dly2TxEOFE <= '0' after tpd; + dly2CrcMask <= "0000" after tpd; + dly2TxData <= (others=>'0') after tpd; + dly3TxSOC <= '0' after tpd; + dly3TxEOF <= '0' after tpd; + dly3TxEOFE <= '0' after tpd; + dly3CrcMask <= "0000" after tpd; + dly3TxData <= (others=>'0') after tpd; + dly4TxSOC <= '0' after tpd; + dly4TxEOF <= '0' after tpd; + dly4TxEOFE <= '0' after tpd; + dly4CrcMask <= "0000" after tpd; + dly4TxData <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Delay stage 1 + dly1TxSOC <= selSOC after tpd; + dly1TxEOF <= selEOF after tpd; + dly1TxEOFE <= selEOFE after tpd; + dly1CrcMask <= selCrcMask after tpd; + dly1TxData <= selData after tpd; + + -- Delay stage 2 + dly2TxSOC <= dly1TxSOC after tpd; + dly2TxEOF <= dly1TxEOF after tpd; + dly2TxEOFE <= dly1TxEOFE after tpd; + dly2CrcMask <= dly1CrcMask after tpd; + dly2TxData <= dly1TxData after tpd; + + -- Delay stage 3 + dly3TxSOC <= dly2TxSOC after tpd; + dly3TxEOF <= dly2TxEOF after tpd; + dly3TxEOFE <= dly2TxEOFE after tpd; + dly3CrcMask <= dly2CrcMask after tpd; + dly3TxData <= dly2TxData after tpd; + + -- Delay stage 3 + dly4TxSOC <= dly3TxSOC after tpd; + dly4TxEOF <= dly3TxEOF after tpd; + dly4TxEOFE <= dly3TxEOFE after tpd; + dly4CrcMask <= dly3CrcMask after tpd; + dly4TxData <= dly3TxData after tpd; + end if; + end process; + + + -- Output stage, either real data or insert CRC values + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + pibTxSOC <= '0' after tpd; + pibTxWidth <= '0' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData <= (others=>'0') after tpd; + + elsif rising_edge(pgpClk) then + + -- Data depends on state of shifted CRC mask + case dly4CrcMask is + + -- Normal data + when "0000" => + pibTxSOC <= dly4TxSOC after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData <= dly4TxData after tpd; + + -- Partial CRC in upper byte + when "0001" => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData(7 downto 0) <= dly4TxData(7 downto 0) after tpd; + pibTxData(15 downto 8) <= crcTxOut(31 downto 24) after tpd; + + -- Shifted CRC + when "0110" => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData(7 downto 0) <= crcTxOut(23 downto 16) after tpd; + pibTxData(15 downto 8) <= crcTxOut(15 downto 8) after tpd; + + -- Partial CRC in lower byte, end of cell + when "1000" => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '0' after tpd; + pibTxEOC <= '1' after tpd; + pibTxEOF <= dly4TxEOF after tpd; + pibTxEOFE <= dly4TxEOFE after tpd; + pibTxData(7 downto 0) <= crcTxOut(7 downto 0) after tpd; + pibTxData(15 downto 8) <= (others=>'0') after tpd; + + -- Full CRC + when "0011" => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData(7 downto 0) <= crcTxOut(31 downto 24) after tpd; + pibTxData(15 downto 8) <= crcTxOut(23 downto 16) after tpd; + + -- Full CRC, end of cell + when "1100" => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '1' after tpd; + pibTxEOF <= dly4TxEOF after tpd; + pibTxEOFE <= dly4TxEOFE after tpd; + pibTxData(7 downto 0) <= crcTxOut(15 downto 8) after tpd; + pibTxData(15 downto 8) <= crcTxOut(7 downto 0) after tpd; + + when others => + pibTxSOC <= '0' after tpd; + pibTxWidth <= '1' after tpd; + pibTxEOC <= '0' after tpd; + pibTxEOF <= '0' after tpd; + pibTxEOFE <= '0' after tpd; + pibTxData <= dly4TxData after tpd; + end case; + end if; + end process; + + + -- Random data generator + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + randData <= (others =>'0') after tpd; + elsif rising_edge(pgpClk) then + randData <= randData + 1 after tpd; + end if; + end process; + +end PgpCellTx; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpClkGen.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpClkGen.vhd new file mode 100755 index 0000000000000000000000000000000000000000..5a7082f73195f0efe26cf6d56b8624d1c5b957f1 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpClkGen.vhd @@ -0,0 +1,367 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Clock Source Module +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpClkGen.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 06/09/2007 +------------------------------------------------------------------------------- +-- Description: +-- PGP Clock Module. Contians GT11 clock module and DCM to support PGP. +-- Used to generate 152.65Mhz reference clock for MGT and global buffer clock +-- for PGP core at the same frequency. Will also generate an optional 125Mhz +-- global clock and reset for external logic use. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 06/09/2007: created. +-- 09/19/2007: Added power on reset input and local reset inputs, added 125Mhz +-- clock outputs. +-- 09/21/2007: Added generic to choose reference clock drive +-- 10/08/2007: Fixed inversion error on DCM reset. +-- 10/19/2007: Clocks are now fed back into block for use to clean up +-- synplicity clock contraints. +-- 11/06/2007: Changed DLL frequency mode to high. +-- 11/08/2007: Changed GT11 clock inputs from open to '0' to fix simulation. +-- 11/08/2007: Added simulation libraries +-- 01/25/2008: Added generics to support adjusting user clock settings. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +-- synopsys translate_off +Library UNISIM; +-- synopsys translate_on + +entity PgpClkGen is + generic ( + RefClkEn1 : string := "ENABLE"; -- ENABLE or DISABLE + RefClkEn2 : string := "DISABLE"; -- ENABLE or DISABLE + DcmClkSrc : string := "RefClk1"; -- RefClk1 or RefClk2 + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Pad Inputs + pgpRefClkInP : in std_logic; + pgpRefClkInN : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Reference Clock To PGP MGT + -- Use one, See RefClkEn1 & RefClkEn2 Generics + pgpRefClk1 : out std_logic; + pgpRefClk2 : out std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpClk90 : out std_logic; + pgpReset : out std_logic; + + clk320 : out std_logic; + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic; + + -- Output unbuffered clocks + pgpClkUnbuf : out std_logic; + pgpClk90Unbuf : out std_logic; + locClkUnbuf : out std_logic + ); + +end PgpClkGen; + + +-- Define architecture +architecture PgpClkGen of PgpClkGen is + + -- Xilinx GTLL Clock Module + component GT11CLK + generic ( + REFCLKSEL : string := "MGTCLK"; + SYNCLK1OUTEN : string := "ENABLE"; + SYNCLK2OUTEN : string := "DISABLE" + ); + port ( + SYNCLK1OUT : out std_ulogic; + SYNCLK2OUT : out std_ulogic; + MGTCLKN : in std_ulogic; + MGTCLKP : in std_ulogic; + REFCLK : in std_ulogic; + RXBCLK : in std_ulogic; + SYNCLK1IN : in std_ulogic; + SYNCLK2IN : in std_ulogic + ); + end component; + + -- Xilinx DCM + component DCM + generic ( + CLKDV_DIVIDE : real := 2.0; + CLKFX_DIVIDE : integer := 1; + CLKFX_MULTIPLY : integer := 4; + CLKIN_PERIOD : real := 10.0; + CLKIN_DIVIDE_BY_2 : boolean := false; + CLKOUT_PHASE_SHIFT : string := "NONE"; + CLK_FEEDBACK : string := "1X"; + DESKEW_ADJUST : string := "SYSTEM_SYNCHRONOUS"; + DFS_FREQUENCY_MODE : string := "LOW"; + DLL_FREQUENCY_MODE : string := "LOW"; + DSS_MODE : string := "NONE"; + DUTY_CYCLE_CORRECTION : boolean := true; + FACTORY_JF : bit_vector := X"C080"; + PHASE_SHIFT : integer := 0; + STARTUP_WAIT : boolean := false + ); + port ( + CLK0 : out std_ulogic := '0'; + CLK180 : out std_ulogic := '0'; + CLK270 : out std_ulogic := '0'; + CLK2X : out std_ulogic := '0'; + CLK2X180 : out std_ulogic := '0'; + CLK90 : out std_ulogic := '0'; + CLKDV : out std_ulogic := '0'; + CLKFX : out std_ulogic := '0'; + CLKFX180 : out std_ulogic := '0'; + LOCKED : out std_ulogic := '0'; + PSDONE : out std_ulogic := '0'; + STATUS : out std_logic_vector(7 downto 0) := "00000000"; + CLKFB : in std_ulogic := '0'; + CLKIN : in std_ulogic := '0'; + DSSEN : in std_ulogic := '0'; + PSCLK : in std_ulogic := '0'; + PSEN : in std_ulogic := '0'; + PSINCDEC : in std_ulogic := '0'; + RST : in std_ulogic := '0' + ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + + -- For simulation + -- synopsys translate_off + for all : BUFGMUX use entity UNISIM.BUFGMUX (bufgmux_v); + for all : DCM use entity UNISIM.DCM (dcm_v); + for all : GT11CLK use entity UNISIM.GT11CLK (gt11clk_v); + -- synopsys translate_on + + -- Local Signals + signal ponReset : std_logic; + signal intRefClk1 : std_logic; + signal intRefClk2 : std_logic; + signal tmpPgpClk : std_logic; + signal tmpPgpClk90 : std_logic; + signal intPgpClk : std_logic; + signal intPgpClk90 : std_logic; + signal intPgpRst : std_logic; + signal tmpLocClk : std_logic; + signal tmp320Clk : std_logic; + signal int320Clk : std_logic; + signal intUsrClk : std_logic; + signal intUsrRst : std_logic; + signal syncPgpRstIn : std_logic_vector(2 downto 0); + signal pgpRstCnt : std_logic_vector(3 downto 0); + signal syncLocRstIn : std_logic_vector(2 downto 0); + signal locRstCnt : std_logic_vector(3 downto 0); + signal dcmRefClk : std_logic; + signal dcmLock : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of GT11CLK : component is TRUE; + attribute syn_noprune of GT11CLK : component is TRUE; + attribute syn_black_box of DCM : component is TRUE; + attribute syn_noprune of DCM : component is TRUE; + attribute syn_black_box of BUFGMUX : component is TRUE; + attribute syn_noprune of BUFGMUX : component is TRUE; + +begin + + -- Output Generated Clock And Reset Signals + pgpRefClk1 <= intRefClk1; + pgpRefClk2 <= intRefClk2; + pgpClk <= intPgpClk; + pgpClk90 <= intPgpClk90; + clk320 <= int320Clk; + pgpReset <= intPgpRst; + userClk <= intUsrClk; + userReset <= intUsrRst; + + -- Output unbuffered clocks + pgpClkUnbuf <= tmpPgpClk; + pgpClk90Unbuf <= tmpPgpClk90; + locClkUnbuf <= tmpLocClk; + + -- Invert power on reset + ponReset <= not ponResetL; + + + -- MGT Clock Module + U_PgpClkGT11: GT11CLK generic map ( + SYNCLK1OUTEN => RefClkEn1, + SYNCLK2OUTEN => RefClkEn2, + REFCLKSEL => "MGTCLK" + ) port map ( + MGTCLKN => pgpRefClkInN, + MGTCLKP => pgpRefClkInP, + REFCLK => '0', + RXBCLK => '0', + SYNCLK1IN => '0', + SYNCLK2IN => '0', + SYNCLK1OUT => intRefClk1, + SYNCLK2OUT => intRefClk2 + ); + + + -- REF Clock 1 Is Selected As DCM Source + U_DCM_REF1: if DcmClkSrc = "RefClk1" generate + dcmRefClk <= intRefClk1; + end generate; + + -- REF Clock 2 Is Selected As DCM Source + U_DCM_REF2: if DcmClkSrc = "RefClk2" generate + dcmRefClk <= intRefClk2; + end generate; + + + -- DCM For PGP Clock & User Clock + U_PgpDcm: DCM + generic map ( + DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "HIGH", + DUTY_CYCLE_CORRECTION => FALSE, CLKIN_DIVIDE_BY_2 => FALSE, + CLK_FEEDBACK => "1X", CLKOUT_PHASE_SHIFT => "NONE", + STARTUP_WAIT => false, PHASE_SHIFT => 0, + CLKFX_MULTIPLY => UserFxMult, CLKFX_DIVIDE => UserFxDiv, + CLKDV_DIVIDE => 4.0, CLKIN_PERIOD => 6.4, + DSS_MODE => "NONE", FACTORY_JF => X"C080", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS" + ) + port map ( + CLKIN => dcmRefClk, CLKFB => intPgpClk, + CLK0 => tmpPgpClk, CLK90 => tmpPgpClk90, + CLK180 => open, CLK270 => open, + CLK2X => tmp320Clk, CLK2X180 => open, + CLKDV => tmpLocClk, CLKFX => open, + CLKFX180 => open, LOCKED => dcmLock, + PSDONE => open, STATUS => open, + DSSEN => '0', PSCLK => '0', + PSEN => '0', PSINCDEC => '0', + RST => ponReset + ); + + + -- Global Buffer For PGP Clock + U_PgpClkBuff: BUFGMUX port map ( + O => intPgpClk, + I0 => tmpPgpClk, + I1 => '0', + S => '0' + ); + U_PgpClkBuff90: BUFGMUX port map ( + O => intPgpClk90, + I0 => tmpPgpClk90, + I1 => '0', + S => '0' + ); + + + -- Global Buffer For 125Mhz Clock + U_LocClkBuff: BUFGMUX port map ( + O => intUsrClk, + I0 => tmpLocClk, + I1 => '0', + S => '0' + ); + + U_320ClkBuff: BUFGMUX port map ( + O => int320Clk, + I0 => tmp320Clk, + I1 => '0', + S => '0' + ); + + + -- PGP Clock Synced Reset + process ( pgpClkIn ) begin + if rising_edge(pgpClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncPgpRstIn(0) <= dcmLock and ponResetL and not locReset after tpd; + syncPgpRstIn(1) <= syncPgpRstIn(0) after tpd; + syncPgpRstIn(2) <= syncPgpRstIn(1) after tpd; + + -- Reset counter on reset + if syncPgpRstIn(2) = '0' then + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + + -- Count Up To Max Value + elsif pgpRstCnt = "1111" then + intPgpRst <= '0' after tpd; + + -- Increment counter + else + intPgpRst <= '1' after tpd; + pgpRstCnt <= pgpRstCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Local 125Mhz Clock Synced Reset + process ( userClkIn ) begin + if rising_edge(userClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncLocRstIn(0) <= dcmLock and ponResetL and not locReset after tpd; + syncLocRstIn(1) <= syncLocRstIn(0) after tpd; + syncLocRstIn(2) <= syncLocRstIn(1) after tpd; + + -- Reset counter on reset + if syncLocRstIn(2) = '0' then + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + + -- Count Up To Max Value + elsif locRstCnt = "1111" then + intUsrRst <= '0' after tpd; + + -- Increment counter + else + intUsrRst <= '1' after tpd; + locRstCnt <= locRstCnt + 1 after tpd; + end if; + end if; + end process; + +end PgpClkGen; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpCmdSlave.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpCmdSlave.vhd new file mode 100644 index 0000000000000000000000000000000000000000..054385f5873a89649b2d34314c7d929daec6e2b3 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpCmdSlave.vhd @@ -0,0 +1,295 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Command Slave Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpCmdSlave.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/22/2007 +------------------------------------------------------------------------------- +-- Description: +-- Slave block for Command protocol over the PGP. +-- Packet is 16 bytes. The 16 bit values passed over the PGP will be: +-- Word 0 Data[1:0] = VC +-- Word 0 Data[7:2] = Dest_ID +-- Word 0 Data[15:8] = TID[7:0] +-- Word 1 Data[15:0] = TID[23:8] +-- Word 2 Data[7:0] = OpCode[7:0] +-- Word 2 Data[15:8] = Don't Care +-- Word 3 Data[15:0] = Don't Care +-- Word 4 = Don't Care +-- Word 5 = Don't Care +-- Word 6 = Don't Care +-- Word 7 = Don't Care +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/22/2007: created. +-- 10/10/2007: Converted context value to 32-bits. +-- 10/29/2007: Changed name of coregen blocks +-- 11/20/2007: Added check to ensure overflow will put EOFE into buffer. +-- 11/27/2007: Modified to allow the option of sync or async FIFO +-- 11/30/2007: Fixed error with back to back frames and mis-connected data lines. +-- 01/25/2008: Adjusted for new frame format. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpCmdSlave is + generic ( + DestId : natural := 0; -- Destination ID Value To Match + DestMask : natural := 0; -- Destination ID Mask For Match + AsyncFIFO : string := "TRUE" -- Use Async FIFOs, TRUE or FALSE + ); + port ( + + -- PGP Clock And Reset + pgpClk : in std_logic; -- PGP Clock + pgpReset : in std_logic; -- Synchronous PGP Reset + + -- Local clock and reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + + -- PGP Signals, Virtual Channel Rx Only + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxWidth : in std_logic; -- Data is 16-bits + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + + -- Local command signals + cmdEn : out std_logic; -- Command Enable + cmdOpCode : out std_logic_vector(7 downto 0); -- Command OpCode + cmdCtxOut : out std_logic_vector(23 downto 0) -- Command Context + ); + +end PgpCmdSlave; + + +-- Define architecture +architecture PgpCmdSlave of PgpCmdSlave is + + -- Async FIFO + component pgp_afifo_20x511 port ( + din: IN std_logic_VECTOR(19 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Sync FIFO + component pgp_fifo_20x512 port ( + din: IN std_logic_VECTOR(19 downto 0); + clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Local Signals + signal intDestId : std_logic_vector(5 downto 0); + signal selDestId : std_logic_vector(5 downto 0); + signal selDestMask : std_logic_vector(5 downto 0); + signal intCmdEn : std_logic; + signal intCmdOpCode : std_logic_vector(7 downto 0); + signal intCmdCtxOut : std_logic_vector(23 downto 0); + signal fifoDin : std_logic_vector(19 downto 0); + signal fifoDout : std_logic_vector(19 downto 0); + signal fifoRd : std_logic; + signal fifoRdDly : std_logic; + signal fifoCount : std_logic_vector(8 downto 0); + signal fifoEmpty : std_logic; + signal locSOF : std_logic; + signal locWidth : std_logic; + signal locEOF : std_logic; + signal locEOFE : std_logic; + signal locData : std_logic_vector(15 downto 0); + signal intCnt : std_logic_vector(2 downto 0); + signal intCntEn : std_logic; + signal fifoErr : std_logic; + signal fifoFull : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_afifo_20x511 : component is TRUE; + attribute syn_noprune of pgp_afifo_20x511 : component is TRUE; + attribute syn_black_box of pgp_fifo_20x512 : component is TRUE; + attribute syn_noprune of pgp_fifo_20x512 : component is TRUE; + +begin + + -- Output signal + cmdEn <= intCmdEn; + cmdOpCode <= intCmdOpCode; + cmdCtxOut <= intCmdCtxOut; + + -- Convert destnation ID and Mask + selDestId <= conv_std_logic_vector(DestId,6); + selDestMask <= conv_std_logic_vector(DestMask,6); + + -- Data going into FIFO + fifoDin(19) <= vcFrameRxSOF; + fifoDin(18) <= vcFrameRxWidth; + fifoDin(17) <= vcFrameRxEOF or fifoErr; + fifoDin(16) <= vcFrameRxEOFE or fifoErr; + fifoDin(15 downto 0) <= vcFrameRxData; + + -- Async FIFO + U_GenAFifo: if AsyncFIFO = "TRUE" generate + U_CmdAFifo: pgp_afifo_20x511 port map ( + din => fifoDin, + rd_clk => locClk, + rd_en => fifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => fifoDout, + empty => fifoEmpty, + full => fifoFull, + wr_data_count => fifoCount + ); + end generate; + + -- Sync FIFO + U_GenFifo: if AsyncFIFO = "FALSE" generate + U_CmdFifo: pgp_fifo_20x512 port map ( + din => fifoDin, + clk => pgpClk, + rd_en => fifoRd, + rst => pgpReset, + wr_en => vcFrameRxValid, + dout => fifoDout, + empty => fifoEmpty, + full => fifoFull, + data_count => fifoCount + ); + end generate; + + + -- Data coming out of FIFO + locSOF <= fifoDout(19); + locWidth <= fifoDout(18); + locEOF <= fifoDout(17); + locEOFE <= fifoDout(16); + locData <= fifoDout(15 downto 0); + + -- FIFO Read Control + fifoRd <= not fifoEmpty; + + + -- Generate flow control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + fifoErr <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Generate full error + if fifoCount >= 508 or fifoFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at half capacity + vcLocBuffAFull <= fifoCount(8); + + -- Full at 3/4 capacity + vcLocBuffFull <= fifoCount(8) and fifoCount(7); + end if; + end process; + + + -- Receive Data Processor + process ( locClk, locReset ) begin + if locReset = '1' then + intCmdEn <= '0' after tpd; + intCmdOpCode <= (others=>'0') after tpd; + intCmdCtxOut <= (others=>'0') after tpd; + intDestId <= (others=>'0') after tpd; + fifoRdDly <= '0' after tpd; + intCnt <= (others=>'0') after tpd; + intCntEn <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Generate delayed read + fifoRdDly <= fifoRd after tpd; + + -- Only process when data has been read + if fifoRdDly = '1' then + + -- Receive Data Counter + -- Reset on SOF or EOF, Start counter on SOF + if locSOF = '1' or locEOF = '1' then + intCnt <= (others=>'0') after tpd; + intCntEn <= not locEOF after tpd; + elsif intCntEn = '1' and intCnt /= "110" then + intCnt <= intCnt + 1 after tpd; + end if; + + -- SOF Received + if locSOF = '1' then + intCmdCtxOut(7 downto 0) <= locData(15 downto 8) after tpd; + intDestId <= locData(7 downto 2) after tpd; + intCmdEn <= '0' after tpd; + + -- Rest of Frame + else case intCnt is + + -- Word 1 + when "000" => + intCmdCtxOut(23 downto 8) <= locData after tpd; + intCmdEn <= '0' after tpd; + + -- Word 2 + when "001" => + intCmdOpCode <= locData(7 downto 0) after tpd; + intCmdEn <= '0' after tpd; + + -- Word 7, Last word + when "110" => + + -- No error and destination ID matches + if locEOF = '1' and locEOFE = '0' and + ( intDestId and selDestMask ) = selDestId then + intCmdEn <= '1' after tpd; + else + intCmdEn <= '0' after tpd; + end if; + + -- Do nothing for others + when others => + intCmdEn <= '0' after tpd; + end case; + end if; + else + intCmdEn <= '0' after tpd; + end if; + end if; + end process; + +end PgpCmdSlave; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpDataBuffer.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpDataBuffer.vhd new file mode 100755 index 0000000000000000000000000000000000000000..777f7be36b1d8fdd7b712def6818101d7975f183 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpDataBuffer.vhd @@ -0,0 +1,256 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Data Buffer +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpDataBuffer.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/04/2007 +------------------------------------------------------------------------------- +-- Description: +-- Data buffer for front end data sent up to RCE +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/24/2007: created. +-- 11/06/2007: Changed flow control reaction to ensure their are no short cells. +-- 11/07/2007: Changed reaction to full flag due to change in pic interface. +-- 11/09/2007: Moved PGP Fifo to common block. +-- 03/06/2008: Removed width signal. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpDataBuffer is port ( + + -- PGP Clock & Reset Signals + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- Local clock and reset + locClk : in std_logic; + locReset : in std_logic; + + -- Local data transfer signals + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + + -- PGP Virtual Channels Signals + vcFrameTxValid : out std_logic; + vcFrameTxReady : in std_logic; + vcFrameTxSOF : out std_logic; + vcFrameTxWidth : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcFrameTxCid : out std_logic_vector(31 downto 0); + vcFrameTxAckCid : in std_logic_vector(31 downto 0); + vcFrameTxAckEn : in std_logic; + vcFrameTxAck : in std_logic; + vcRemBuffAFull : in std_logic; + vcRemBuffFull : in std_logic; + + -- Overflow occured flag + dataOverFlow : out std_logic + ); +end PgpDataBuffer; + + +-- Define architecture +architecture PgpDataBuffer of PgpDataBuffer is + + -- Async Fifo + component pgp_afifo_20x511 port ( + din: IN std_logic_VECTOR(19 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- PGP Pic Buffer Block + component PgpPicRemBuff is + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + vcFrameTxValid : out std_logic; + vcFrameTxReady : in std_logic; + vcFrameTxSOF : out std_logic; + vcFrameTxWidth : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcFrameTxCid : out std_logic_vector(31 downto 0); + vcFrameTxAckCid : in std_logic_vector(31 downto 0); + vcFrameTxAckEn : in std_logic; + vcFrameTxAck : in std_logic; + vcRemBuffAFull : in std_logic; + vcRemBuffFull : in std_logic; + txFifoRd : out std_logic; + txFifoEmpty : in std_logic; + txFifoData : in std_logic_vector(15 downto 0); + txFifoSOF : in std_logic; + txFifoEOF : in std_logic; + txFifoEOFE : in std_logic + ); + end component; + + -- Local Signals + signal asyncDin : std_logic_vector(19 downto 0); + signal asyncDout : std_logic_vector(19 downto 0); + signal asyncRd : std_logic; + signal asyncCount : std_logic_vector(8 downto 0); + signal asyncEmpty : std_logic; + signal asyncFull : std_logic; + signal asyncOflowRstDly0 : std_logic; + signal asyncOflowRstDly1 : std_logic; + signal asyncOflow : std_logic; + signal asyncOflowDly0 : std_logic; + signal asyncOflowDly1 : std_logic; + signal asyncOflowRst : std_logic; + signal intOverFlow : std_logic; + signal fifoerr : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_afifo_20x511 : component is TRUE; + attribute syn_noprune of pgp_afifo_20x511 : component is TRUE; + +begin + + -- Drive overflow flag + dataOverFlow <= intOverFlow; + + -- Detect overflows on write + process ( locClk, locReset ) begin + if locReset = '1' then + asyncOflowRstDly0 <= '0' after tpd; + asyncOflowRstDly1 <= '0' after tpd; + asyncOflow <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Double sync overflow clear + asyncOflowRstDly0 <= asyncOflowRst after tpd; + asyncOflowRstDly1 <= asyncOflowRstDly0 after tpd; + + -- Overflow write clear + if asyncOflowRstDly1 = '1' then + asyncOflow <= '0' after tpd; + + -- Overflow write + elsif asyncFull = '1' and frameTxEnable = '1' then + asyncOflow <= '1' after tpd; + end if; + end if; + end process; + + + -- PGP Clock Version Of Overflow + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + asyncOflowDly0 <= '0' after tpd; + asyncOflowDly1 <= '0' after tpd; + asyncOflowRst <= '0' after tpd; + intOverFlow <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Sync overflow signal + asyncOflowDly0 <= asyncOflow after tpd; + asyncOflowDly1 <= asyncOflowDly0 after tpd; + + -- Generate overflow reset + asyncOflowRst <= asyncOflowDly1 after tpd; + + -- Generate overflow signal + intOverFlow <= asyncOflowDly1 and not intOverFlow after tpd; + + end if; + end process; + + + -- Write data into FIFO + asyncDin(19) <= frameTxEOFE or fifoErr; + asyncDin(18) <= frameTxEOF or fifoErr; + asyncDin(17) <= '1'; -- Width + asyncDin(16) <= frameTxSOF; + asyncDin(15 downto 0) <= frameTxData; + + -- Generate fifo error signal + process ( locClk, locReset ) begin + if locReset = '1' then + fifoErr <= '0' after tpd; + frameTxAFull <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Generate full error + if asyncCount >= 508 or asyncFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at 3/4 capacity + frameTxAFull <= asyncFull or (asyncCount(8) and asyncCount(7)); + + end if; + end process; + + -- Async FIFO + U_AsyncFifo: pgp_afifo_20x511 port map ( + din => asyncDin, + rd_clk => pgpClk, + rd_en => asyncRd, + rst => pgpReset, + wr_clk => locClk, + wr_en => frameTxEnable, + dout => asyncDout, + empty => asyncEmpty, + full => asyncFull, + wr_data_count => asyncCount + ); + + + -- PGP Pic Buffer Block + U_PgpBuffer: PgpPicRemBuff port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + vcFrameTxValid => vcFrameTxValid, + vcFrameTxReady => vcFrameTxReady, + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxWidth => vcFrameTxWidth, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcFrameTxCid => vcFrameTxCid, + vcFrameTxAckCid => vcFrameTxAckCid, + vcFrameTxAckEn => vcFrameTxAckEn, + vcFrameTxAck => vcFrameTxAck, + vcRemBuffAFull => vcRemBuffAFull, + vcRemBuffFull => vcRemBuffFull, + txFifoRd => asyncRd, + txFifoEmpty => asyncEmpty, + txFifoData => asyncDout(15 downto 0), + txFifoSOF => asyncDout(16), + txFifoEOF => asyncDout(18), + txFifoEOFE => asyncDout(19) + ); + +end PgpDataBuffer; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpDsBuff.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpDsBuff.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e5d350e0a52febcdbb596d5fcfaeced96acacc7b --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpDsBuff.vhd @@ -0,0 +1,150 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Downstream Data Buffer +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : PgpDsBuff.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/11/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for buffer block for downstream data. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/11/2010: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpDsBuff is port ( + + -- Clock and reset + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + + -- PGP Receive Signals + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxWidth : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + + -- Local data transfer signals + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); +end PgpDsBuff; + + +-- Define architecture +architecture PgpDsBuff of PgpDsBuff is + + -- Async Fifo + component pgp_afifo_20x511 port ( + din: IN std_logic_VECTOR(19 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Local Signals + signal rxFifoDin : std_logic_vector(19 downto 0); + signal rxFifoDout : std_logic_vector(19 downto 0); + signal rxFifoRd : std_logic; + signal rxFifoValid : std_logic; + signal rxFifoCount : std_logic_vector(8 downto 0); + signal rxFifoEmpty : std_logic; + signal rxFifoFull : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_afifo_20x511 : component is TRUE; + attribute syn_noprune of pgp_afifo_20x511 : component is TRUE; + +begin + + -- Data going into Rx FIFO + rxFifoDin(19) <= '0'; + rxFifoDin(18) <= vcFrameRxSOF; + rxFifoDin(17) <= vcFrameRxEOF; + rxFifoDin(16) <= vcFrameRxEOFE; + rxFifoDin(15 downto 0) <= vcFrameRxData; + + -- Generate flow control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Almost full at quarter capacity + --vcLocBuffAFull <= rxFifoCount(8); + vcLocBuffAFull <= rxFifoCount(8) or rxFifoCount(7); + + -- Full at half capacity + vcLocBuffFull <= rxFifoFull or rxFifoCount(8); + end if; + end process; + + -- Async FIFO + U_RegRxAFifo: pgp_afifo_20x511 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + + -- Data valid + process ( locClk, locReset ) begin + if locReset = '1' then + rxFifoValid <= '0' after tpd; + elsif rising_edge(locClk) then + if rxFifoRd = '1' then + rxFifoValid <= '1' after tpd; + elsif frameRxReady = '1' then + rxFifoValid <= '0' after tpd; + end if; + end if; + end process; + + -- Control reads + rxFifoRd <= (not rxFifoEmpty) and ((not rxFifoValid) or frameRxReady); + + -- Outgoing signals + frameRxValid <= rxFifoValid; + frameRxSOF <= rxFifoDout(18); + frameRxEOF <= rxFifoDout(17); + frameRxEOFE <= rxFifoDout(16); + frameRxData <= rxFifoDout(15 downto 0); + +end PgpDsBuff; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpFrontEnd.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpFrontEnd.vhd new file mode 100755 index 0000000000000000000000000000000000000000..3f6e9ca0da9b037101c39ed2fd2060f95174b6ed --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpFrontEnd.vhd @@ -0,0 +1,890 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Front End Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpFrontEnd.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/24/2007 +------------------------------------------------------------------------------- +-- Description: +-- Wrapper for front end logic connection to the RCE. +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/24/2007: created. +-- 03/06/2008: Removed width signal. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use work.Version.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpFrontEnd is + generic ( + MgtMode : string := "A"; -- Default Location + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + + -- Reference Clock, PGP Clock & Reset Signals + -- Use one ref clock, tie other to 0, see RefClkSel above + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + mgtRxRecClk : out std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- Display Digits + pgpDispA : out std_logic_vector(7 downto 0); + pgpDispB : out std_logic_vector(7 downto 0); + + -- Reset output + resetOut : out std_logic; + + -- Local clock and reset + locClk : in std_logic; + locReset : in std_logic; + + -- Local command signal + cmdEn : out std_logic; + cmdOpCode : out std_logic_vector(7 downto 0); + cmdCtxOut : out std_logic_vector(23 downto 0); + + -- Local register control signals + regReq : out std_logic; + regOp : out std_logic; + regInp : out std_logic; + regAck : in std_logic; + regFail : in std_logic; + regAddr : out std_logic_vector(23 downto 0); + regDataOut : out std_logic_vector(31 downto 0); + regDataIn : in std_logic_vector(31 downto 0); + + -- Local data transfer signals + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0); + valid : out std_logic; + eof : out std_logic; + sof : out std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + + -- MGT Signals For Simulation, + -- Drive mgtCombusIn to 0's, Leave mgtCombusOut open for real use + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); +end PgpFrontEnd; + + +-- Define architecture +architecture PgpFrontEnd of PgpFrontEnd is + + -- PGP Block + component PgpMgtWrap + generic ( + MgtMode : string := "A"; -- Default Location + AckTimeout : natural := 8; -- Ack/Nack Not Received Timeout, 8.192uS Steps + PicMode : natural := 0; -- PIC Interface Mode, 1=PIC, 0=Normal + RefClkSel : string := "REFCLK1"; -- Reference Clock To Use "REFCLK1" or "REFCLK2" + CScopeEnPhy : string := "DISABLE" -- Insert ChipScope, Enable or Disable + ); + port ( + pgpClk : in std_logic; -- 125Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pibReLink : in std_logic; -- Re-Link control signal + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxWidth : in std_logic; -- User frame data width + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc0FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc0FrameTxAck : out std_logic; -- PGP ACK/NACK + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxWidth : in std_logic; -- User frame data width + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc1FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc1FrameTxAck : out std_logic; -- PGP ACK/NACK + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxWidth : in std_logic; -- User frame data width + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc2FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc2FrameTxAck : out std_logic; -- PGP ACK/NACK + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxWidth : in std_logic; -- User frame data width + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc3FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc3FrameTxAck : out std_logic; -- PGP ACK/NACK + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxWidth : out std_logic; -- PGP frame data width + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxWidth : out std_logic; -- PGP frame data width + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc2FrameRxWidth : out std_logic; -- PGP frame data width + vc2FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc2FrameRxEOFE : out std_logic; -- PGP frame data error + vc2FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc3FrameRxWidth : out std_logic; -- PGP frame data width + vc3FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc3FrameRxEOFE : out std_logic; -- PGP frame data error + vc3FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + localVersion : out std_logic_vector(7 downto 0); -- Local version ID + remoteVersion : out std_logic_vector(7 downto 0); -- Remote version ID + pibFail : out std_logic; -- PIB fail indication + pibState : out std_logic_vector(2 downto 0); -- PIB State + pibLock : out std_logic_vector(1 downto 0); -- PIB Lock Bits, 0=Rx, 1=Tx + pibLinkReady : out std_logic; -- PIB link is ready + pgpSeqError : out std_logic; -- PGP Sequence Logic Error Occured + countLinkDown : out std_logic; -- Link down count increment + countLinkError : out std_logic; -- Link error count increment + countNack : out std_logic; -- NACK count increment + countCellError : out std_logic; -- Receive Cell error count increment + mgtDAddr : in std_logic_vector( 7 downto 0); -- MGT Configuration Address + mgtDClk : in std_logic; -- MGT Configuration Clock + mgtDEn : in std_logic; -- MGT Configuration Data Enable + mgtDI : in std_logic_vector(15 downto 0); -- MGT Configuration Data In + mgtDO : out std_logic_vector(15 downto 0); -- MGT Configuration Data Out + mgtDRdy : out std_logic; -- MGT Configuration Ready + mgtDWe : in std_logic; -- MGT Configuration Write Enable + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + mgtInverted : out std_logic; -- MGT Received Data Is Inverted + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic; -- MGT Serial Receive Negative + mgtRxP : in std_logic; -- MGT Serial Receive Positive + mgtTxN : out std_logic; -- MGT Serial Transmit Negative + mgtTxP : out std_logic; -- MGT Serial Transmit Positive + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); + end component; + + -- Command Block + component PgpCmdSlave + generic ( + DestId : natural := 0; -- Destination ID Value To Match + DestMask : natural := 0; -- Destination ID Mask For Match + AsyncFIFO : string := "TRUE" -- Use Async FIFOs, TRUE or FALSE + ); + port ( + pgpClk : in std_logic; -- PGP Clock + pgpReset : in std_logic; -- Synchronous PGP Reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxWidth : in std_logic; -- Data is 16-bits + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + cmdEn : out std_logic; -- Command Enable + cmdOpCode : out std_logic_vector(7 downto 0); -- Command OpCode + cmdCtxOut : out std_logic_vector(23 downto 0) -- Command Context + ); + end component; + + -- Register access block + component PgpRegSlave + generic ( + AsyncFIFO : string := "TRUE" -- Use Async FIFOs, TRUE or FALSE + ); + port ( + pgpClk : in std_logic; -- PGP Clock + pgpReset : in std_logic; -- Synchronous PGP Reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxWidth : in std_logic; -- Data is 16-bits + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + vcFrameTxValid : out std_logic; -- User frame data is valid + vcFrameTxReady : in std_logic; -- PGP is ready + vcFrameTxSOF : out std_logic; -- User frame data start of frame + vcFrameTxWidth : out std_logic; -- User frame data width + vcFrameTxEOF : out std_logic; -- User frame data end of frame + vcFrameTxEOFE : out std_logic; -- User frame data error + vcFrameTxData : out std_logic_vector(15 downto 0); -- User frame data + vcFrameTxCid : out std_logic_vector(31 downto 0); -- User frame data, context ID + vcFrameTxAckCid : in std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vcFrameTxAckEn : in std_logic; -- PGP ACK/NACK enable + vcFrameTxAck : in std_logic; -- PGP ACK/NACK + vcRemBuffAFull : in std_logic; -- Remote buffer almost full + vcRemBuffFull : in std_logic; -- Remote buffer full + regInp : out std_logic; -- Register Access In Progress Flag + regReq : out std_logic; -- Register Access Request + regOp : out std_logic; -- Register OpCode, 0=Read, 1=Write + regAck : in std_logic; -- Register Access Acknowledge + regFail : in std_logic; -- Register Access Fail + regAddr : out std_logic_vector(23 downto 0); -- Register Address + regDataOut : out std_logic_vector(31 downto 0); -- Register Data Out + regDataIn : in std_logic_vector(31 downto 0) -- Register Data In + ); + end component; + + -- Data buffer + component PgpDataBuffer + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + vcFrameTxValid : out std_logic; + vcFrameTxReady : in std_logic; + vcFrameTxSOF : out std_logic; + vcFrameTxWidth : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcFrameTxCid : out std_logic_vector(31 downto 0); + vcFrameTxAckCid : in std_logic_vector(31 downto 0); + vcFrameTxAckEn : in std_logic; + vcFrameTxAck : in std_logic; + vcRemBuffAFull : in std_logic; + vcRemBuffFull : in std_logic; + dataOverFlow : out std_logic + ); + end component; + + -- Downstream buffer + component PgpDsBuff + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxWidth : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); + end component; + + -- Local Signals + signal pibReLink : std_logic; + signal vc0FrameTxValid : std_logic; + signal vc0FrameTxReady : std_logic; + signal vc0FrameTxSOF : std_logic; + signal vc0FrameTxWidth : std_logic; + signal vc0FrameTxEOF : std_logic; + signal vc0FrameTxEOFE : std_logic; + signal vc0FrameTxData : std_logic_vector(15 downto 0); + signal vc0FrameTxCid : std_logic_vector(31 downto 0); + signal vc0FrameTxAckCid : std_logic_vector(31 downto 0); + signal vc0FrameTxAckEn : std_logic; + signal vc0FrameTxAck : std_logic; + signal vc0RemBuffAFull : std_logic; + signal vc0RemBuffFull : std_logic; + signal vc1FrameTxValid : std_logic; + signal vc1FrameTxReady : std_logic; + signal vc1FrameTxSOF : std_logic; + signal vc1FrameTxWidth : std_logic; + signal vc1FrameTxEOF : std_logic; + signal vc1FrameTxEOFE : std_logic; + signal vc1FrameTxData : std_logic_vector(15 downto 0); + signal vc1FrameTxCid : std_logic_vector(31 downto 0); + signal vc1FrameTxAckCid : std_logic_vector(31 downto 0); + signal vc1FrameTxAckEn : std_logic; + signal vc1FrameTxAck : std_logic; + signal vc1RemBuffAFull : std_logic; + signal vc1RemBuffFull : std_logic; + signal vc2FrameTxValid : std_logic; + signal vc2FrameTxReady : std_logic; + signal vc2FrameTxSOF : std_logic; + signal vc2FrameTxWidth : std_logic; + signal vc2FrameTxEOF : std_logic; + signal vc2FrameTxEOFE : std_logic; + signal vc2FrameTxData : std_logic_vector(15 downto 0); + signal vc2FrameTxCid : std_logic_vector(31 downto 0); + signal vc2FrameTxAckCid : std_logic_vector(31 downto 0); + signal vc2FrameTxAckEn : std_logic; + signal vc2FrameTxAck : std_logic; + signal vc2RemBuffAFull : std_logic; + signal vc2RemBuffFull : std_logic; + signal vc3FrameTxValid : std_logic; + signal vc3FrameTxReady : std_logic; + signal vc3FrameTxSOF : std_logic; + signal vc3FrameTxWidth : std_logic; + signal vc3FrameTxEOF : std_logic; + signal vc3FrameTxEOFE : std_logic; + signal vc3FrameTxData : std_logic_vector(15 downto 0); + signal vc3FrameTxCid : std_logic_vector(31 downto 0); + signal vc3FrameTxAckCid : std_logic_vector(31 downto 0); + signal vc3FrameTxAckEn : std_logic; + signal vc3FrameTxAck : std_logic; + signal vc3RemBuffAFull : std_logic; + signal vc3RemBuffFull : std_logic; + signal vc0FrameRxValid : std_logic; + signal vc0FrameRxSOF : std_logic; + signal vc0FrameRxWidth : std_logic; + signal vc0FrameRxEOF : std_logic; + signal vc0FrameRxEOFE : std_logic; + signal vc0FrameRxData : std_logic_vector(15 downto 0); + signal vc0LocBuffAFull : std_logic; + signal vc0LocBuffFull : std_logic; + signal vc1FrameRxValid : std_logic; + signal vc1FrameRxSOF : std_logic; + signal vc1FrameRxWidth : std_logic; + signal vc1FrameRxEOF : std_logic; + signal vc1FrameRxEOFE : std_logic; + signal vc1FrameRxData : std_logic_vector(15 downto 0); + signal vc1LocBuffAFull : std_logic; + signal vc1LocBuffFull : std_logic; + signal vc2FrameRxValid : std_logic; + signal vc2FrameRxSOF : std_logic; + signal vc2FrameRxWidth : std_logic; + signal vc2FrameRxEOF : std_logic; + signal vc2FrameRxEOFE : std_logic; + signal vc2FrameRxData : std_logic_vector(15 downto 0); + signal vc2LocBuffAFull : std_logic; + signal vc2LocBuffFull : std_logic; + signal vc3FrameRxValid : std_logic; + signal vc3FrameRxSOF : std_logic; + signal vc3FrameRxWidth : std_logic; + signal vc3FrameRxEOF : std_logic; + signal vc3FrameRxEOFE : std_logic; + signal vc3FrameRxData : std_logic_vector(15 downto 0); + signal vc3LocBuffAFull : std_logic; + signal vc3LocBuffFull : std_logic; + signal pibState : std_logic_vector(2 downto 0); + signal pibLock : std_logic_vector(1 downto 0); + signal countLinkDown : std_logic; + signal countLinkError : std_logic; + signal countNack : std_logic; + signal countCellError : std_logic; + signal mgtInverted : std_logic; + signal cntLinkError : std_logic_vector(3 downto 0); + signal cntNack : std_logic_vector(3 downto 0); + signal cntCellError : std_logic_vector(3 downto 0); + signal cntLinkDown : std_logic_vector(3 downto 0); + signal cntOverFlow : std_logic_vector(3 downto 0); + signal pllLock : std_logic; + signal pllLockDly : std_logic; + signal cntPllLock : std_logic_vector(3 downto 0); + signal pgpSeqError : std_logic; + signal intRegReq : std_logic; + signal intRegOp : std_logic; + signal intRegAck : std_logic; + signal intRegFail : std_logic; + signal intRegAddr : std_logic_vector(23 downto 0); + signal intRegDataOut : std_logic_vector(31 downto 0); + signal intRegDataIn : std_logic_vector(31 downto 0); + signal intCmdEn : std_logic; + signal intCmdOpCode : std_logic_vector(7 downto 0); + signal intCmdCtxOut : std_logic_vector(23 downto 0); + signal scratchPad : std_logic_vector(31 downto 0); + signal countReset : std_logic; + signal dataOverFlow : std_logic; + signal intCmdAFull : std_logic; + signal intCmdFull : std_logic; + signal extCmdAFull : std_logic; + signal extCmdFull : std_logic; + signal pibError : std_logic; + signal txCount : std_logic_vector(31 downto 0); + signal pibLinkReady : std_logic; + signal pibFail : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Display values + pgpDispB <= x"0" & txCount(3 downto 0); + pgpDispA <= x"10" when pllLock = '0' else -- Display 'P' + x"0F" when pibFail = '1' else -- Display 'F' + x"11" when pibLinkReady = '0' else -- Display 'N' + x"0E" when pibError = '1' else -- Display 'E' + x"12"; -- Display 'L' + + -- Detect error status + pibError <= '1' when (cntLinkError & cntCellError & cntNack) /= 0 else pgpSeqError; + + -- Transaction Counter + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + txCount <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + if pibLinkReady = '0' then + txCount <= (others=>'0') after tpd; + else + if (vc0FrameTxReady = '1' and vc0FrameTxEOF = '1') or + (vc1FrameTxReady = '1' and vc1FrameTxEOF = '1') or + (vc2FrameTxReady = '1' and vc2FrameTxEOF = '1') or + (vc3FrameTxReady = '1' and vc3FrameTxEOF = '1') then + txCount <= txCount + 1 after tpd; + end if; + end if; + end if; + end process; + + + -- Register read and write + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intRegDataIn <= (others=>'0') after tpd; + intRegAck <= '0' after tpd; + intRegFail <= '0' after tpd; + scratchPad <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Register request is pending + if intRegReq = '1' then + + -- Drive ack + intRegAck <= '1' after tpd; + + -- Read + if intRegOp = '0' then + + -- Which register + case intRegAddr is + + when x"000000" => + intRegDataIn <= FpgaVersion after tpd; + intRegFail <= '0' after tpd; + + when x"000001" => + intRegDataIn <= scratchPad after tpd; + intRegFail <= '0' after tpd; + + when x"000002" => + intRegDataIn(31) <= '0' after tpd; + intRegDataIn(30) <= '0' after tpd; + intRegDataIn(29) <= mgtInverted after tpd; + intRegDataIn(28) <= pgpSeqError after tpd; + intRegDataIn(27 downto 24) <= cntOverFlow after tpd; + intRegDataIn(23 downto 20) <= cntPllLock after tpd; + intRegDataIn(19 downto 16) <= cntLinkDown after tpd; + intRegDataIn(15 downto 12) <= cntLinkError after tpd; + intRegDataIn(11 downto 8) <= cntNack after tpd; + intRegDataIn( 7 downto 4) <= cntCellError after tpd; + intRegDataIn( 3 downto 0) <= "0000" after tpd; + intRegFail <= '0' after tpd; + + when x"000003" => + intRegDataIn <= txCount after tpd; + intRegFail <= '0' after tpd; + + when others => + intRegFail <= '1' after tpd; + intRegDataIn <= (others=>'0') after tpd; + end case; + + -- Write + else + + -- Scratchpad write + if intRegAddr = x"000001" then + intRegFail <= '0' after tpd; + scratchPad <= intRegDataOut after tpd; + else + intRegFail <= '1' after tpd; + end if; + end if; + + -- No Request + else + intRegAck <= '0' after tpd; + intRegFail <= '0' after tpd; + intRegDataIn <= (others=>'0') after tpd; + end if; + end if; + end process; + + + -- Internal command receiver + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + resetOut <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Internal command received + if intCmdEn = '1' then + + -- Reset + if intCmdOpCode = "00000000" then + resetOut <= '1' after tpd; + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + + -- Count Reset + elsif intCmdOpCode = "00000001" then + countReset <= '1' after tpd; + pibReLink <= '0' after tpd; + + -- PGP Relink + elsif intCmdOpCode = "00000010" then + countReset <= '0' after tpd; + pibReLink <= '1' after tpd; + + else + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + end if; + else + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + end if; + end if; + end process; + + + -- Error Counters + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + cntLinkError <= (others=>'0') after tpd; + cntNack <= (others=>'0') after tpd; + cntCellError <= (others=>'0') after tpd; + cntLinkDown <= (others=>'0') after tpd; + cntPllLock <= (others=>'0') after tpd; + cntOverFlow <= (others=>'0') after tpd; + pllLock <= '0' after tpd; + pllLockDly <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Link Error Counter, 8-bits + if countReset = '1' or pibLinkReady = '0' then + cntLinkError <= (others=>'0') after tpd; + elsif countLinkError = '1' and cntLinkError /= x"F" then + cntLinkError <= cntLinkError + 1 after tpd; + end if; + + -- Nack Counter, 8-bits + if countReset = '1' or pibLinkReady = '0' then + cntNack <= (others=>'0') after tpd; + elsif countNack = '1' and cntNack /= x"F" then + cntNack <= cntNack + 1 after tpd; + end if; + + -- Cell Error Counter, 8-bits + if countReset = '1' or pibLinkReady = '0' then + cntCellError <= (others=>'0') after tpd; + elsif countCellError = '1' and cntCellError /= x"F" then + cntCellError <= cntCellError + 1 after tpd; + end if; + + -- Link Down Counter, 8-bits + if countReset = '1' then + cntLinkDown <= (others=>'0') after tpd; + elsif countLinkDown = '1' and cntLinkDown /= x"F" then + cntLinkDown <= cntLinkDown + 1 after tpd; + end if; + + -- PLL Unlock Counter + if countReset = '1' or pibLinkReady = '0' then + cntPllLock <= (others=>'0') after tpd; + elsif pllLock = '0' and pllLockDly = '1' and cntPllLock /= x"F" then + cntPllLock <= cntPllLock + 1 after tpd; + end if; + + -- PLL Lock Edge Detection + pllLock <= pibLock(1) and pibLock(0) after tpd; + pllLockDly <= pllLock after tpd; + + -- Data overflow counter + if countReset = '1' then + cntOverFlow <= (others=>'0') after tpd; + elsif dataOverFlow = '1'and cntOverFlow /= x"F" then + cntOverFlow <= cntOverFlow + 1 after tpd; + end if; + + end if; + end process; + + + -- PGP Wrap + U_PgpMgtWrap: PgpMgtWrap + generic map ( MgtMode => MgtMode, AckTimeout => 8, + PicMode => 0, RefClkSel => RefClkSel, + CScopeEnPhy => "DISABLE" ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pibReLink => pibReLink, + vc0FrameTxValid => vc0FrameTxValid, vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, vc0FrameTxWidth => vc0FrameTxWidth, + vc0FrameTxEOF => vc0FrameTxEOF, vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, vc0FrameTxCid => vc0FrameTxCid, + vc0FrameTxAckCid => vc0FrameTxAckCid, vc0FrameTxAckEn => vc0FrameTxAckEn, + vc0FrameTxAck => vc0FrameTxAck, vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxWidth => vc1FrameTxWidth, vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, vc1FrameTxData => vc1FrameTxData, + vc1FrameTxCid => vc1FrameTxCid, vc1FrameTxAckCid => vc1FrameTxAckCid, + vc1FrameTxAckEn => vc1FrameTxAckEn, vc1FrameTxAck => vc1FrameTxAck, + vc1RemBuffAFull => vc1RemBuffAFull, vc1RemBuffFull => vc1RemBuffFull, + vc2FrameTxValid => vc2FrameTxValid, vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, vc2FrameTxWidth => vc2FrameTxWidth, + vc2FrameTxEOF => vc2FrameTxEOF, vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, vc2FrameTxCid => vc2FrameTxCid, + vc2FrameTxAckCid => vc2FrameTxAckCid, vc2FrameTxAckEn => vc2FrameTxAckEn, + vc2FrameTxAck => vc2FrameTxAck, vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxWidth => vc3FrameTxWidth, vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, vc3FrameTxData => vc3FrameTxData, + vc3FrameTxCid => vc3FrameTxCid, vc3FrameTxAckCid => vc3FrameTxAckCid, + vc3FrameTxAckEn => vc3FrameTxAckEn, vc3FrameTxAck => vc3FrameTxAck, + vc3RemBuffAFull => vc3RemBuffAFull, vc3RemBuffFull => vc3RemBuffFull, + vc0FrameRxValid => vc0FrameRxValid, vc0FrameRxSOF => vc0FrameRxSOF, + vc0FrameRxWidth => vc0FrameRxWidth, vc0FrameRxEOF => vc0FrameRxEOF, + vc0FrameRxEOFE => vc0FrameRxEOFE, vc0FrameRxData => vc0FrameRxData, + vc0LocBuffAFull => vc0LocBuffAFull, vc0LocBuffFull => vc0LocBuffFull, + vc1FrameRxValid => vc1FrameRxValid, vc1FrameRxSOF => vc1FrameRxSOF, + vc1FrameRxWidth => vc1FrameRxWidth, vc1FrameRxEOF => vc1FrameRxEOF, + vc1FrameRxEOFE => vc1FrameRxEOFE, vc1FrameRxData => vc1FrameRxData, + vc1LocBuffAFull => vc1LocBuffAFull, vc1LocBuffFull => vc1LocBuffFull, + vc2FrameRxValid => vc2FrameRxValid, vc2FrameRxSOF => vc2FrameRxSOF, + vc2FrameRxWidth => vc2FrameRxWidth, vc2FrameRxEOF => vc2FrameRxEOF, + vc2FrameRxEOFE => vc2FrameRxEOFE, vc2FrameRxData => vc2FrameRxData, + vc2LocBuffAFull => vc2LocBuffAFull, vc2LocBuffFull => vc2LocBuffFull, + vc3FrameRxValid => vc3FrameRxValid, vc3FrameRxSOF => vc3FrameRxSOF, + vc3FrameRxWidth => vc3FrameRxWidth, vc3FrameRxEOF => vc3FrameRxEOF, + vc3FrameRxEOFE => vc3FrameRxEOFE, vc3FrameRxData => vc3FrameRxData, + vc3LocBuffAFull => vc3LocBuffAFull, vc3LocBuffFull => vc3LocBuffFull, + localVersion => open, remoteVersion => open, + pibFail => pibFail, pibState => pibState, + pibLinkReady => pibLinkReady, pgpSeqError => pgpSeqError, + countLinkDown => countLinkDown, countLinkError => countLinkError, + countNack => countNack, countCellError => countCellError, + mgtDAddr => (others=>'0'), mgtDClk => '0', + mgtDEn => '0', mgtDI => (others=>'0'), + mgtDO => open, mgtDRdy => open, + mgtDWe => '0', mgtLoopback => '0', + mgtInverted => mgtInverted, mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, mgtCombusIn => mgtCombusIn, + mgtCombusOut => mgtCombusOut, pibLock => pibLock, + mgtRxRecClk => mgtRxRecClk + ); + + + -- VC0, External command processor + U_ExtCmd: PgpCmdSlave + generic map ( + DestId => 0, + DestMask => 1, + AsyncFIFO => "TRUE" + ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + locClk => locClk, locReset => locReset, + vcFrameRxValid => vc0FrameRxValid, vcFrameRxSOF => vc0FrameRxSOF, + vcFrameRxWidth => vc0FrameRxWidth, vcFrameRxEOF => vc0FrameRxEOF, + vcFrameRxEOFE => vc0FrameRxEOFE, vcFrameRxData => vc0FrameRxData, + vcLocBuffAFull => extCmdAFull, vcLocBuffFull => extCmdFull, + cmdEn => cmdEn, cmdOpCode => cmdOpCode, + cmdCtxOut => cmdCtxOut + ); + + + -- VC0, Internal command processor + U_IntCmd: PgpCmdSlave + generic map ( + DestId => 1, + DestMask => 1, + AsyncFIFO => "FALSE" + ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + locClk => pgpClk, locReset => pgpReset, + vcFrameRxValid => vc0FrameRxValid, vcFrameRxSOF => vc0FrameRxSOF, + vcFrameRxWidth => vc0FrameRxWidth, vcFrameRxEOF => vc0FrameRxEOF, + vcFrameRxEOFE => vc0FrameRxEOFE, vcFrameRxData => vc0FrameRxData, + vcLocBuffAFull => intCmdAFull, vcLocBuffFull => intCmdFull, + cmdEn => intCmdEn, cmdOpCode => intCmdOpCode, + cmdCtxOut => intCmdCtxOut + ); + + -- Generate flow control + vc0LocBuffAFull <= extCmdAFull or intCmdAFull; + vc0LocBuffFull <= extCmdFull or intCmdFull; + + + -- Return data, VC0 + U_DataBuff: PgpDataBuffer port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + locClk => locClk, locReset => locReset, + frameTxEnable => frameTxEnable, frameTxSOF => frameTxSOF, + frameTxEOF => frameTxEOF, frameTxEOFE => frameTxEOFE, + frameTxData => frameTxData, frameTxAFull => frameTxAFull, + vcFrameTxValid => vc0FrameTxValid, + vcFrameTxReady => vc0FrameTxReady, vcFrameTxSOF => vc0FrameTxSOF, + vcFrameTxWidth => vc0FrameTxWidth, vcFrameTxEOF => vc0FrameTxEOF, + vcFrameTxEOFE => vc0FrameTxEOFE, vcFrameTxData => vc0FrameTxData, + vcFrameTxCid => vc0FrameTxCid, vcFrameTxAckCid => vc0FrameTxAckCid, + vcFrameTxAckEn => vc0FrameTxAckEn, vcFrameTxAck => vc0FrameTxAck, + vcRemBuffAFull => vc0RemBuffAFull, vcRemBuffFull => vc0RemBuffFull, + dataOverFlow => dataOverFlow + ); + + valid<=vc0FrameTxValid; + eof<=vc0FrameTxEOF; + sof<=vc0FrameTxSOF; + + -- VC1, External register access control + U_ExtReg: PgpRegSlave generic map ( AsyncFIFO => "TRUE" ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + locClk => locClk, locReset => locReset, + vcFrameRxValid => vc1FrameRxValid, vcFrameRxSOF => vc1FrameRxSOF, + vcFrameRxWidth => vc1FrameRxWidth, vcFrameRxEOF => vc1FrameRxEOF, + vcFrameRxEOFE => vc1FrameRxEOFE, vcFrameRxData => vc1FrameRxData, + vcLocBuffAFull => vc1LocBuffAFull, vcLocBuffFull => vc1LocBuffFull, + vcFrameTxValid => vc1FrameTxValid, vcFrameTxReady => vc1FrameTxReady, + vcFrameTxSOF => vc1FrameTxSOF, vcFrameTxWidth => vc1FrameTxWidth, + vcFrameTxEOF => vc1FrameTxEOF, vcFrameTxEOFE => vc1FrameTxEOFE, + vcFrameTxData => vc1FrameTxData, vcFrameTxCid => vc1FrameTxCid, + vcFrameTxAckCid => vc1FrameTxAckCid, vcFrameTxAckEn => vc1FrameTxAckEn, + vcFrameTxAck => vc1FrameTxAck, vcRemBuffAFull => vc1RemBuffAFull, + vcRemBuffFull => vc1RemBuffFull, regReq => regReq, + regOp => regOp, regAck => regAck, + regFail => regFail, regAddr => regAddr, + regDataOut => regDataOut, regDataIn => regDataIn, + regInp => regInp + ); + + + -- VC2, Internal register access control + U_IntReg: PgpRegSlave generic map ( AsyncFIFO => "FALSE" ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + locClk => pgpClk, locReset => pgpReset, + vcFrameRxValid => vc2FrameRxValid, vcFrameRxSOF => vc2FrameRxSOF, + vcFrameRxWidth => vc2FrameRxWidth, vcFrameRxEOF => vc2FrameRxEOF, + vcFrameRxEOFE => vc2FrameRxEOFE, vcFrameRxData => vc2FrameRxData, + vcLocBuffAFull => vc2LocBuffAFull, vcLocBuffFull => vc2LocBuffFull, + vcFrameTxValid => vc2FrameTxValid, vcFrameTxReady => vc2FrameTxReady, + vcFrameTxSOF => vc2FrameTxSOF, vcFrameTxWidth => vc2FrameTxWidth, + vcFrameTxEOF => vc2FrameTxEOF, vcFrameTxEOFE => vc2FrameTxEOFE, + vcFrameTxData => vc2FrameTxData, vcFrameTxCid => vc2FrameTxCid, + vcFrameTxAckCid => vc2FrameTxAckCid, vcFrameTxAckEn => vc2FrameTxAckEn, + vcFrameTxAck => vc2FrameTxAck, vcRemBuffAFull => vc2RemBuffAFull, + vcRemBuffFull => vc2RemBuffFull, regReq => intRegReq, + regOp => intRegOp, regAck => intRegAck, + regFail => intRegFail, regAddr => intRegAddr, + regDataOut => intRegDataOut, regDataIn => intRegDataIn + ); + + -- VC3, Downstream data + U_DsBuff: PgpDsBuff port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + locClk => locClk, + locReset => locReset, + vcFrameRxValid => vc3FrameRxValid, + vcFrameRxSOF => vc3FrameRxSOF, + vcFrameRxWidth => vc3FrameRxWidth, + vcFrameRxEOF => vc3FrameRxEOF, + vcFrameRxEOFE => vc3FrameRxEOFE, + vcFrameRxData => vc3FrameRxData, + vcLocBuffAFull => vc3LocBuffAFull, + vcLocBuffFull => vc3LocBuffFull, + frameRxValid => frameRxValid, + frameRxReady => frameRxReady, + frameRxSOF => frameRxSOF, + frameRxEOF => frameRxEOF, + frameRxEOFE => frameRxEOFE, + frameRxData => frameRxData + ); + + -- VC3 transmit is unused + vc3FrameTxValid <= '0'; + vc3FrameTxEOFE <= '0'; + vc3FrameTxEOF <= '0'; + vc3FrameTxWidth <= '0'; + vc3FrameTxSOF <= '0'; + vc3FrameTxData <= (others=>'0'); + vc3FrameTxCid <= (others=>'0'); + +end PgpFrontEnd; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpMgtWrap.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpMgtWrap.vhd new file mode 100755 index 0000000000000000000000000000000000000000..63a2db485d89ff4dcf531492581ee0158a561772 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpMgtWrap.vhd @@ -0,0 +1,1590 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, MGT Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpMgtWrap.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 03/15/2007 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, MGT and CRC blocks. +-- This module also contains the logic to control the reset of the MGT. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 03/15/2007: created. +-- 06/01/2007: Included MGT block instead of using xilinx wrapper. +-- 06/08/2007: CRC blocks now held in reset when link is down. +-- 06/08/2007: Added Lock Bits +-- 08/25/2007: Changed error count signals. +-- 09/18/2007: Added force cell size signal +-- 09/19/2007: Changed force cell size signal to PIC mode signal +-- 09/21/2007: Ack timeout & Pic Mode converted to generics, +-- Added Generic for reference clock selection and ref clock 2 in +-- 01/25/2008: Added MGT Recovered Clock Output +-- 11/05/2008: Added reset state machine logic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +-- synopsys translate_off +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; +-- synopsys translate_on + + +entity PgpMgtWrap is + generic ( + MgtMode : string := "A"; -- Default Location + AckTimeout : natural := 8; -- Ack/Nack Not Received Timeout, 8.192uS Steps + PicMode : natural := 1; -- PIC Interface Mode, 1=PIC, 0=Normal + RefClkSel : string := "REFCLK1"; -- Reference Clock To Use "REFCLK1" or "REFCLK2" + CScopeEnPhy : string := "DISABLE" -- Insert ChipScope, Enable or Disable + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 125Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pibReLink : in std_logic; -- Re-Link control signal + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxWidth : in std_logic; -- User frame data width + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc0FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc0FrameTxAck : out std_logic; -- PGP ACK/NACK + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxWidth : in std_logic; -- User frame data width + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc1FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc1FrameTxAck : out std_logic; -- PGP ACK/NACK + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxWidth : in std_logic; -- User frame data width + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc2FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc2FrameTxAck : out std_logic; -- PGP ACK/NACK + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxWidth : in std_logic; -- User frame data width + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc3FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc3FrameTxAck : out std_logic; -- PGP ACK/NACK + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxWidth : out std_logic; -- PGP frame data width + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxWidth : out std_logic; -- PGP frame data width + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc2FrameRxWidth : out std_logic; -- PGP frame data width + vc2FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc2FrameRxEOFE : out std_logic; -- PGP frame data error + vc2FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc3FrameRxWidth : out std_logic; -- PGP frame data width + vc3FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc3FrameRxEOFE : out std_logic; -- PGP frame data error + vc3FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + + -- Event Counters & Status Signals + localVersion : out std_logic_vector(7 downto 0); -- Local version ID + remoteVersion : out std_logic_vector(7 downto 0); -- Remote version ID + pibFail : out std_logic; -- PIB fail indication + pibState : out std_logic_vector(2 downto 0); -- PIB State + pibLock : out std_logic_vector(1 downto 0); -- PIB Lock Bits, 0=Rx, 1=Tx + pibLinkReady : out std_logic; -- PIB link is ready + pgpSeqError : out std_logic; -- PGP Sequence Logic Error Occured + countLinkDown : out std_logic; -- Link down count increment + countLinkError : out std_logic; -- Disparity/Decode err count + countNack : out std_logic; -- NACK count increment + countCellError : out std_logic; -- Receive cell error count + + -- MGT Configuration Port + mgtDAddr : in std_logic_vector( 7 downto 0); -- MGT Configuration Address + mgtDClk : in std_logic; -- MGT Configuration Clock + mgtDEn : in std_logic; -- MGT Configuration Data Enable + mgtDI : in std_logic_vector(15 downto 0); -- MGT Configuration Data In + mgtDO : out std_logic_vector(15 downto 0); -- MGT Configuration Data Out + mgtDRdy : out std_logic; -- MGT Configuration Ready + mgtDWe : in std_logic; -- MGT Configuration Write Enable + + -- MGT Status & Control Signals + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + mgtInverted : out std_logic; -- MGT Received Data Is Inverted + + -- MGT Signals, Drive Ref Clock Which Matches RefClkSel Generic Above + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic; -- MGT Serial Receive Negative + mgtRxP : in std_logic; -- MGT Serial Receive Positive + mgtTxN : out std_logic; -- MGT Serial Transmit Negative + mgtTxP : out std_logic; -- MGT Serial Transmit Positive + + -- MGT Signals For Simulation, + -- Drive mgtCombusIn to 0's, Leave mgtCombusOut open for real use + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); + +end PgpMgtWrap; + + +-- Define architecture +architecture PgpMgtWrap of PgpMgtWrap is + + -- PGP Core + component PgpTop + generic ( + AckTimeout : natural := 8; -- Ack/Nack Not Received Timeout, 8.192uS Steps + PicMode : natural := 0 -- PIC Interface Mode, 1=PIC, 0=Normal + ); + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + pibReLink : in std_logic; + vc0FrameTxValid : in std_logic; + vc0FrameTxReady : out std_logic; + vc0FrameTxSOF : in std_logic; + vc0FrameTxWidth : in std_logic; + vc0FrameTxEOF : in std_logic; + vc0FrameTxEOFE : in std_logic; + vc0FrameTxData : in std_logic_vector(15 downto 0); + vc0FrameTxCid : in std_logic_vector(31 downto 0); + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); + vc0FrameTxAckEn : out std_logic; + vc0FrameTxAck : out std_logic; + vc0RemBuffAFull : out std_logic; + vc0RemBuffFull : out std_logic; + vc1FrameTxValid : in std_logic; + vc1FrameTxReady : out std_logic; + vc1FrameTxSOF : in std_logic; + vc1FrameTxWidth : in std_logic; + vc1FrameTxEOF : in std_logic; + vc1FrameTxEOFE : in std_logic; + vc1FrameTxData : in std_logic_vector(15 downto 0); + vc1FrameTxCid : in std_logic_vector(31 downto 0); + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); + vc1FrameTxAckEn : out std_logic; + vc1FrameTxAck : out std_logic; + vc1RemBuffAFull : out std_logic; + vc1RemBuffFull : out std_logic; + vc2FrameTxValid : in std_logic; + vc2FrameTxReady : out std_logic; + vc2FrameTxSOF : in std_logic; + vc2FrameTxWidth : in std_logic; + vc2FrameTxEOF : in std_logic; + vc2FrameTxEOFE : in std_logic; + vc2FrameTxData : in std_logic_vector(15 downto 0); + vc2FrameTxCid : in std_logic_vector(31 downto 0); + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); + vc2FrameTxAckEn : out std_logic; + vc2FrameTxAck : out std_logic; + vc2RemBuffAFull : out std_logic; + vc2RemBuffFull : out std_logic; + vc3FrameTxValid : in std_logic; + vc3FrameTxReady : out std_logic; + vc3FrameTxSOF : in std_logic; + vc3FrameTxWidth : in std_logic; + vc3FrameTxEOF : in std_logic; + vc3FrameTxEOFE : in std_logic; + vc3FrameTxData : in std_logic_vector(15 downto 0); + vc3FrameTxCid : in std_logic_vector(31 downto 0); + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); + vc3FrameTxAckEn : out std_logic; + vc3FrameTxAck : out std_logic; + vc3RemBuffAFull : out std_logic; + vc3RemBuffFull : out std_logic; + vc0FrameRxValid : out std_logic; + vc0FrameRxSOF : out std_logic; + vc0FrameRxWidth : out std_logic; + vc0FrameRxEOF : out std_logic; + vc0FrameRxEOFE : out std_logic; + vc0FrameRxData : out std_logic_vector(15 downto 0); + vc0LocBuffAFull : in std_logic; + vc0LocBuffFull : in std_logic; + vc1FrameRxValid : out std_logic; + vc1FrameRxSOF : out std_logic; + vc1FrameRxWidth : out std_logic; + vc1FrameRxEOF : out std_logic; + vc1FrameRxEOFE : out std_logic; + vc1FrameRxData : out std_logic_vector(15 downto 0); + vc1LocBuffAFull : in std_logic; + vc1LocBuffFull : in std_logic; + vc2FrameRxValid : out std_logic; + vc2FrameRxSOF : out std_logic; + vc2FrameRxWidth : out std_logic; + vc2FrameRxEOF : out std_logic; + vc2FrameRxEOFE : out std_logic; + vc2FrameRxData : out std_logic_vector(15 downto 0); + vc2LocBuffAFull : in std_logic; + vc2LocBuffFull : in std_logic; + vc3FrameRxValid : out std_logic; + vc3FrameRxSOF : out std_logic; + vc3FrameRxWidth : out std_logic; + vc3FrameRxEOF : out std_logic; + vc3FrameRxEOFE : out std_logic; + vc3FrameRxData : out std_logic_vector(15 downto 0); + vc3LocBuffAFull : in std_logic; + vc3LocBuffFull : in std_logic; + crcTxIn : out std_logic_vector(15 downto 0); + crcTxInit : out std_logic; + crcTxValid : out std_logic; + crcTxWidth : out std_logic; + crcTxOut : in std_logic_vector(31 downto 0); + crcRxIn : out std_logic_vector(15 downto 0); + crcRxInit : out std_logic; + crcRxValid : out std_logic; + crcRxWidth : out std_logic; + crcRxOut : in std_logic_vector(31 downto 0); + phyRxPolarity : out std_logic; + phyRxData : in std_logic_vector(15 downto 0); + phyRxDataK : in std_logic_vector(1 downto 0); + phyTxData : out std_logic_vector(15 downto 0); + phyTxDataK : out std_logic_vector(1 downto 0); + phyLinkError : in std_logic; + phyInitDone : in std_logic; + localVersion : out std_logic_vector(7 downto 0); + remoteVersion : out std_logic_vector(7 downto 0); + pibFail : out std_logic; + pibState : out std_logic_vector(2 downto 0); + pibLinkReady : out std_logic; + pgpSeqError : out std_logic; + countLinkError : out std_logic; + countLinkDown : out std_logic; + countNack : out std_logic; + countCellError : out std_logic + ); + end component; + + + -- MGT Block + component + GT11 generic ( + ALIGN_COMMA_WORD : integer := 1; + BANDGAPSEL : boolean := FALSE; + BIASRESSEL : boolean := TRUE; + CCCB_ARBITRATOR_DISABLE : boolean := FALSE; + CHAN_BOND_LIMIT : integer := 16; + CHAN_BOND_MODE : string := "NONE"; + CHAN_BOND_ONE_SHOT : boolean := FALSE; + CHAN_BOND_SEQ_1_1 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_1_2 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_1_3 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_1_4 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_1_MASK : bit_vector := "0000"; + CHAN_BOND_SEQ_2_1 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_2_2 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_2_3 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_2_4 : bit_vector := "00000000000"; + CHAN_BOND_SEQ_2_MASK : bit_vector := "0000"; + CHAN_BOND_SEQ_2_USE : boolean := FALSE; + CHAN_BOND_SEQ_LEN : integer := 1; + CLK_COR_8B10B_DE : boolean := FALSE; + CLK_COR_MAX_LAT : integer := 48; + CLK_COR_MIN_LAT : integer := 36; + CLK_COR_SEQ_1_1 : bit_vector := "00000000000"; + CLK_COR_SEQ_1_2 : bit_vector := "00000000000"; + CLK_COR_SEQ_1_3 : bit_vector := "00000000000"; + CLK_COR_SEQ_1_4 : bit_vector := "00000000000"; + CLK_COR_SEQ_1_MASK : bit_vector := "0000"; + CLK_COR_SEQ_2_1 : bit_vector := "00000000000"; + CLK_COR_SEQ_2_2 : bit_vector := "00000000000"; + CLK_COR_SEQ_2_3 : bit_vector := "00000000000"; + CLK_COR_SEQ_2_4 : bit_vector := "00000000000"; + CLK_COR_SEQ_2_MASK : bit_vector := "0000"; + CLK_COR_SEQ_2_USE : boolean := FALSE; + CLK_COR_SEQ_DROP : boolean := FALSE; + CLK_COR_SEQ_LEN : integer := 1; + CLK_CORRECT_USE : boolean := TRUE; + COMMA_10B_MASK : bit_vector := x"3FF"; + COMMA32 : boolean := FALSE; + CYCLE_LIMIT_SEL : bit_vector := "00"; + DCDR_FILTER : bit_vector := "010"; + DEC_MCOMMA_DETECT : boolean := TRUE; + DEC_PCOMMA_DETECT : boolean := TRUE; + DEC_VALID_COMMA_ONLY : boolean := TRUE; + DIGRX_FWDCLK : bit_vector := "00"; + DIGRX_SYNC_MODE : boolean := FALSE; + ENABLE_DCDR : boolean := FALSE; + FDET_HYS_CAL : bit_vector := "110"; + FDET_HYS_SEL : bit_vector := "110"; + FDET_LCK_CAL : bit_vector := "101"; + FDET_LCK_SEL : bit_vector := "101"; + GT11_MODE : string := "DONT_CARE"; + IREFBIASMODE : bit_vector := "11"; + LOOPCAL_WAIT : bit_vector := "00"; + MCOMMA_32B_VALUE : bit_vector := x"000000F6"; + MCOMMA_DETECT : boolean := TRUE; + OPPOSITE_SELECT : boolean := FALSE; + PCOMMA_32B_VALUE : bit_vector := x"F6F62828"; + PCOMMA_DETECT : boolean := TRUE; + PCS_BIT_SLIP : boolean := FALSE; + PMA_BIT_SLIP : boolean := FALSE; + PMACLKENABLE : boolean := TRUE; + PMACOREPWRENABLE : boolean := TRUE; + PMAIREFTRIM : bit_vector := "0111"; + PMAVBGCTRL : bit_vector := "00000"; + PMAVREFTRIM : bit_vector := "0111"; + POWER_ENABLE : boolean := TRUE; + REPEATER : boolean := FALSE; + RX_BUFFER_USE : boolean := TRUE; + RX_CLOCK_DIVIDER : bit_vector := "00"; + RXACTST : boolean := FALSE; + RXAFEEQ : bit_vector := "000000000"; + RXAFEPD : boolean := FALSE; + RXAFETST : boolean := FALSE; + RXAPD : boolean := FALSE; + RXASYNCDIVIDE : bit_vector := "11"; + RXBY_32 : boolean := TRUE; + RXCDRLOS : bit_vector := "000000"; + RXCLK0_FORCE_PMACLK : boolean := FALSE; + RXCLKMODE : bit_vector := "000010"; + RXCMADJ : bit_vector := "10"; + RXCPSEL : boolean := TRUE; + RXCPTST : boolean := FALSE; + RXCRCCLOCKDOUBLE : boolean := FALSE; + RXCRCENABLE : boolean := FALSE; + RXCRCINITVAL : bit_vector := x"00000000"; + RXCRCINVERTGEN : boolean := FALSE; + RXCRCSAMECLOCK : boolean := FALSE; + RXCTRL1 : bit_vector := x"200"; + RXCYCLE_LIMIT_SEL : bit_vector := "00"; + RXDATA_SEL : bit_vector := "00"; + RXDCCOUPLE : boolean := FALSE; + RXDIGRESET : boolean := FALSE; + RXDIGRX : boolean := FALSE; + RXEQ : bit_vector := x"4000000000000000"; + RXFDCAL_CLOCK_DIVIDE : string := "NONE"; + RXFDET_HYS_CAL : bit_vector := "110"; + RXFDET_HYS_SEL : bit_vector := "110"; + RXFDET_LCK_CAL : bit_vector := "101"; + RXFDET_LCK_SEL : bit_vector := "101"; + RXFECONTROL1 : bit_vector := "00"; + RXFECONTROL2 : bit_vector := "000"; + RXFETUNE : bit_vector := "01"; + RXLB : boolean := FALSE; + RXLKADJ : bit_vector := "00000"; + RXLKAPD : boolean := FALSE; + RXLOOPCAL_WAIT : bit_vector := "00"; + RXLOOPFILT : bit_vector := "0111"; + RXOUTDIV2SEL : integer := 1; + RXPD : boolean := FALSE; + RXPDDTST : boolean := FALSE; + RXPLLNDIVSEL : integer := 8; + RXPMACLKSEL : string := "REFCLK1"; + RXRCPADJ : bit_vector := "011"; + RXRCPPD : boolean := FALSE; + RXRECCLK1_USE_SYNC : boolean := FALSE; + RXRIBADJ : bit_vector := "11"; + RXRPDPD : boolean := FALSE; + RXRSDPD : boolean := FALSE; + RXSLOWDOWN_CAL : bit_vector := "00"; + RXUSRDIVISOR : integer := 1; + RXVCO_CTRL_ENABLE : boolean := TRUE; + RXVCODAC_INIT : bit_vector := "1010000000"; + SAMPLE_8X : boolean := FALSE; + SH_CNT_MAX : integer := 64; + SH_INVALID_CNT_MAX : integer := 16; + SLOWDOWN_CAL : bit_vector := "00"; + TX_BUFFER_USE : boolean := TRUE; + TX_CLOCK_DIVIDER : bit_vector := "00"; + TXABPMACLKSEL : string := "REFCLK1"; + TXAPD : boolean := FALSE; + TXAREFBIASSEL : boolean := FALSE; + TXASYNCDIVIDE : bit_vector := "11"; + TXCLK0_FORCE_PMACLK : boolean := FALSE; + TXCLKMODE : bit_vector := "1001"; + TXCPSEL : boolean := TRUE; + TXCRCCLOCKDOUBLE : boolean := FALSE; + TXCRCENABLE : boolean := FALSE; + TXCRCINITVAL : bit_vector := x"00000000"; + TXCRCINVERTGEN : boolean := FALSE; + TXCRCSAMECLOCK : boolean := FALSE; + TXCTRL1 : bit_vector := x"200"; + TXDAT_PRDRV_DAC : bit_vector := "111"; + TXDAT_TAP_DAC : bit_vector := "10110"; + TXDATA_SEL : bit_vector := "00"; + TXDIGPD : boolean := FALSE; + TXFDCAL_CLOCK_DIVIDE : string := "NONE"; + TXHIGHSIGNALEN : boolean := TRUE; + TXLOOPFILT : bit_vector := "0111"; + TXLVLSHFTPD : boolean := FALSE; + TXOUTCLK1_USE_SYNC : boolean := FALSE; + TXOUTDIV2SEL : integer := 1; + TXPD : boolean := FALSE; + TXPHASESEL : boolean := FALSE; + TXPLLNDIVSEL : integer := 8; + TXPOST_PRDRV_DAC : bit_vector := "111"; + TXPOST_TAP_DAC : bit_vector := "01110"; + TXPOST_TAP_PD : boolean := TRUE; + TXPRE_PRDRV_DAC : bit_vector := "111"; + TXPRE_TAP_DAC : bit_vector := "00000"; + TXPRE_TAP_PD : boolean := TRUE; + TXSLEWRATE : boolean := FALSE; + TXTERMTRIM : bit_vector := "1100"; + VCO_CTRL_ENABLE : boolean := TRUE; + VCODAC_INIT : bit_vector := "1010000000"; + VREFBIASMODE : bit_vector := "11" + ); + port ( + CHBONDI : in std_logic_vector (4 downto 0); + ENCHANSYNC : in std_logic; + ENMCOMMAALIGN : in std_logic; + ENPCOMMAALIGN : in std_logic; + LOOPBACK : in std_logic_vector (1 downto 0); + POWERDOWN : in std_logic; + RXBLOCKSYNC64B66BUSE : in std_logic; + RXCOMMADETUSE : in std_logic; + RXDATAWIDTH : in std_logic_vector (1 downto 0); + RXDEC64B66BUSE : in std_logic; + RXDEC8B10BUSE : in std_logic; + RXDESCRAM64B66BUSE : in std_logic; + RXIGNOREBTF : in std_logic; + RXINTDATAWIDTH : in std_logic_vector (1 downto 0); + RXPOLARITY : in std_logic; + RXRESET : in std_logic; + RXSLIDE : in std_logic; + RXUSRCLK : in std_logic; + RXUSRCLK2 : in std_logic; + TXBYPASS8B10B : in std_logic_vector (7 downto 0); + TXCHARDISPMODE : in std_logic_vector (7 downto 0); + TXCHARDISPVAL : in std_logic_vector (7 downto 0); + TXCHARISK : in std_logic_vector (7 downto 0); + TXDATA : in std_logic_vector (63 downto 0); + TXDATAWIDTH : in std_logic_vector (1 downto 0); + TXENC64B66BUSE : in std_logic; + TXENC8B10BUSE : in std_logic; + TXGEARBOX64B66BUSE : in std_logic; + TXINHIBIT : in std_logic; + TXINTDATAWIDTH : in std_logic_vector (1 downto 0); + TXPOLARITY : in std_logic; + TXRESET : in std_logic; + TXSCRAM64B66BUSE : in std_logic; + TXUSRCLK : in std_logic; + TXUSRCLK2 : in std_logic; + RXCLKSTABLE : in std_logic; + RXPMARESET : in std_logic; + TXCLKSTABLE : in std_logic; + TXPMARESET : in std_logic; + RXCRCIN : in std_logic_vector (63 downto 0); + RXCRCDATAWIDTH : in std_logic_vector (2 downto 0); + RXCRCDATAVALID : in std_logic; + RXCRCINIT : in std_logic; + RXCRCRESET : in std_logic; + RXCRCPD : in std_logic; + RXCRCCLK : in std_logic; + RXCRCINTCLK : in std_logic; + TXCRCIN : in std_logic_vector (63 downto 0); + TXCRCDATAWIDTH : in std_logic_vector (2 downto 0); + TXCRCDATAVALID : in std_logic; + TXCRCINIT : in std_logic; + TXCRCRESET : in std_logic; + TXCRCPD : in std_logic; + TXCRCCLK : in std_logic; + TXCRCINTCLK : in std_logic; + TXSYNC : in std_logic; + RXSYNC : in std_logic; + TXENOOB : in std_logic; + DCLK : in std_logic; + DADDR : in std_logic_vector (7 downto 0); + DEN : in std_logic; + DWE : in std_logic; + DI : in std_logic_vector (15 downto 0); + RX1P : in std_logic; + RX1N : in std_logic; + GREFCLK : in std_logic; + REFCLK1 : in std_logic; + REFCLK2 : in std_logic; + CHBONDO : out std_logic_vector (4 downto 0); + RXSTATUS : out std_logic_vector (5 downto 0); + RXCHARISCOMMA : out std_logic_vector (7 downto 0); + RXCHARISK : out std_logic_vector (7 downto 0); + RXCOMMADET : out std_logic; + RXDATA : out std_logic_vector (63 downto 0); + RXDISPERR : out std_logic_vector (7 downto 0); + RXLOSSOFSYNC : out std_logic_vector (1 downto 0); + RXNOTINTABLE : out std_logic_vector (7 downto 0); + RXREALIGN : out std_logic; + RXRUNDISP : out std_logic_vector (7 downto 0); + RXBUFERR : out std_logic; + TXBUFERR : out std_logic; + TXKERR : out std_logic_vector (7 downto 0); + TXRUNDISP : out std_logic_vector (7 downto 0); + RXRECCLK1 : out std_logic; + RXRECCLK2 : out std_logic; + TXOUTCLK1 : out std_logic; + TXOUTCLK2 : out std_logic; + RXLOCK : out std_logic; + TXLOCK : out std_logic; + RXCYCLELIMIT : out std_logic; + TXCYCLELIMIT : out std_logic; + RXCALFAIL : out std_logic; + TXCALFAIL : out std_logic; + RXCRCOUT : out std_logic_vector (31 downto 0); + TXCRCOUT : out std_logic_vector (31 downto 0); + RXSIGDET : out std_logic; + DRDY : out std_logic; + DO : out std_logic_vector (15 downto 0); + RXMCLK : out std_logic; + TX1P : out std_logic; + TX1N : out std_logic; + TXPCSHCLKOUT : out std_logic; + RXPCSHCLKOUT : out std_logic; + COMBUSIN : in std_logic_vector (15 downto 0); + COMBUSOUT : out std_logic_vector (15 downto 0) + ); + end component; + + + -- Local Signals + signal crcTxIn : std_logic_vector(15 downto 0); + signal crcTxInMgt : std_logic_vector(63 downto 0); + signal crcTxInit : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic; + signal crcTxWidthMgt : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(15 downto 0); + signal crcRxInMgt : std_logic_vector(63 downto 0); + signal crcRxInit : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic; + signal crcRxWidthMgt : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic; + signal phyRxData : std_logic_vector(15 downto 0); + signal phyRxDataK : std_logic_vector(1 downto 0); + signal phyTxData : std_logic_vector(15 downto 0); + signal phyTxDataK : std_logic_vector(1 downto 0); + signal mgtRxPmaReset : std_logic; + signal mgtTxPmaReset : std_logic; + signal mgtRxReset : std_logic; + signal mgtTxReset : std_logic; + signal mgtRxBuffError : std_logic; + signal mgtTxBuffError : std_logic; + signal mgtRxDispErr : std_logic_vector(1 downto 0); + signal mgtRxDecErr : std_logic_vector(1 downto 0); + signal mgtRxLock : std_logic; + signal mgtTxLock : std_logic; + signal crcRxReset : std_logic; + signal crcTxReset : std_logic; + signal txPcsResetCnt : std_logic_vector(3 downto 0); + signal txPcsResetCntRst : std_logic; + signal txPcsResetCntEn : std_logic; + signal txStateCnt : std_logic_vector(5 downto 0); + signal txStateCntRst : std_logic; + signal rxPcsResetCnt : std_logic_vector(3 downto 0); + signal rxPcsResetCntRst : std_logic; + signal rxPcsResetCntEn : std_logic; + signal rxStateCnt : std_logic_vector(13 downto 0); + signal rxStateCntRst : std_logic; + signal intRxPmaReset : std_logic; + signal intTxPmaReset : std_logic; + signal intRxReset : std_logic; + signal intTxReset : std_logic; + signal txClockReady : std_logic; + signal rxClockReady : std_logic; + signal intLinkReady : std_logic; + signal phyLinkError : std_logic; + signal phyInitDone : std_logic; + + -- RX Reset State Machine + constant RX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant RX_PMA_RESET : std_logic_vector(2 downto 0) := "001"; + constant RX_WAIT_LOCK : std_logic_vector(2 downto 0) := "010"; + constant RX_PCS_RESET : std_logic_vector(2 downto 0) := "011"; + constant RX_WAIT_PCS : std_logic_vector(2 downto 0) := "100"; + constant RX_ALMOST_READY : std_logic_vector(2 downto 0) := "101"; + constant RX_READY : std_logic_vector(2 downto 0) := "110"; + signal curRxState : std_logic_vector(2 downto 0); + signal nxtRxState : std_logic_vector(2 downto 0); + + -- TX Reset State Machine + constant TX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant TX_PMA_RESET : std_logic_vector(2 downto 0) := "001"; + constant TX_WAIT_LOCK : std_logic_vector(2 downto 0) := "010"; + constant TX_PCS_RESET : std_logic_vector(2 downto 0) := "011"; + constant TX_WAIT_PCS : std_logic_vector(2 downto 0) := "100"; + constant TX_ALMOST_READY : std_logic_vector(2 downto 0) := "101"; + constant TX_READY : std_logic_vector(2 downto 0) := "110"; + signal curTxState : std_logic_vector(2 downto 0); + signal nxtTxState : std_logic_vector(2 downto 0); + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of GT11 : component is TRUE; + attribute syn_noprune of GT11 : component is TRUE; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Pgp + U_PgpTop: PgpTop + generic map (AckTimeout => AckTimeout, + PicMode => PicMode ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pibReLink => pibReLink, + vc0FrameTxValid => vc0FrameTxValid, vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, vc0FrameTxWidth => vc0FrameTxWidth, + vc0FrameTxEOF => vc0FrameTxEOF, vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, vc0FrameTxCid => vc0FrameTxCid, + vc0FrameTxAckCid => vc0FrameTxAckCid, vc0FrameTxAckEn => vc0FrameTxAckEn, + vc0FrameTxAck => vc0FrameTxAck, vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxWidth => vc1FrameTxWidth, vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, vc1FrameTxData => vc1FrameTxData, + vc1FrameTxCid => vc1FrameTxCid, vc1FrameTxAckCid => vc1FrameTxAckCid, + vc1FrameTxAckEn => vc1FrameTxAckEn, vc1FrameTxAck => vc1FrameTxAck, + vc1RemBuffAFull => vc1RemBuffAFull, vc1RemBuffFull => vc1RemBuffFull, + vc2FrameTxValid => vc2FrameTxValid, vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, vc2FrameTxWidth => vc2FrameTxWidth, + vc2FrameTxEOF => vc2FrameTxEOF, vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, vc2FrameTxCid => vc2FrameTxCid, + vc2FrameTxAckCid => vc2FrameTxAckCid, vc2FrameTxAckEn => vc2FrameTxAckEn, + vc2FrameTxAck => vc2FrameTxAck, vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxWidth => vc3FrameTxWidth, vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, vc3FrameTxData => vc3FrameTxData, + vc3FrameTxCid => vc3FrameTxCid, vc3FrameTxAckCid => vc3FrameTxAckCid, + vc3FrameTxAckEn => vc3FrameTxAckEn, vc3FrameTxAck => vc3FrameTxAck, + vc3RemBuffAFull => vc3RemBuffAFull, vc3RemBuffFull => vc3RemBuffFull, + vc0FrameRxValid => vc0FrameRxValid, vc0FrameRxSOF => vc0FrameRxSOF, + vc0FrameRxWidth => vc0FrameRxWidth, vc0FrameRxEOF => vc0FrameRxEOF, + vc0FrameRxEOFE => vc0FrameRxEOFE, vc0FrameRxData => vc0FrameRxData, + vc0LocBuffAFull => vc0LocBuffAFull, vc0LocBuffFull => vc0LocBuffFull, + vc1FrameRxValid => vc1FrameRxValid, vc1FrameRxSOF => vc1FrameRxSOF, + vc1FrameRxWidth => vc1FrameRxWidth, vc1FrameRxEOF => vc1FrameRxEOF, + vc1FrameRxEOFE => vc1FrameRxEOFE, vc1FrameRxData => vc1FrameRxData, + vc1LocBuffAFull => vc1LocBuffAFull, vc1LocBuffFull => vc1LocBuffFull, + vc2FrameRxValid => vc2FrameRxValid, vc2FrameRxSOF => vc2FrameRxSOF, + vc2FrameRxWidth => vc2FrameRxWidth, vc2FrameRxEOF => vc2FrameRxEOF, + vc2FrameRxEOFE => vc2FrameRxEOFE, vc2FrameRxData => vc2FrameRxData, + vc2LocBuffAFull => vc2LocBuffAFull, vc2LocBuffFull => vc2LocBuffFull, + vc3FrameRxValid => vc3FrameRxValid, vc3FrameRxSOF => vc3FrameRxSOF, + vc3FrameRxWidth => vc3FrameRxWidth, vc3FrameRxEOF => vc3FrameRxEOF, + vc3FrameRxEOFE => vc3FrameRxEOFE, vc3FrameRxData => vc3FrameRxData, + vc3LocBuffAFull => vc3LocBuffAFull, vc3LocBuffFull => vc3LocBuffFull, + crcTxIn => crcTxIn, crcTxInit => crcTxInit, + crcTxValid => crcTxValid, crcTxWidth => crcTxWidth, + crcTxOut => crcTxOut, crcRxIn => crcRxIn, + crcRxInit => crcRxInit, crcRxValid => crcRxValid, + crcRxWidth => crcRxWidth, crcRxOut => crcRxOut, + phyRxPolarity => phyRxPolarity, phyRxData => phyRxData, + phyRxDataK => phyRxDataK, phyTxData => phyTxData, + phyTxDataK => phyTxDataK, phyLinkError => phyLinkError, + phyInitDone => phyInitDone, localVersion => localVersion, + remoteVersion => remoteVersion, pibFail => pibFail, + pibState => pibState, pibLinkReady => intLinkReady, + pgpSeqError => pgpSeqError, countLinkDown => countLinkDown, + countLinkError => countLinkError, countNack => countNack, + countCellError => countCellError + ); + + + -- Lock & Polarity Signals + mgtInverted <= phyRxPolarity; + pibLinkReady <= intLinkReady; + + -- Adapt CRC data width flag + crcTxWidthMgt(2 downto 1) <= "00"; + crcTxWidthMgt(0) <= crcTxWidth; + crcRxWidthMgt(2 downto 1) <= "00"; + crcRxWidthMgt(0) <= crcRxWidth; + crcRxReset <= mgtRxReset; + crcTxReset <= mgtTxReset; + + -- Pass CRC data in on proper bits + crcTxInMgt(63 downto 56) <= crcTxIn(7 downto 0); + crcTxInMgt(55 downto 48) <= crcTxIn(15 downto 8); + crcTxInMgt(47 downto 0) <= (others=>'0'); + crcRxInMgt(63 downto 56) <= crcRxIn(7 downto 0); + crcRxInMgt(55 downto 48) <= crcRxIn(15 downto 8); + crcRxInMgt(47 downto 0) <= (others=>'0'); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGT : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "NONE", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00000000000", + CHAN_BOND_SEQ_1_2 => "00000000000", + CHAN_BOND_SEQ_1_3 => "00000000000", + CHAN_BOND_SEQ_1_4 => "00000000000", + CHAN_BOND_SEQ_1_MASK => "1110", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 1, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => MgtMode, + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "001", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "111", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "001", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "100", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => TRUE, + RXAFETST => TRUE, + RXCMADJ => "10", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "10", + RXFECONTROL2 => "111", + RXFETUNE => "00", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => FALSE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "0101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE + + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => crcRxValid, + RXCRCDATAWIDTH => crcRxWidthMgt, + RXCRCIN => crcRxInMgt, + RXCRCINIT => crcRxInit, + RXCRCINTCLK => pgpClk, + RXCRCOUT => crcRxOut, + RXCRCPD => '0', + RXCRCRESET => crcRxReset, + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => crcTxValid, + TXCRCDATAWIDTH => crcTxWidthMgt, + TXCRCIN => crcTxInMgt, + TXCRCINIT => crcTxInit, + TXCRCINTCLK => pgpClk, + TXCRCOUT => crcTxOut, + TXCRCPD => '0', + TXCRCRESET => crcTxReset, + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN, + RX1P => mgtRxP, + TX1N => mgtTxN, + TX1P => mgtTxP, + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock, + TXLOCK => mgtTxLock, + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset, + RXRESET => mgtRxReset, + TXPMARESET => mgtTxPmaReset, + TXRESET => mgtTxReset, + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError, + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError, + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity, + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => (others=>'0'), + CHBONDO => open, + ENCHANSYNC => '0', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => "000000", + TXBYPASS8B10B(1 downto 0) => "00", + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => x"00", + TXCHARDISPVAL(7 downto 0) => x"00", + TXCHARISK(7 downto 2) => "000000", + TXCHARISK(1 downto 0) => phyTxDataK, + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK, + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => mgtRxDispErr, + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => mgtRxDecErr, + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData, + TXDATA(63 downto 16) => x"000000000000", + TXDATA(15 downto 0) => phyTxData, + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => mgtRxRecClk, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => mgtDAddr, + DCLK => mgtDClk, + DEN => mgtDEn, + DI => mgtDI, + DO => mgtDO, + DRDY => mgtDRdy, + DWE => mgtDWe, + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusIn, + COMBUSOUT => mgtCombusOut + ); + + + -- TX & RX State Machine Synchronous Logic + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + curTxState <= TX_SYSTEM_RESET after tpd; + curRxState <= RX_SYSTEM_RESET after tpd; + txPcsResetCnt <= (others=>'0') after tpd; + txStateCnt <= (others=>'0') after tpd; + rxPcsResetCnt <= (others=>'0') after tpd; + rxStateCnt <= (others=>'0') after tpd; + mgtRxPmaReset <= '1' after tpd; + mgtTxPmaReset <= '1' after tpd; + mgtRxReset <= '0' after tpd; + mgtTxReset <= '0' after tpd; + phyLinkError <= '0' after tpd; + pibLock <= (others=>'0') after tpd; + phyInitDone <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Drive PIB Lock + pibLock(0) <= rxClockReady after tpd; + pibLock(1) <= txClockReady after tpd; + + -- Phy Init Is Done + phyInitDone <= rxClockReady and txClockReady after tpd; + + -- Error signals, only drive during normal operation + if mgtRxDecErr /= "00" or mgtRxDispErr /= "00" then + phyLinkError <= intLinkReady after tpd; + else + phyLinkError <= '0' after tpd; + end if; + + -- Pass on reset signals + mgtRxPmaReset <= intRxPmaReset after tpd; + mgtTxPmaReset <= intTxPmaReset after tpd; + mgtRxReset <= intRxReset after tpd; + mgtTxReset <= intTxReset after tpd; + + -- Update state + if pibReLink = '1' then + curTxState <= TX_WAIT_LOCK after tpd; + curRxState <= RX_WAIT_LOCK after tpd; + else + curTxState <= nxtTxState after tpd; + curRxState <= nxtRxState after tpd; + end if; + + -- Tx State Counter + if txStateCntRst = '1' or pibReLink = '1' then + txStateCnt <= (others=>'0') after tpd; + else + txStateCnt <= txStateCnt + 1 after tpd; + end if; + + -- TX Loop Counter + if txPcsResetCntRst = '1' or pibReLink = '1' then + txPcsResetCnt <= (others=>'0') after tpd; + elsif txPcsResetCntEn = '1' then + txPcsResetCnt <= txPcsResetCnt + 1 after tpd; + end if; + + -- Rx State Counter + if rxStateCntRst = '1' or pibReLink = '1' then + rxStateCnt <= (others=>'0') after tpd; + else + rxStateCnt <= rxStateCnt + 1 after tpd; + end if; + + -- RX Loop Counter + if rxPcsResetCntRst = '1' or pibReLink = '1' then + rxPcsResetCnt <= (others=>'0') after tpd; + elsif rxPcsResetCntEn = '1' then + rxPcsResetCnt <= rxPcsResetCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Async TX State Logic + process ( curTxState, txStateCnt, mgtTxLock, mgtTxBuffError, txPcsResetCnt ) begin + case curTxState is + + -- System Reset State + when TX_SYSTEM_RESET => + txPcsResetCntRst <= '1'; + txPcsResetCntEn <= '0'; + txStateCntRst <= '1'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txClockReady <= '0'; + nxtTxState <= TX_PMA_RESET; + + -- PMA Reset State + when TX_PMA_RESET => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '1'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Wait for three clocks + if txStateCnt = 3 then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Wait for TX Lock + when TX_WAIT_LOCK => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '1'; + txClockReady <= '0'; + + -- Wait for three clocks + if mgtTxLock = '1' then + nxtTxState <= TX_PCS_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Assert PCS Reset + when TX_PCS_RESET => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '1'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + + -- Wait for three clocks + elsif txStateCnt = 3 then + nxtTxState <= TX_WAIT_PCS; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Wait 5 clocks after PCS reset + when TX_WAIT_PCS => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + + -- Wait for three clocks + elsif txStateCnt = 5 then + nxtTxState <= TX_ALMOST_READY; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Almost Ready State + when TX_ALMOST_READY => + intTxPmaReset <= '0'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + + -- TX Buffer Error + elsif mgtTxBuffError = '1' then + txStateCntRst <= '1'; + txPcsResetCntEn <= '1'; + + -- 16 Cycles have occured, reset PLL + if txPcsResetCnt = 15 then + nxtTxState <= TX_PMA_RESET; + txPcsResetCntRst <= '1'; + + -- Go back to PCS Reset + else + nxtTxState <= TX_PCS_RESET; + txPcsResetCntRst <= '0'; + end if; + + -- Wait for 64 clocks + elsif txStateCnt = 63 then + nxtTxState <= TX_READY; + txStateCntRst <= '1'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + end if; + + -- Ready State + when TX_READY => + txPcsResetCntRst <= '1'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '1'; + txClockReady <= '1'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + + -- Buffer error has occured + elsif mgtTxBuffError = '1' then + nxtTxState <= TX_PCS_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Just in case + when others => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '0'; + txClockReady <= '0'; + nxtTxState <= TX_SYSTEM_RESET; + end case; + end process; + + + -- Async RX State Logic + process ( curRxState, rxStateCnt, mgtRxLock, mgtRxBuffError, rxPcsResetCnt ) begin + case curRxState is + + -- System Reset State + when RX_SYSTEM_RESET => + rxPcsResetCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxStateCntRst <= '1'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxClockReady <= '0'; + nxtRxState <= RX_PMA_RESET; + + -- PMA Reset State + when RX_PMA_RESET => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '1'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Wait for three clocks + if rxStateCnt = 3 then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Wait for RX Lock + when RX_WAIT_LOCK => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= not mgtRxLock; + rxClockReady <= '0'; + + -- Wait for rx to be locked for 16K clock cycles + if rxStateCnt = "11111111111111" then + nxtRxState <= RX_PCS_RESET; + else + nxtRxState <= curRxState; + end if; + + -- Assert PCS Reset + when RX_PCS_RESET => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '1'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + + -- Wait for three clocks + elsif rxStateCnt = 3 then + nxtRxState <= RX_WAIT_PCS; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Wait 5 clocks after PCS reset + when RX_WAIT_PCS => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + + -- Wait for five clocks + elsif rxStateCnt = 5 then + nxtRxState <= RX_ALMOST_READY; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Almost Ready State + when RX_ALMOST_READY => + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + + -- RX Buffer Error + elsif mgtRxBuffError = '1' then + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '1'; + + -- 16 Cycles have occured, reset PLL + if rxPcsResetCnt = 15 then + nxtRxState <= RX_PMA_RESET; + rxPcsResetCntRst <= '1'; + + -- Go back to PCS Reset + else + nxtRxState <= RX_PCS_RESET; + rxPcsResetCntRst <= '0'; + end if; + + -- Wait for 64 clocks + elsif rxStateCnt = 63 then + nxtRxState <= RX_READY; + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + end if; + + -- Ready State + when RX_READY => + rxPcsResetCntRst <= '1'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= '1'; + rxClockReady <= '1'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + + -- Buffer error has occured + elsif mgtRxBuffError = '1' then + nxtRxState <= RX_PCS_RESET; + else + nxtRxState <= curRxState; + end if; + + -- Just in case + when others => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= '0'; + rxClockReady <= '0'; + nxtRxState <= RX_SYSTEM_RESET; + end case; + end process; + +end PgpMgtWrap; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpPhy.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpPhy.vhd new file mode 100755 index 0000000000000000000000000000000000000000..2af50f188eb426edc9723fd864739e9da1ecec28 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpPhy.vhd @@ -0,0 +1,835 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Physical Interface Module +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpPhy.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Physical interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 01/17/2006: First simulation complete. +-- 04/16/2006: Modified to support cell transmission with a blank spot for the +-- SOC charactor already included in the cell. +-- 05/30/2007: Modified link init sequence so that rx and tx are reset +-- seperately. Changed state counters for pattern detection. +-- Fixed version and link train error, extended init timeout. +-- 06/08/2007: Added counter on rx and tx lock to ensure that we only proceed +-- with init after rx and tx lock are stable. +-- 06/11/2007: Changed init sequence so that txPmaReset and rxPmaReset are not +-- longer asserted during the init sequence. These resets mess with +-- the PLL and should only be asserted at startup. It appears as if +-- the RX PLL can re-lock when the signal returns without a PMA +-- reset. Also the state machine will allow the init sequence to +-- continue to loop until a link is found. The link will only go to +-- fail if the versions mismatch. TX or RX unlock will cause the +-- link to re-start. +-- 06/13/2007: Cleanup of PMA reset control. Wait for RX lock is now much +-- longer than before per the Xilinx datasheet. +-- 06/15/2007: Removed shifting on receive data. MGT will always align comma +-- to an even byte. +-- 06/19/2007: One skip is now transmitted after a cell. The rest is junk data. +-- 06/19/2007: Removed reset of lock counters in ST_RESET state. +-- 08/24/2007: Changed clock init state machine. +-- 08/25/2007: Combined decode and disparity error +-- 04/30/2008: Added Chipscope For Debugging +-- 11/05/2008: Removed chipscope. Removed rx/tx pll and reset logic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpPhy is port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibReLink : in std_logic; -- Re-Link control signal + + -- Status signals + localVersion : in std_logic_vector(7 downto 0); -- Local version ID + remoteVersion : out std_logic_vector(7 downto 0); -- Remote version ID + pibFail : out std_logic; -- PIB fail indication + pibLinkReady : out std_logic; -- PIB link is ready + pibState : out std_logic_vector(2 downto 0); -- PIB State + + -- Cell Transmit Interface + pibTxSOC : in std_logic; -- Cell data start of cell + pibTxWidth : in std_logic; -- Cell data width + pibTxEOC : in std_logic; -- Cell data end of cell + pibTxEOF : in std_logic; -- Cell data end of frame + pibTxEOFE : in std_logic; -- Cell data end of frame error + pibTxData : in std_logic_vector(15 downto 0); -- Cell data data + + -- Cell Receive Interface + pibRxSOC : out std_logic; -- Cell data start of cell + pibRxWidth : out std_logic; -- Cell data width + pibRxEOC : out std_logic; -- Cell data end of cell + pibRxEOF : out std_logic; -- Cell data end of frame + pibRxEOFE : out std_logic; -- Cell data end of frame error + pibRxData : out std_logic_vector(15 downto 0); -- Cell data data + + -- Physical Interface Signals + phyRxPolarity : out std_logic; -- PHY receive signal polarity + phyRxData : in std_logic_vector(15 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(1 downto 0); -- PHY receive data is K character + phyTxData : out std_logic_vector(15 downto 0); -- PHY transmit data + phyTxDataK : out std_logic_vector(1 downto 0); -- PHY transmit data is K character + phyInitDone : in std_logic -- PHY init is done +); + +end PgpPhy; + + +-- Define architecture +architecture PgpPhy of PgpPhy is + + -- Local Signals + signal nxtPibFail : std_logic; + signal nxtPibLinkReady : std_logic; + signal stateCnt : std_logic_vector(15 downto 0); + signal stateCntRst : std_logic; + signal stateCntEn : std_logic; + signal pattCnt : std_logic_vector(7 downto 0); + signal pattCntRst : std_logic; + signal pattCntEn : std_logic; + signal txIdleEn : std_logic; + signal txTrainEn : std_logic; + signal txVerEn : std_logic; + signal txSkipEn : std_logic; + signal txDataEn : std_logic; + signal rxDataEn : std_logic; + signal rxDetectIdle : std_logic; + signal rxDetectTrain : std_logic; + signal rxDetectInvert : std_logic; + signal rxDetectVer : std_logic; + signal rxDetectVerErr : std_logic; + signal nxtRxPolarity : std_logic; + signal dly0RxData : std_logic_vector(15 downto 0); + signal dly0RxDataK : std_logic_vector(1 downto 0); + signal dly1RxData : std_logic_vector(15 downto 0); + signal dly1RxDataK : std_logic_vector(1 downto 0); + signal sofDetect : std_logic; + signal intPhyRxPolarity : std_logic; + signal txDlyEOC : std_logic; + signal txDlyEOF : std_logic; + signal txDlyEOFE : std_logic; + + -- Physical Link State + constant ST_LOCK : std_logic_vector(2 downto 0) := "001"; + constant ST_IDLE : std_logic_vector(2 downto 0) := "010"; + constant ST_TRAIN : std_logic_vector(2 downto 0) := "011"; + constant ST_VER : std_logic_vector(2 downto 0) := "100"; + constant ST_EN : std_logic_vector(2 downto 0) := "101"; + constant ST_SKP : std_logic_vector(2 downto 0) := "110"; + constant ST_FAIL : std_logic_vector(2 downto 0) := "111"; + signal curState : std_logic_vector(2 downto 0); + signal nxtState : std_logic_vector(2 downto 0); + + -- Debug states + signal nxtDebug : std_logic_vector(2 downto 0); + signal curDebug : std_logic_vector(2 downto 0); + + -- Constant 8-bit values for RX & Tx + constant K_COM : std_logic_vector(7 downto 0) := "10111100"; -- K28.5 + constant K_IDL : std_logic_vector(7 downto 0) := "01111100"; -- K28.3 + constant K_LTS : std_logic_vector(7 downto 0) := "00111100"; -- K28.1 + constant D_102 : std_logic_vector(7 downto 0) := "01001010"; -- D10.2 + constant D_215 : std_logic_vector(7 downto 0) := "10110101"; -- D21.5 + constant K_SKP : std_logic_vector(7 downto 0) := "00011100"; -- K28.0 + constant K_VTS : std_logic_vector(7 downto 0) := "11110111"; -- K23.7 + constant K_SOC : std_logic_vector(7 downto 0) := "11111011"; -- K27.7 + constant K_EOF : std_logic_vector(7 downto 0) := "11111101"; -- K29.7 + constant K_EOFE : std_logic_vector(7 downto 0) := "11111110"; -- K30.7 + constant K_EOC : std_logic_vector(7 downto 0) := "01011100"; -- K28.2 + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Outputs + phyRxPolarity <= intPhyRxPolarity; + + + -- State transition sync logic. + -- In state counter for timeouts + -- Rx pattern counter + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + curState <= ST_LOCK after tpd; + curDebug <= ST_LOCK after tpd; + stateCnt <= (others=>'0') after tpd; + pattCnt <= (others=>'0') after tpd; + intPhyRxPolarity <= '0' after tpd; + pibFail <= '0' after tpd; + pibLinkReady <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Status signals + pibFail <= nxtPibFail after tpd; + pibLinkReady <= nxtPibLinkReady after tpd; + + -- Re-Link detected or either of the clocks have lost lock + if pibReLink = '1' or phyInitDone = '0' then + curState <= ST_LOCK after tpd; + else + curState <= nxtState after tpd; + end if; + + -- Link inversion + intPhyRxPolarity <= nxtRxPolarity after tpd; + + -- In state counter + if stateCntRst = '1' then + stateCnt <= (others=>'0') after tpd; + elsif stateCntEn = '1' then + stateCnt <= stateCnt + 1 after tpd; + end if; + + -- Pattern receive counter + if pattCntRst = '1' then + pattCnt <= (others=>'0') after tpd; + elsif pattCntEn = '1' then + pattCnt <= pattCnt + 1 after tpd; + end if; + + -- Drive state debug output + curDebug <= nxtDebug; + end if; + end process; + + -- Output debug state + pibState <= curDebug; + + -- Link control state machine + process ( curState, stateCnt, rxDetectIdle, pattCnt, intPhyRxPolarity, rxDetectTrain, + rxDetectVer, rxDetectVerErr, rxDetectInvert, pibTxEOC, pibTxWidth, txDlyEOC, + curDebug ) begin + case curState is + + -- Wait for lock state + when ST_LOCK => + nxtPibLinkReady <= '0'; + nxtPibFail <= '0'; + pattCntRst <= '1'; + pattCntEn <= '0'; + stateCntRst <= '1'; + stateCntEn <= '0'; + txIdleEn <= '0'; + txTrainEn <= '0'; + txVerEn <= '0'; + txSkipEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtRxPolarity <= '0'; + nxtDebug <= ST_LOCK; + nxtState <= ST_IDLE; + + -- Transmit IDLE + when ST_IDLE => + + -- Idle is transmitting + nxtPibLinkReady <= '0'; + nxtPibFail <= '0'; + txTrainEn <= '0'; + txVerEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtRxPolarity <= '0'; + nxtDebug <= ST_IDLE; + + -- Transmit IDLE normally, + -- add two skip patterns every 512 clocks + if stateCnt(8 downto 2) = 0 then + txIdleEn <= '0'; + txSkipEn <= '1'; + else + txIdleEn <= '1'; + txSkipEn <= '0'; + end if; + + -- Free run state counter + stateCntEn <= '1'; + + -- Pattern counter counts IDLE sequence reception + -- Stop counting once we receive enough patterns + pattCntEn <= rxDetectIdle and not pattCnt(7); + + -- Move to next state when 128 IDLE sequences detected and we have + -- been in the state long enough to transmit 256 IDLE sequences (512 clocks) + if pattCnt(7) = '1' and stateCnt > 511 then + stateCntRst <= '1'; + pattCntRst <= '1'; + nxtState <= ST_TRAIN; + + -- Check for timeout while waiting for IDLE + elsif stateCnt = x"FFFF" then + stateCntRst <= '1'; + pattCntRst <= '1'; + nxtState <= ST_LOCK; + + -- Keep counting + else + stateCntRst <= '0'; + pattCntRst <= '0'; + nxtState <= curState; + end if; + + -- Transmit training sequence + when ST_TRAIN => + + -- Training sequence is transmitting + nxtPibLinkReady <= '0'; + nxtPibFail <= '0'; + txIdleEn <= '0'; + txVerEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtDebug <= ST_TRAIN; + + -- Transmit training normally, + -- add two skip patterns every 512 clocks + if stateCnt(8 downto 2) = 0 then + txTrainEn <= '0'; + txSkipEn <= '1'; + else + txTrainEn <= '1'; + txSkipEn <= '0'; + end if; + + -- Free run state counter + stateCntEn <= '1'; + + -- Detect link inversion, allow single polarity flip due to latency + -- in the rocket IO data path. + if rxDetectTrain = '1' and rxDetectInvert = '1' and intPhyRxPolarity = '0' then + nxtRxPolarity <= '1'; + else + nxtRxPolarity <= intPhyRxPolarity; + end if; + + -- Pattern counter counts training sequence reception + -- Stop counting once we receive enough patterns + pattCntEn <= rxDetectTrain and (not rxDetectInvert) and (not pattCnt(7)); + + -- Move to next state when 128 training sequences detected and we have + -- been in the state long enough to transmit 256 training sequences (512 clocks) + if pattCnt(7) = '1' and stateCnt > 511 then + stateCntRst <= '1'; + pattCntRst <= '1'; + nxtState <= ST_VER; + + -- Check for timeout while waiting for training sequences + elsif stateCnt = x"FFFF" then + stateCntRst <= '1'; + pattCntRst <= '1'; + nxtState <= ST_LOCK; + + -- Keep counting + else + stateCntRst <= '0'; + pattCntRst <= '0'; + nxtState <= curState; + end if; + + -- Transmit Version sequence + when ST_VER => + + -- Version is transmitting + nxtPibLinkReady <= '0'; + nxtPibFail <= '0'; + txIdleEn <= '0'; + txTrainEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtDebug <= ST_VER; + + -- Transmit version normally, + -- add two skip patterns every 512 clocks + if stateCnt(8 downto 2) = 0 then + txVerEn <= '0'; + txSkipEn <= '1'; + else + txVerEn <= '1'; + txSkipEn <= '0'; + end if; + + -- Free run state counter + stateCntEn <= '1'; + nxtRxPolarity <= intPhyRxPolarity; + + -- Pattern counter counts version sequence reception + -- Stop counting once we receive enough patterns + pattCntEn <= rxDetectVer and not pattCnt(2); + + -- Move to next state when 4 version sequences detected and we have + -- been in the state long enough to transmit 8 version sequences (16 clocks) + if pattCnt(2) = '1' and stateCnt > 15 then + + -- Reset counters for next state + stateCntRst <= '1'; + pattCntRst <= '1'; + + -- Detect version mismatch + if rxDetectVerErr = '1' and rxDetectVer = '1' then + nxtState <= ST_FAIL; + else + nxtState <= ST_EN; + end if; + + -- Check for timeout while waiting for version sequences + elsif stateCnt = x"FFFF" then + stateCntRst <= '1'; + pattCntRst <= '1'; + nxtState <= ST_LOCK; + + -- Keep counting + else + stateCntRst <= '0'; + pattCntRst <= '0'; + nxtState <= curState; + end if; + + -- Normal operation + when ST_EN => + + -- Normal data is transmitting + nxtPibLinkReady <= '1'; + nxtPibFail <= '0'; + txIdleEn <= '0'; + txTrainEn <= '0'; + txVerEn <= '0'; + txSkipEn <= '0'; + txDataEn <= '1'; + rxDataEn <= '1'; + nxtRxPolarity <= intPhyRxPolarity; + nxtDebug <= ST_EN; + + -- Pattern count is not used + pattCntEn <= '0'; + pattCntRst <= '1'; + + -- State Counter Is In Reset + stateCntEn <= '0'; + stateCntRst <= '1'; + + -- IDLE is detected + if rxDetectIdle = '1' then + nxtState <= ST_LOCK; + + -- We just transmitted a CELL, transmit Skip immediatly following + elsif (pibTxEOC = '1' and pibTxWidth = '0') or txDlyEOC = '1' then + nxtState <= ST_SKP; + + -- Stay in enable mode + else + nxtState <= curState; + end if; + + -- Transmit SKP sequence + when ST_SKP => + + -- SKP data is transmitting + nxtPibLinkReady <= '1'; + nxtPibFail <= '0'; + txIdleEn <= '0'; + txTrainEn <= '0'; + txVerEn <= '0'; + txSkipEn <= '1'; + txDataEn <= '0'; + rxDataEn <= '1'; + nxtRxPolarity <= intPhyRxPolarity; + nxtDebug <= ST_SKP; + + -- Reset pattern count + pattCntEn <= '0'; + pattCntRst <= '1'; + + -- We are done when we have transmitted 1 SKIP sequence (2 clocks). + if stateCnt(0) = '1' then + nxtstate <= ST_EN; + stateCntEn <= '0'; + stateCntRst <= '1'; + else + nxtstate <= curState; + stateCntEn <= '1'; + stateCntRst <= '0'; + end if; + + -- Link init failed + when ST_FAIL => + + -- IDLE is transmitting + nxtPibLinkReady <= '0'; + nxtPibFail <= '1'; + txIdleEn <= '1'; + txTrainEn <= '0'; + txVerEn <= '0'; + txSkipEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtRxPolarity <= '0'; + pattCntEn <= '0'; + stateCntEn <= '1'; + stateCntRst <= '0'; + pattCntRst <= '1'; + nxtState <= curState; + nxtDebug <= curDebug; + + -- Default state + when others => + nxtPibLinkReady <= '0'; + nxtPibFail <= '0'; + txIdleEn <= '0'; + txTrainEn <= '0'; + txVerEn <= '0'; + txSkipEn <= '0'; + txDataEn <= '0'; + rxDataEn <= '0'; + nxtRxPolarity <= '0'; + pattCntEn <= '0'; + stateCntEn <= '0'; + stateCntRst <= '0'; + pattCntRst <= '0'; + nxtState <= ST_LOCK; + nxtDebug <= ST_LOCK; + end case; + end process; + + + -- Receive data from external Serdes + -- Re-Align and detect ordered set + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + dly0RxData <= (others=>'0') after tpd; + dly0RxDataK <= (others=>'0') after tpd; + dly1RxData <= (others=>'0') after tpd; + dly1RxDataK <= (others=>'0') after tpd; + rxDetectIdle <= '0' after tpd; + rxDetectTrain <= '0' after tpd; + rxDetectInvert <= '0' after tpd; + rxDetectVer <= '0' after tpd; + rxDetectVerErr <= '0' after tpd; + remoteVersion <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- First and second stages take data right from IO pads + dly0RxData <= phyRxData after tpd; + dly0RxDataK <= phyRxDataK after tpd; + dly1RxData <= dly0RxData after tpd; + dly1RxDataK <= dly0RxDataK after tpd; + + -- Detect IDLE sequence + if dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_COM and + dly0RxDataK(1) = '1' and dly0RxData(15 downto 8) = K_IDL and + dly1RxDataK(0) = '1' and dly1RxData(7 downto 0) = K_IDL and + dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_IDL then + rxDetectIdle <= '1' after tpd; + else + rxDetectIdle <= '0' after tpd; + end if; + + -- Detect training sequence + if dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_COM and + dly0RxDataK(1) = '1' and dly0RxData(15 downto 8) = K_LTS and + dly1RxDataK(0) = '0' and + dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_LTS then + + -- Non-Inverted training data + if dly1RxData(7 downto 0) = D_102 then + rxDetectTrain <= '1' after tpd; + rxDetectInvert <= '0' after tpd; + + -- Inverted training data + elsif dly1RxData(7 downto 0) = D_215 then + rxDetectTrain <= '1' after tpd; + rxDetectInvert <= '1' after tpd; + + -- Bad data + else + rxDetectTrain <= '0' after tpd; + rxDetectInvert <= '0' after tpd; + end if; + else + rxDetectTrain <= '0' after tpd; + rxDetectInvert <= '0' after tpd; + end if; + + -- Detect Version Sequence + if dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_COM and + dly0RxDataK(1) = '1' and dly0RxData(15 downto 8) = K_VTS and + dly1RxDataK(0) = '0' and + dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_VTS then + + -- Version sequence detected + rxDetectVer <= '1' after tpd; + + -- Only store remote version when we are transmitting version + if txVerEn = '0' then + remoteVersion <= dly1RxData(7 downto 0) after tpd; + end if; + + -- Version matches + if dly1RxData(7 downto 0) = localVersion then + rxDetectVerErr <= '0' after tpd; + + -- Version mismatch + else + rxDetectVerErr <= '1' after tpd; + end if; + else + rxDetectVer <= '0' after tpd; + end if; + end if; + end process; + + + -- Receive data from external Serdes + -- Re-Align and detect SOC,EOF,EOC,EOFE + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + pibRxSOC <= '0' after tpd; + pibRxWidth <= '0' after tpd; + pibRxEOC <= '0' after tpd; + pibRxEOF <= '0' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxData <= (others=>'0') after tpd; + sofDetect <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Receiver is enabled + if rxDataEn = '1' then + + -- Detect SOC + if dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_SOC then + sofDetect <= '1' after tpd; + else + sofDetect <= '0' after tpd; + end if; + + -- Store data to outgoing pads + pibRxData(15 downto 8) <= dly1RxData(15 downto 8) after tpd; + pibRxData(7 downto 0) <= dly1RxData(7 downto 0) after tpd; + + -- SOC Flags + pibRxSOC <= sofDetect after tpd; + + -- Detect EOF flag, low byte + if (dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_EOF ) then + pibRxEOF <= '1' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '1' after tpd; + + -- Detect EOF flag, high byte + elsif (dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_EOF ) then + pibRxEOF <= '1' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '0' after tpd; + + -- Detect EOFE flag, low byte + elsif (dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_EOFE ) then + pibRxEOF <= '1' after tpd; + pibRxEOFE <= '1' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '1' after tpd; + + -- Detect EOFE flag, high byte + elsif (dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_EOFE ) then + pibRxEOF <= '1' after tpd; + pibRxEOFE <= '1' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '0' after tpd; + + -- Detect EOC flag, low byte + elsif (dly0RxDataK(0) = '1' and dly0RxData(7 downto 0) = K_EOC ) then + pibRxEOF <= '0' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '1' after tpd; + + -- Detect EOC flag, high byte + elsif (dly1RxDataK(1) = '1' and dly1RxData(15 downto 8) = K_EOC ) then + pibRxEOF <= '0' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxEOC <= '1' after tpd; + pibRxWidth <= '0' after tpd; + + -- Normal data + else + pibRxEOF <= '0' after tpd; + pibRxEOFE <= '0' after tpd; + pibRxEOC <= '0' after tpd; + pibRxWidth <= '1' after tpd; + end if; + end if; + end if; + end process; + + + -- Transmit data to external serdes. Data frame cell tx logic will + -- contain data with the first byte in bits 7-0. An SOC charactor + -- must be added to the front of the frame. An EOF charactor will be + -- added to the end. + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + phyTxData <= (others=>'0') after tpd; + phyTxDataK <= (others=>'0') after tpd; + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + elsif rising_edge(pgpClk) then + + -- Transmit IDLE + if txIdleEn = '1' then + if stateCnt(0) = '0' then + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_COM after tpd; + phyTxData(15 downto 8) <= K_IDL after tpd; + else + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_IDL after tpd; + phyTxData(15 downto 8) <= K_IDL after tpd; + end if; + + -- Unused signals + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Transmit training sequence + elsif txTrainEn = '1' then + if stateCnt(0) = '0' then + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_COM after tpd; + phyTxData(15 downto 8) <= K_LTS after tpd; + else + phyTxDataK <= "10" after tpd; + phyTxData(7 downto 0) <= D_102 after tpd; + phyTxData(15 downto 8) <= K_LTS after tpd; + end if; + + -- Unused signals + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Transmit local version + elsif txVerEn = '1' then + if stateCnt(0) = '0' then + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_COM after tpd; + phyTxData(15 downto 8) <= K_VTS after tpd; + else + phyTxDataK <= "10" after tpd; + phyTxData(7 downto 0) <= localVersion after tpd; + phyTxData(15 downto 8) <= K_VTS after tpd; + end if; + + -- Unused signals + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Transmit skip sequence + elsif txSkipEn = '1' then + if stateCnt(0) = '0' then + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_COM after tpd; + phyTxData(15 downto 8) <= K_SKP after tpd; + else + phyTxDataK <= "11" after tpd; + phyTxData(7 downto 0) <= K_SKP after tpd; + phyTxData(15 downto 8) <= K_SKP after tpd; + end if; + + -- Unused signals + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Transmitter is enabled + elsif txDataEn = '1' then + + -- SOC Generation + if pibTxSOC = '1' then + phyTxData(15 downto 8) <= pibTxData(15 downto 8) after tpd; + phyTxData(7 downto 0) <= K_SOC after tpd; + phyTxDataK <= "01" after tpd; + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- End of cell requested + elsif pibTxEOC = '1' then + + -- Width = '0', overwrite upper byte with EOF, we are done + if pibTxWidth = '0' then + phyTxData(7 downto 0) <= pibTxData(7 downto 0) after tpd; + phyTxDataK <= "10" after tpd; + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Which EOC charactor to send + if pibTxEOFE = '1' then + phyTxData(15 downto 8) <= K_EOFE after tpd; + elsif pibTxEOF = '1' then + phyTxData(15 downto 8) <= K_EOF after tpd; + else + phyTxData(15 downto 8) <= K_EOC after tpd; + end if; + + -- Width = '1', need to add an extra byte + else + phyTxData <= pibTxData after tpd; + phyTxDataK <= "00" after tpd; + txDlyEOC <= '1' after tpd; + txDlyEOF <= pibTxEOF after tpd; + txDlyEOFE <= pibTxEOFE after tpd; + end if; + + -- Delayed EOC + elsif txDlyEOC = '1' then + + -- Pass unused through + phyTxData(15 downto 8) <= pibTxData(15 downto 8) after tpd; + phyTxDataK <= "01" after tpd; + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + + -- Which EOC charactor to send + if txDlyEOFE = '1' then + phyTxData(7 downto 0) <= K_EOFE after tpd; + elsif txDlyEOF = '1' then + phyTxData(7 downto 0) <= K_EOF after tpd; + else + phyTxData(7 downto 0) <= K_EOC after tpd; + end if; + + -- Normal data + else + phyTxData <= pibTxData after tpd; + phyTxDataK <= "00" after tpd; + txDlyEOC <= '0' after tpd; + txDlyEOF <= '0' after tpd; + txDlyEOFE <= '0' after tpd; + end if; + end if; + end if; + end process; + +end PgpPhy; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpPicRemBuff.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpPicRemBuff.vhd new file mode 100755 index 0000000000000000000000000000000000000000..a106eee6b1f24a336f886f6d5e71ea14a3dffd6c --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpPicRemBuff.vhd @@ -0,0 +1,252 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Remote Buffer For PIC +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : PgpPicRemBuff.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/09/2007 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for block on the remote end of the PGP link which feeds +-- the PGP with frame data that will be receoved by the PIC Import block. +-- The PIC Import block does not support short cells. This logic will ensure +-- that only full cells are transfered over the PGP link. +-- This block is fed from a fifo which is filled by the user logic. +-- Flow control +-- When the PIC asserts FULL data transfer will stop immediatly. When almost +-- full is asserted the current cell will be complete the the interface will +-- pause at the next boundary. +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/09/2007: created. +-- 11/16/2007: Fixed corner case where flow control asserts just as pre-read +-- data is read from the fifo. +-- 11/27/2007: Moved CID generator into chipscope block for size reasons. +-- 11/29/2007: Changed cell boundary detection to improve timing. +-- 12/11/2007: Removed chipscope; +-- 03/06/2008: Removed 8-bit support. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpPicRemBuff is port ( + + -- Clock and reset + pgpClk : in std_logic; -- 125Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- Interface To PGP + vcFrameTxValid : out std_logic; -- User frame data is valid + vcFrameTxReady : in std_logic; -- PGP is ready + vcFrameTxSOF : out std_logic; -- User frame data start of frame + vcFrameTxWidth : out std_logic; -- User frame data width + vcFrameTxEOF : out std_logic; -- User frame data end of frame + vcFrameTxEOFE : out std_logic; -- User frame data error + vcFrameTxData : out std_logic_vector(15 downto 0); -- User frame data + vcFrameTxCid : out std_logic_vector(31 downto 0); -- User frame data, context ID + vcFrameTxAckCid : in std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vcFrameTxAckEn : in std_logic; -- PGP ACK/NACK enable + vcFrameTxAck : in std_logic; -- PGP ACK/NACK + vcRemBuffAFull : in std_logic; -- Remote buffer almost full + vcRemBuffFull : in std_logic; -- Remote buffer full + + -- Interface to feeding FIFO + txFifoRd : out std_logic; -- TX Fifo Read Strobe + txFifoEmpty : in std_logic; -- TX Fifo Empty + txFifoData : in std_logic_vector(15 downto 0); -- TX Data + txFifoSOF : in std_logic; -- TX Fifo Start Of Frame + txFifoEOF : in std_logic; -- TX Fifo End Of Frame + txFifoEOFE : in std_logic -- TX Fifo End Of Frame, Error + ); +end PgpPicRemBuff; + + +-- Define architecture +architecture PgpPicRemBuff of PgpPicRemBuff is + + -- Output Fifo + component pgp_fifo_21x512 port ( + clk: IN std_logic; + din: IN std_logic_VECTOR(20 downto 0); + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + data_count: OUT std_logic_VECTOR(8 downto 0); + dout: OUT std_logic_VECTOR(20 downto 0); + empty: OUT std_logic; + full: OUT std_logic); + end component; + + -- Local Signals + signal intFifoRdDly : std_logic; + signal syncWr : std_logic; + signal syncDin : std_logic_vector(20 downto 0); + signal wrCount : std_logic_vector(7 downto 0); + signal syncRdDly : std_logic; + signal cellCount : std_logic_vector(2 downto 0); + signal syncValid : std_logic; + signal syncDout : std_logic_vector(20 downto 0); + signal syncRd : std_logic; + signal syncEmpty : std_logic; + signal syncCount : std_logic_vector(8 downto 0); + signal intFifoRd : std_logic; + signal intCid : std_logic_vector(31 downto 0); + signal syncAFull : std_logic; + signal syncSOC : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_fifo_21x512 : component is TRUE; + attribute syn_noprune of pgp_fifo_21x512 : component is TRUE; + +begin + + -- Pass read to FIFO + txFifoRd <= intFifoRd; + + -- Read when FIFO has data and sync FIFO has room + intFifoRd <= (not txFifoEmpty) and (not syncAFull); + + -- Track data movement + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intFifoRdDly <= '0' after tpd; + syncWr <= '0' after tpd; + syncDin(19 downto 0) <= (others=>'0') after tpd; + wrCount <= (others=>'0') after tpd; + syncRdDly <= '0' after tpd; + cellCount <= "000" after tpd; + syncValid <= '0' after tpd; + syncSOC <= '0' after tpd; + syncAFull <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Generate sync fifo almost full signal + if syncCount > 500 or cellCount(2) = '1' then + syncAFull <= '1' after tpd; + else + syncAFull <= '0' after tpd; + end if; + + -- Delayed copy of fifo read + intFifoRdDly <= intFifoRd after tpd; + + -- Add pipeline stage to write data for timing + syncWr <= intFifoRdDly after tpd; + syncDin(19) <= txFifoEOFE after tpd; + syncDin(18) <= txFifoEOF after tpd; + syncDin(17) <= '1' after tpd; + syncDin(16) <= txFifoSOF after tpd; + syncDin(15 downto 0) <= txFifoData after tpd; + + -- Cell Write Counter + if syncDin(18) = '1' then + wrCount <= (others=>'0') after tpd; + elsif syncWr = '1' then + wrCount <= wrCount + 1 after tpd; + end if; + + -- Delayed copy of sync FIFO reads + syncRdDly <= syncRd after tpd; + + -- Track number of cells in the sync fifo + -- Read cell marker, no write + if syncRdDly = '1' and syncDout(20) = '1' and + (syncWr = '0' or syncDin(20) = '0') then + cellCount <= cellCount - 1 after tpd; + + -- Write cell marker, no read + elsif syncWr = '1' and syncDin(20) = '1' and + (syncRdDly = '0' or syncDout(20) = '0') then + cellCount <= cellCount + 1 after tpd; + + -- FIFO is empty + elsif syncEmpty = '1' then + cellCount <= "000" after tpd; + end if; + + -- De-assert valid when PGP accepts and no read occurs + if vcFrameTxReady = '1' and syncRd = '0' then + syncValid <= '0' after tpd; + syncSOC <= '0' after tpd; + + -- Read is occuring with or without ready + elsif syncRd = '1' then + + -- Last value was EOC or no cells in FIFO, De-Assert valid for at least one cycle + -- Mark current output as start of cell + if syncDout(20) = '1' or cellCount = 0 then + syncValid <= '0' after tpd; + syncSOC <= '1' after tpd; + else + syncValid <= '1' after tpd; + syncSOC <= '0' after tpd; + end if; + + -- SOC is on FIFO output, assert valid only when at least one cell is + -- present in the FIFO and remote buffers are ready + elsif syncSOC = '1' then + if cellCount /= 0 and syncEmpty = '0' and vcRemBuffAFull = '0' + and vcRemBuffFull = '0' then + syncValid <= '1' after tpd; + end if; + end if; + end if; + end process; + + + -- Set end of cell flag + syncDin(20) <= '1' when syncDin(18) = '1' or wrCount = 255 else '0'; + + + -- Control reads from FIFO + process (vcRemBuffFull, vcFrameTxReady, syncValid, syncSOC, syncEmpty ) begin + + -- Data is moving + if vcFrameTxReady = '1' and syncValid = '1' then + syncRd <= (not syncEmpty) and (not vcRemBuffFull); + + -- Pre-read required + elsif syncValid = '0' and syncSOC = '0' then + syncRd <= (not syncEmpty) and (not vcRemBuffFull); + + -- No Read + else + syncRd <= '0'; + end if; + end process; + + + -- Sync FIFO + U_SyncFifo: pgp_fifo_21x512 port map ( + clk => pgpClk, + din => syncDin, + rd_en => syncRd, + rst => pgpReset, + wr_en => syncWr, + data_count => syncCount, + dout => syncDout, + empty => syncEmpty, + full => open + ); + + -- Outgoing data + vcFrameTxValid <= syncValid; + vcFrameTxEOFE <= syncDout(19); + vcFrameTxEOF <= syncDout(18); + vcFrameTxWidth <= '1'; + vcFrameTxSOF <= syncDout(16); + vcFrameTxData <= syncDout(15 downto 0); + vcFrameTxCid <= (others=>'0'); + +end PgpPicRemBuff; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpRegSlave.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpRegSlave.vhd new file mode 100755 index 0000000000000000000000000000000000000000..e3d7db33f2f49dbae33dae6434a2bf4fedf37e03 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpRegSlave.vhd @@ -0,0 +1,803 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Register Slave Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpRegSlave.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/22/2007 +------------------------------------------------------------------------------- +-- Description: +-- Slave block for Register protocol over the PGP. +-- Packet is 16 bytes. The 16 bit values passed over the PGP will be: +-- Word 0 Data[1:0] = VC +-- Word 0 Data[7:2] = Dest_ID +-- Word 0 Data[15:8] = TID[7:0] +-- Word 1 Data[15:0] = TID[23:8] +-- Word 2 Data[15:0] = Address[15:0] +-- Word 3 Data[15:14] = OpCode, 0x0=Read, 0x1=Write, 0x2=Set, 0x3=Clear +-- Word 3 Data[13:8] = Don't Care +-- Word 3 Data[7:0] = Address[23:16] +-- Word 4 Data[15:0] = WriteData[15:0] +-- Word 5 Data[15:0] = WriteData[31:16] +-- Word 6 = Don't Care +-- Word 7 Data[15:2] = Don't Care +-- Word 7 Data[1] = Timeout Flag (response data) +-- Word 7 Data[0] = Fail Flag (response data) +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/22/2007: created. +-- 10/10/2007: Added 32-bit CID value to frame. +-- 10/29/2007: Changed name of coregen blocks +-- 11/06/2007: Changed flow control reaction to ensure their are no short cells. +-- 11/06/2007: Added wait for ACK and re-transmission on NACK reception. +-- 11/07/2007: Changed reaction to full flag due to change in pic interface. +-- 11/20/2007: Added check to ensure overflow will put EOFE into buffer. +-- 11/27/2007: Modified to allow the option of sync or async FIFOs +-- Removed re-transmission of nack reception. +-- 11/30/2007: Fixed error with back to back frames and mis-connected data lines. +-- Made frame size 20bytes for received data. Testing Only. +-- 11/30/2007: Removed FIFO in TX direction. +-- 12/12/2007: Added wait for ack de-assertion for set and clear commands. +-- Previous version would see ack from pervious command due to +-- pipeline of register data. +-- 12/14/2007: Adjusted frame length back to 16 bytes. +-- 01/25/2008: Adjusted for new frame format. +-- 02/08/2008: More frame format changes. Added in progress flag. +-- 02/05/2008: Changed timeout to 12-bits. +-- 07/22/2008: Changed timeout to 16-bits. +-- 01/14/2009: Changed timeout to 24-bits. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpRegSlave is + generic ( + AsyncFIFO : string := "TRUE" -- Use Async FIFOs, TRUE or FALSE + ); + port ( + + -- PGP Clock And Reset + pgpClk : in std_logic; -- PGP Clock + pgpReset : in std_logic; -- Synchronous PGP Reset + + -- Local clock and reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + + -- PGP Receive Signals + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxWidth : in std_logic; -- Data is 16-bits + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + + -- PGP Transmit Signals + vcFrameTxValid : out std_logic; -- User frame data is valid + vcFrameTxReady : in std_logic; -- PGP is ready + vcFrameTxSOF : out std_logic; -- User frame data start of frame + vcFrameTxWidth : out std_logic; -- User frame data width + vcFrameTxEOF : out std_logic; -- User frame data end of frame + vcFrameTxEOFE : out std_logic; -- User frame data error + vcFrameTxData : out std_logic_vector(15 downto 0); -- User frame data + vcFrameTxCid : out std_logic_vector(31 downto 0); -- User frame data, context ID + vcFrameTxAckCid : in std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vcFrameTxAckEn : in std_logic; -- PGP ACK/NACK enable + vcFrameTxAck : in std_logic; -- PGP ACK/NACK + vcRemBuffAFull : in std_logic; -- Remote buffer almost full + vcRemBuffFull : in std_logic; -- Remote buffer full + + -- Local register control signals + regInp : out std_logic; -- Register Access In Progress Flag + regReq : out std_logic; -- Register Access Request + regOp : out std_logic; -- Register OpCode, 0=Read, 1=Write + regAck : in std_logic; -- Register Access Acknowledge + regFail : in std_logic; -- Register Access Fail + regAddr : out std_logic_vector(23 downto 0); -- Register Address + regDataOut : out std_logic_vector(31 downto 0); -- Register Data Out + regDataIn : in std_logic_vector(31 downto 0) -- Register Data In + ); + +end PgpRegSlave; + + +-- Define architecture +architecture PgpRegSlave of PgpRegSlave is + + -- Async FIFO + component pgp_afifo_20x511 port ( + din: IN std_logic_VECTOR(19 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Sync FIFO + component pgp_fifo_20x512 port ( + din: IN std_logic_VECTOR(19 downto 0); + clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Local Signals + signal rxFifoDin : std_logic_vector(19 downto 0); + signal rxFifoDout : std_logic_vector(19 downto 0); + signal rxFifoRd : std_logic; + signal rxFifoRdDly : std_logic; + signal rxFifoCount : std_logic_vector(8 downto 0); + signal rxFifoEmpty : std_logic; + signal locRxSOF : std_logic; + signal locRxWidth : std_logic; + signal locRxEOF : std_logic; + signal locRxEOFE : std_logic; + signal locRxData : std_logic_vector(15 downto 0); + signal intRxCnt : std_logic_vector(2 downto 0); + signal intRxCntEn : std_logic; + signal intOpCode : std_logic_vector(1 downto 0); + signal intVc : std_logic_vector(1 downto 0); + signal intDest : std_logic_vector(5 downto 0); + signal intAddress : std_logic_vector(23 downto 0); + signal intTid : std_logic_vector(23 downto 0); + signal intWrData : std_logic_vector(31 downto 0); + signal rxFifoRdEn : std_logic; + signal intRegStart : std_logic; + signal intInp : std_logic; + signal intReq : std_logic; + signal intOp : std_logic; + signal intData : std_logic_vector(31 downto 0); + signal intReqCnt : std_logic_vector(23 downto 0); + signal intFail : std_logic; + signal intTout : std_logic; + signal respCnt : std_logic_vector(2 downto 0); + signal nxtInp : std_logic; + signal nxtReq : std_logic; + signal nxtOp : std_logic; + signal nxtdata : std_logic_vector(31 downto 0); + signal nxtFail : std_logic; + signal nxtTout : std_logic; + signal fifoErr : std_logic; + signal fifoFull : std_logic; + signal respReq : std_logic; + signal respReqDly : std_logic_vector(1 downto 0); + signal respAck : std_logic; + signal respAckDly : std_logic_vector(1 downto 0); + signal respValid : std_logic; + + -- Register access states + signal curState : std_logic_vector(2 downto 0); + signal nxtState : std_logic_vector(2 downto 0); + constant ST_IDLE : std_logic_vector(2 downto 0) := "001"; + constant ST_WRITE : std_logic_vector(2 downto 0) := "010"; + constant ST_READ : std_logic_vector(2 downto 0) := "011"; + constant ST_SET : std_logic_vector(2 downto 0) := "100"; + constant ST_CLEAR : std_logic_vector(2 downto 0) := "101"; + constant ST_RESP : std_logic_vector(2 downto 0) := "110"; + constant ST_DONE : std_logic_vector(2 downto 0) := "111"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_afifo_20x511 : component is TRUE; + attribute syn_noprune of pgp_afifo_20x511 : component is TRUE; + attribute syn_black_box of pgp_fifo_20x512 : component is TRUE; + attribute syn_noprune of pgp_fifo_20x512 : component is TRUE; + +begin + + -- Data going into Rx FIFO + rxFifoDin(19) <= vcFrameRxSOF; + rxFifoDin(18) <= vcFrameRxWidth; + rxFifoDin(17) <= vcFrameRxEOF or fifoErr; + rxFifoDin(16) <= vcFrameRxEOFE or fifoErr; + rxFifoDin(15 downto 0) <= vcFrameRxData; + + -- Async Receive FIFO + U_GenRxAFifo: if AsyncFIFO = "TRUE" generate + U_RegRxAFifo: pgp_afifo_20x511 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => fifoFull, + wr_data_count => rxFifoCount + ); + end generate; + + -- Sync Receive FIFO + U_GenRxFifo: if AsyncFIFO = "FALSE" generate + U_RegRxFifo: pgp_fifo_20x512 port map ( + din => rxFifoDin, + clk => pgpClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => fifoFull, + data_count => rxFifoCount + ); + end generate; + + -- Data coming out of Rx FIFO + locRxSOF <= rxFifoDout(19); + locRxWidth <= rxFifoDout(18); + locRxEOF <= rxFifoDout(17); + locRxEOFE <= rxFifoDout(16); + locRxData <= rxFifoDout(15 downto 0); + + -- Generate fifo read, Don't read after EOF is just read + rxFifoRd <= (not rxFifoEmpty) and rxFifoRdEn and ((not rxFifoRdDly) or (not locRxEOF)); + + -- Generate flow control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + fifoErr <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Generate full error + if rxFifoCount >= 508 or fifoFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at half capacity + vcLocBuffAFull <= rxFifoCount(8); + + -- Full at 3/4 capacity + vcLocBuffFull <= rxFifoCount(8) and rxFifoCount(7); + end if; + end process; + + + -- Receive Data Processor + process ( locClk, locReset ) begin + if locReset = '1' then + intOpCode <= "00" after tpd; + intAddress <= (others=>'0') after tpd; + intWrData <= (others=>'0') after tpd; + intRegStart <= '0' after tpd; + intTid <= (others=>'0') after tpd; + rxFifoRdDly <= '0' after tpd; + intRxCnt <= (others=>'0') after tpd; + intRxCntEn <= '0' after tpd; + intDest <= (others=>'0') after tpd; + intVc <= (others=>'0') after tpd; + elsif rising_edge(locClk) then + + -- Generate delayed read + rxFifoRdDly <= rxFifoRd after tpd; + + -- Only process when data has been read + if rxFifoRdDly = '1' then + + -- Receive Data Counter + -- Reset on SOF or EOF, Start counter on SOF + if locRxSOF = '1' or locRxEOF = '1' then + intRxCnt <= (others=>'0') after tpd; + intRxCntEn <= not locRxEOF after tpd; + elsif intRxCntEn = '1' and intRxCnt /= "111" then + intRxCnt <= intRxCnt + 1 after tpd; + end if; + + -- SOF Received + if locRxSOF = '1' then + intTid(7 downto 0) <= locRxData(15 downto 8) after tpd; + intDest <= locRxData(7 downto 2) after tpd; + intVc <= locRxData(1 downto 0) after tpd; + intRegStart <= '0' after tpd; + + -- Rest of Frame + else case intRxCnt is + + -- Word 1 + when "000" => + intTid(23 downto 8) <= locRxData after tpd; + intRegStart <= '0' after tpd; + + -- Word 2 + when "001" => + intAddress(15 downto 0) <= locRxData after tpd; + intRegStart <= '0' after tpd; + + -- Word 3 + when "010" => + intOpCode <= locRxData(15 downto 14) after tpd; + intAddress(23 downto 16) <= locRxData(7 downto 0) after tpd; + intRegStart <= '0' after tpd; + + -- Word 4 + when "011" => + intWrData(15 downto 0) <= locRxData after tpd; + intRegStart <= '0' after tpd; + + -- Word 5 + when "100" => + intWrData(31 downto 16) <= locRxData after tpd; + intRegStart <= '0' after tpd; + + -- Word 7, Last word + when "110" => + + -- No error and internal flags match + if locRxEOF = '1' and locRxEOFE = '0' and locRxWidth = '1' then + intRegStart <= '1' after tpd; + else + intRegStart <= '0' after tpd; + end if; + + -- Do nothing for others + when others => + intRegStart <= '0' after tpd; + end case; + end if; + else + intRegStart <= '0' after tpd; + end if; + end if; + end process; + + + -- Drive address bus + regAddr <= intAddress; + regDataOut <= intData; + regInp <= intInp; + regReq <= intReq; + regOp <= intOp; + + + -- Register State Machine, Sync Logic + process ( locClk, locReset ) begin + if locReset = '1' then + intInp <= '0' after tpd; + intReq <= '0' after tpd; + intOp <= '0' after tpd; + intData <= (others=>'0') after tpd; + intReqCnt <= (others=>'0') after tpd; + intFail <= '0' after tpd; + intTout <= '0' after tpd; + respAckDly <= (others=>'0') after tpd; + curState <= ST_IDLE after tpd; + elsif rising_edge(locClk) then + + -- Sync Response Ack Lines + respAckDly(0) <= respAck; + respAckDly(1) <= respAckDly(0); + + -- State transition + curState <= nxtState after tpd; + + -- Opcode and write data + intInp <= nxtInp after tpd; + intReq <= nxtReq after tpd; + intOp <= nxtOp after tpd; + + -- Data Storage + intData <= nxtData after tpd; + + -- Timeout & fail flags + intFail <= nxtFail after tpd; + intTout <= nxtTout after tpd; + + -- Timeout counter + if intReq <= '0' then + intReqCnt <= (others=>'0') after tpd; + elsif intReqCnt /= x"FFFFFF" then + intReqCnt <= intReqCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Register state engine + process ( curState, intWrData, intRegStart, intOpCode, intData, + regAck, regFail, regDataIn, intReqCnt, intFail, intTout, respAckDly ) begin + + -- States + case curState is + + -- IDLE, Wait for enable from read logic + when ST_IDLE => + + -- No Response Request + respReq <= '0'; + + -- No timeout or fail + nxtFail <= '0'; + nxtTout <= '0'; + + -- No external commands + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Register data + nxtdata <= intWrData; + + -- Start + if intRegStart = '1' then + + -- Write Command + if intOpCode = "01" then + nxtState <= ST_WRITE; + + -- Read, Set Bit, Clear Bit + else + nxtState <= ST_READ; + end if; + rxFifoRdEn <= '0'; + else + nxtState <= curState; + rxFifoRdEn <= '1'; + end if; + + -- Write State + when ST_WRITE => + + -- No Response Request + respReq <= '0'; + + -- Assert write to external interface + nxtInp <= '1'; + nxtReq <= '1'; + nxtOp <= '1'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Keep data + nxtdata <= intData; + + -- Ack is passed + if regAck = '1' then + + -- Generate response + nxtState <= ST_RESP; + + -- Store fail flag, no timeout + nxtFail <= regFail; + nxtTout <= '0'; + + -- Timeout + elsif intReqCnt = x"FFFFFF" then + + -- Generate response + nxtState <= ST_RESP; + + -- No Fail, set timeout + nxtFail <= '0'; + nxtTout <= '1'; + + -- Keep waiting + else + nxtState <= curState; + nxtFail <= '0'; + nxtTout <= '0'; + end if; + + -- Read State + when ST_READ => + + -- No Response Request + respReq <= '0'; + + -- Assert read to external interface + nxtInp <= '1'; + nxtReq <= '1'; + nxtOp <= '0'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Take read data + nxtdata <= regDataIn; + + -- Ack is passed + if regAck = '1' then + + -- Fail + if regFail = '1' then + + -- Store fail flag, no timeout, send response + nxtFail <= regFail; + nxtTout <= '0'; + nxtState <= ST_RESP; + + -- Normal termination + else + + -- No fail or timeout + nxtFail <= '0'; + nxtTout <= '0'; + + -- Set bit command + if intOpCode = "10" then + nxtState <= ST_SET; + + -- Clear bit command + elsif intOpCode = "11" then + nxtState <= ST_CLEAR; + + -- Read command + else + nxtState <= ST_RESP; + end if; + end if; + + -- Timeout + elsif intReqCnt = x"FFFFFF" then + + -- Generate response + nxtState <= ST_RESP; + + -- No Fail, set timeout + nxtFail <= '0'; + nxtTout <= '1'; + + -- Keep waiting + else + nxtState <= curState; + nxtFail <= '0'; + nxtTout <= '0'; + end if; + + -- Set Bit Command + when ST_SET => + + -- No Response Request + respReq <= '0'; + + -- No external commands + nxtInp <= '1'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Set bits + nxtdata <= intData or intWrData; + + -- No errors + nxtFail <= '0'; + nxtTout <= '0'; + + -- Go to write state + -- Wait for ack from previous command to clear + if regAck = '0' then + nxtState <= ST_WRITE; + else + nxtState <= curState; + end if; + + -- Clear Bit Command + when ST_CLEAR => + + -- No Response Request + respReq <= '0'; + + -- No external commands + nxtInp <= '1'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Clear bits + nxtdata <= intData and (not intWrData); + + -- No errors + nxtFail <= '0'; + nxtTout <= '0'; + + -- Go to write state + -- Wait for ack from previous command to clear + if regAck = '0' then + nxtState <= ST_WRITE; + else + nxtState <= curState; + end if; + + -- Response + when ST_RESP => + + -- Response Request + respReq <= '1'; + + -- No external commands + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Keep Data + nxtdata <= intData; + + -- Keep errors + nxtFail <= intFail; + nxtTout <= intTout; + + -- Wait For Response Engine To Response + if respAckDly(1) = '1' then + nxtState <= ST_DONE; + else + nxtState <= curState; + end if; + + -- Done + when ST_DONE => + + -- Response Request + respReq <= '0'; + + -- No external commands + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Disable FIFO Rd + rxFifoRdEn <= '0'; + + -- Keep Data + nxtdata <= intData; + + -- Keep errors + nxtFail <= intFail; + nxtTout <= intTout; + + -- Wait For Response Engine To Respond + if respAckDly(1) = '0' then + nxtState <= ST_IDLE; + else + nxtState <= curState; + end if; + + when others => + respReq <= '0'; + nxtReq <= '0'; + nxtInp <= '0'; + nxtOp <= '0'; + rxFifoRdEn <= '0'; + nxtdata <= (others=>'0'); + nxtFail <= '0'; + nxtTout <= '0'; + nxtState <= ST_IDLE; + end case; + end process; + + + -- Response Data Engine. Runs on PGP clock not local clock. + -- Handshake lines are double synced before being acted upon. + -- Timing constraints must ensure that data moving between + -- clocks is less than the period of the faster clock. + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + respReqDly <= (others=>'0') after tpd; + respAck <= '0' after tpd; + respCnt <= (others=>'0') after tpd; + respValid <= '0' after tpd; + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Sync Response Req Lines + respReqDly(0) <= respReq after tpd; + respReqDly(1) <= respReqDly(0) after tpd; + + -- Response Counter + if respReqDly(1) = '0' then + respCnt <= (others=>'0') after tpd; + elsif respValid = '1' and vcFrameTxReady = '1' then + respCnt <= respCnt + 1 after tpd; + end if; + + -- Request is not asserted + if respReqDly(1) = '0' then + respValid <= '0' after tpd; + respAck <= '0' after tpd; + + -- Request is assert, valid is not assert, ack is not asserted, + -- wait for PGP to be ready. Assert grant and valid + elsif respValid = '0' and respAck = '0' and vcRemBuffAFull = '0' then + respValid <= '1' after tpd; + respAck <= '0' after tpd; + + -- Data movement on last value. Assert ack, de-assert valid + elsif vcFrameTxReady = '1' and respCnt = "111" then + respValid <= '0' after tpd; + respAck <= '1' after tpd; + end if; + + -- Initial Data + if respReqDly(1) = '0' then + vcFrameTxSOF <= '1' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData(15 downto 8) <= intTid(7 downto 0) after tpd; + vcFrameTxData(7 downto 2) <= intDest after tpd; + vcFrameTxData(1 downto 0) <= intVc after tpd; + + -- Data Movement + elsif respValid = '1' and vcFrameTxReady = '1' then + case respCnt is + when "000" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= intTid(23 downto 8) after tpd; + when "001" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= intAddress(15 downto 0) after tpd; + when "010" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData(15 downto 14) <= intOpCode after tpd; + vcFrameTxData(13 downto 8) <= (others=>'0') after tpd; + vcFrameTxData(7 downto 0) <= intAddress(23 downto 16) after tpd; + when "011" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= intData(15 downto 0) after tpd; + when "100" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= intData(31 downto 16) after tpd; + when "101" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= (others=>'0') after tpd; + when "110" => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '1' after tpd; + vcFrameTxData(15 downto 2) <= (others=>'0') after tpd; + vcFrameTxData(1) <= intTout after tpd; + vcFrameTxData(0) <= intFail after tpd; + when others => + vcFrameTxSOF <= '0' after tpd; + vcFrameTxEOF <= '0' after tpd; + vcFrameTxData <= (others=>'0') after tpd; + end case; + end if; + end if; + end process; + + -- Output to PGP + vcFrameTxValid <= respValid; + vcFrameTxEOFE <= '0'; + vcFrameTxCid <= (others=>'0'); + vcFrameTxWidth <= '1'; + +end PgpRegSlave; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpRxTrack.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpRxTrack.vhd new file mode 100755 index 0000000000000000000000000000000000000000..507325d871f8f7ccfd06762fcbf01c65f044ccee --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpRxTrack.vhd @@ -0,0 +1,339 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Receive Tracking Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpRxTrack.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Receive Tracking logic module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 04/18/2007: Added support to track the number of cells in a frame to detect +-- dropped cells. +-- 06/19/2007: Included PgpAckTx block to reduce file count. +-- 07/25/2007: In frame status of all VCs is now output. Cell CRC error changed +-- to cell rx error. +-- 09/18/2007: Changed code go generate abort flag if SOF is received while +-- the VC is in the in-frame state. This will cause the current VC +-- to receive EOF/EOFE combination. +-- 09/29/2007: Changed name of coregen blocks +-- 11/06/2007: Added cellRxShort flag to indicate to tracking logic that EOFE +-- was generated due to short cell. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpRxTrack is port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- PIB Interface + pibLinkReady : in std_logic; -- PIB Link Ready + + -- Error Indication + ackFifoFull : out std_logic; -- ACK FIFO is full + + -- Cell Receiver Block + cellRxSOF : in std_logic; -- Cell contained SOF + cellRxDataVc : in std_logic_vector(1 downto 0); -- Cell virtual channel + cellRxEOF : in std_logic; -- Cell contained EOF + cellRxEOFE : in std_logic; -- Cell contained EOFE + cellRxEmpty : in std_logic; -- Cell was empty + cellRxStart : in std_logic; -- Cell reception start + cellRxDone : in std_logic; -- Cell reception done + cellRxShort : in std_logic; -- Cell receieve is short (PIC Mode) + cellRxCellError : in std_logic; -- Cell receieve error + cellRxSeq : in std_logic_vector(7 downto 0); -- Cell receieve sequence + cellVcInFrame : out std_logic_vector(3 downto 0); -- Cell VC in frame status + cellVcAbort : out std_logic; -- Cell abort flag for current VC + + -- Cell Transmit Logic & schedular + cellTxNAck : out std_logic; -- Cell transmit NACK request + cellTxAck : out std_logic; -- Cell transmit ACK request + cellTxAckSeq : out std_logic_vector(7 downto 0); -- Cell transmit ACK sequence + cellTxAcked : in std_logic; -- Cell transmit ACK was sent + cellTxAckReq : out std_logic -- Cell transmit ACK request + ); + +end PgpRxTrack; + + +-- Define architecture +architecture PgpRxTrack of PgpRxTrack is + + -- ACK/NACK FIFO, 9 * 256 + component pgp_fifo_9x256 port ( + clk: IN std_logic; + rst: IN std_logic; + din: IN std_logic_VECTOR(8 downto 0); + wr_en: IN std_logic; + rd_en: IN std_logic; + dout: OUT std_logic_VECTOR(8 downto 0); + full: OUT std_logic; + empty: OUT std_logic + ); end component; + + -- Local Signals + signal vc0InFrame : std_logic; + signal vc0SeqNum : std_logic_vector(7 downto 0); + signal vc1InFrame : std_logic; + signal vc1SeqNum : std_logic_vector(7 downto 0); + signal vc2InFrame : std_logic; + signal vc2SeqNum : std_logic_vector(7 downto 0); + signal vc3InFrame : std_logic; + signal vc3SeqNum : std_logic_vector(7 downto 0); + signal muxInFrame : std_logic; + signal muxSeqNum : std_logic_vector(7 downto 0); + signal ackTxFifoDin : std_logic_vector(8 downto 0); + signal ackTxFifoDout : std_logic_vector(8 downto 0); + signal ackTxFifoWr : std_logic; + signal ackTxFifoRd : std_logic; + signal ackTxFifoRdDly : std_logic; + signal ackTxFifoFull : std_logic; + signal ackTxFifoEmpty : std_logic; + signal ackTxFifoRst : std_logic; + signal intCellTxAckReq : std_logic; + signal frameRxSeq : std_logic_vector(7 downto 0); + signal frameRxAck : std_logic; + signal frameRxNAck : std_logic; + signal intAbort : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_fifo_9x256 : component is TRUE; + attribute syn_noprune of pgp_fifo_9x256 : component is TRUE; + +begin + + -- VC In frame status output + cellVcInFrame(0) <= vc0InFrame; + cellVcInFrame(1) <= vc1InFrame; + cellVcInFrame(2) <= vc2InFrame; + cellVcInFrame(3) <= vc3InFrame; + cellVcAbort <= intAbort; + + + -- Mux current VC values + process ( cellRxDataVc, vc0InFrame, vc0SeqNum, vc1InFrame, vc1SeqNum, + vc2InFrame, vc2SeqNum, vc3InFrame, vc3SeqNum ) begin + case cellRxDataVc is + when "00" => + muxInFrame <= vc0InFrame; + muxSeqNum <= vc0SeqNum; + when "01" => + muxInFrame <= vc1InFrame; + muxSeqNum <= vc1SeqNum; + when "10" => + muxInFrame <= vc2InFrame; + muxSeqNum <= vc2SeqNum; + when "11" => + muxInFrame <= vc3InFrame; + muxSeqNum <= vc3SeqNum; + when others => + muxInFrame <= '0'; + muxSeqNum <= (others=>'0'); + end case; + end process; + + + -- Drive current status back to cell receive engine + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + frameRxSeq <= (others=>'0') after tpd; + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + vc0InFrame <= '0' after tpd; + vc0SeqNum <= (others=>'0') after tpd; + vc1InFrame <= '0' after tpd; + vc1SeqNum <= (others=>'0') after tpd; + vc2InFrame <= '0' after tpd; + vc2SeqNum <= (others=>'0') after tpd; + vc3InFrame <= '0' after tpd; + vc3SeqNum <= (others=>'0') after tpd; + intAbort <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Link is down, reset status of all VCs + if pibLinkReady = '0' then + vc0InFrame <= '0' after tpd; + vc0SeqNum <= (others=>'0') after tpd; + vc1InFrame <= '0' after tpd; + vc1SeqNum <= (others=>'0') after tpd; + vc2InFrame <= '0' after tpd; + vc2SeqNum <= (others=>'0') after tpd; + vc3InFrame <= '0' after tpd; + vc3SeqNum <= (others=>'0') after tpd; + intAbort <= '0' after tpd; + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + + -- Start of cell, + elsif cellRxStart = '1' then + + -- Detect missing EOF this occurs when + -- we get SOF when we are already in frame + -- Generate NACK for previous sequence number + -- Generate abort signal + if muxInFrame = '1' and cellRxSOF = '1' then + frameRxSeq <= muxSeqNum after tpd; + frameRxAck <= '0' after tpd; + frameRxNAck <= '1' after tpd; + intAbort <= '1' after tpd; + else + frameRxSeq <= (others=>'0') after tpd; + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + intAbort <= '0' after tpd; + end if; + + -- Cell contains start of frame and is not empty + if cellRxSOF = '1' and cellRxEmpty = '0' then + + -- Mark current VC as in frame if in frame flag is not already set. + -- If flag is already set then an error occured and we should to to + -- out of frame state + case cellRxDataVc is + when "00" => + vc0InFrame <= '1' after tpd; + vc0SeqNum <= cellRxSeq after tpd; + when "01" => + vc1InFrame <= '1' after tpd; + vc1SeqNum <= cellRxSeq after tpd; + when "10" => + vc2InFrame <= '1' after tpd; + vc2SeqNum <= cellRxSeq after tpd; + when "11" => + vc3InFrame <= '1' after tpd; + vc3SeqNum <= cellRxSeq after tpd; + when others => + end case; + end if; + + -- End of cell + elsif cellRxDone = '1' then + + -- Clear abort + intAbort <= '0' after tpd; + + -- Cell is in error, mark all VCs as not in frame + if cellRxCellError = '1' then + vc0InFrame <= '0' after tpd; + vc1InFrame <= '0' after tpd; + vc2InFrame <= '0' after tpd; + vc3InFrame <= '0' after tpd; + + -- EOF is received + elsif cellRxEOF = '1' and cellRxEmpty = '0' then + + -- Drive ack/nack only if cell was not short. + -- This is to avoid sending back a nack to the + -- remote end before it is expected. + if cellRxShort = '0' then + + -- Drive ACK/NACK update for one clock. This will handle + -- A NACK for current cell. If others cells are errored + -- out their nack will be handled by the timeout. + frameRxSeq <= muxSeqNum after tpd; + frameRxAck <= not cellRxEOFE after tpd; + frameRxNAck <= cellRxEOFE after tpd; + else + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + end if; + + -- Clear in frame status for current vc + case cellRxDataVc is + when "00" => vc0InFrame <= '0' after tpd; + when "01" => vc1InFrame <= '0' after tpd; + when "10" => vc2InFrame <= '0' after tpd; + when "11" => vc3InFrame <= '0' after tpd; + when others => + end case; + + -- Non EOF frame + else + + -- Clear ACK/NACK drive + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + end if; + + -- Clear Ack/NACK drive + else + frameRxAck <= '0' after tpd; + frameRxNAck <= '0' after tpd; + end if; + end if; + end process; + + + -- Connect external signals + ackFifoFull <= ackTxFifoFull; + cellTxAckReq <= intCellTxAckReq; + + -- Control reads from FIFO + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + cellTxNAck <= '0' after tpd; + cellTxAck <= '0' after tpd; + cellTxAckSeq <= (others=>'0') after tpd; + intCellTxAckReq <= '0' after tpd; + ackTxFifoRdDly <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Delayed copy of FIFO read + ackTxFifoRdDly <= ackTxFifoRd after tpd; + + -- Link has gone down or cell transmitter has acked + if pibLinkReady = '0' or cellTxAcked = '1' then + cellTxNAck <= '0' after tpd; + cellTxAck <= '0' after tpd; + cellTxAckSeq <= (others=>'0') after tpd; + intCellTxAckReq <= '0' after tpd; + + -- New value has been read + elsif ackTxFifoRdDly = '1' then + cellTxNAck <= not ackTxFifoDout(8) after tpd; + cellTxAck <= ackTxFifoDout(8) after tpd; + cellTxAckSeq <= ackTxFifoDout(7 downto 0) after tpd; + intCellTxAckReq <= '1' after tpd; + end if; + end if; + end process; + + -- Generate read signal + ackTxFifoRd <= not intCellTxAckReq and not ackTxFifoEmpty and not ackTxFifoRdDly; + + -- Generate FIFO reset + ackTxFifoRst <= pgpReset or not pibLinkReady; + + -- Control write signals + ackTxFifoWr <= frameRxAck or frameRxNAck; + ackTxFifoDin(8) <= frameRxAck; + ackTxFifoDin(7 downto 0) <= frameRxSeq; + + -- Sequence number FIFO + U_AckTxFifo : pgp_fifo_9x256 port map ( + clk => pgpClk, rst => ackTxFifoRst, + din => ackTxFifoDin, wr_en => ackTxFifoWr, + rd_en => ackTxFifoRd, dout => ackTxFifoDout, + full => ackTxFifoFull, empty => ackTxFifoEmpty + ); + +end PgpRxTrack; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpTop.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpTop.vhd new file mode 100755 index 0000000000000000000000000000000000000000..f92d154ad45c8a026360e98ec441adbc886ce3c7 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpTop.vhd @@ -0,0 +1,714 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Top Level Module +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpTop.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Top level VHDL source file for Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 04/18/2007: Added support to track the number of cells in a frame to detect +-- dropped cells. +-- 04/19/2007: Added link ready flag to cell receiver +-- 05/30/2007: Added lock bits and inverted flag outputs. +-- 05/31/2007: Removed lock bits +-- 06/08/2007: Added lock bits +-- 06/19/2007: Removed PgpRandData, PpgAckTx, PgpErrorCount blocks +-- 07/19/2007: Removed cellTxCount +-- 08/25/2007: Changed error count signals. +-- 09/18/2007: Added forceCellSize signal to make sure all outgoing cells are +-- 512 bytes unless they are the last in a frame. +-- 09/19/2007: Changed force cell size signal to PIC mode signal +-- 09/21/2007: Ack timeout & Pic Mode converted to generics. +-- 09/21/2007: Removed payload imput +-- 11/06/2007: Added cellRxShort flag to indicate to tracking logic that EOFE +-- was generated due to short cell. +-- 11/05/2008: Removed chipscope. Removed rx/tx pll and reset logic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use work.PgpVersion.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpTop is + generic ( + AckTimeout : natural := 8; -- Ack/Nack Not Received Timeout, 8.192uS Steps + PicMode : natural := 0 -- PIC Interface Mode, 1=PIC, 0=Normal + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibReLink : in std_logic; -- Re-Link control signal + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxWidth : in std_logic; -- User frame data width + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data end of frame error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc0FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc0FrameTxAck : out std_logic; -- PGP ACK/NACK + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxWidth : in std_logic; -- User frame data width + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data end of frame error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc1FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc1FrameTxAck : out std_logic; -- PGP ACK/NACK + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxWidth : in std_logic; -- User frame data width + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data end of frame error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc2FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc2FrameTxAck : out std_logic; -- PGP ACK/NACK + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxWidth : in std_logic; -- User frame data width + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data end of frame error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc3FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc3FrameTxAck : out std_logic; -- PGP ACK/NACK + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxWidth : out std_logic; -- PGP frame data width + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data end of frame error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxWidth : out std_logic; -- PGP frame data width + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data end of frame error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc2FrameRxWidth : out std_logic; -- PGP frame data width + vc2FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc2FrameRxEOFE : out std_logic; -- PGP frame data end of frame error + vc2FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc3FrameRxWidth : out std_logic; -- PGP frame data width + vc3FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc3FrameRxEOFE : out std_logic; -- PGP frame data end of frame error + vc3FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + + -- Transmit CRC Interface + crcTxIn : out std_logic_vector(15 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxWidth : out std_logic; -- Transmit data for CRC width + crcTxOut : in std_logic_vector(31 downto 0); -- Transmit calculated CRC value + + -- Receive CRC Interface + crcRxIn : out std_logic_vector(15 downto 0); -- Receive data for CRC + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxWidth : out std_logic; -- Receive data for CRC width + crcRxOut : in std_logic_vector(31 downto 0); -- Receive calculated CRC value + + -- Physical Interface Signals + phyRxPolarity : out std_logic; -- PHY receive signal polarity + phyRxData : in std_logic_vector(15 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(1 downto 0); -- PHY receive data is K character + phyTxData : out std_logic_vector(15 downto 0); -- PHY transmit data + phyTxDataK : out std_logic_vector(1 downto 0); -- PHY transmit data is K character + phyLinkError : in std_logic; -- PHY 8B10B or disparity error + phyInitDone : in std_logic; -- PHY init is done + + -- Event Counters & Status Signals + localVersion : out std_logic_vector(7 downto 0); -- Local version ID + remoteVersion : out std_logic_vector(7 downto 0); -- Remote version ID + pibFail : out std_logic; -- PIB fail indication + pibState : out std_logic_vector(2 downto 0); -- PIB State + pibLinkReady : out std_logic; -- PIB link is ready + pgpSeqError : out std_logic; -- PGP Sequence Logic Error Occured + countLinkDown : out std_logic; -- Link down count increment + countLinkError : out std_logic; -- Disparity/Decode error count + countNack : out std_logic; -- NACK count increment + countCellError : out std_logic -- Receive Cell error count + ); + +end PgpTop; + + +-- Define architecture +architecture PgpTop of PgpTop is + + -- ACK/NACK Receiver Logic + component PgpAckRx + generic ( + AckTimeout : natural := 8 -- Ack/Nack Not Received Timeout, 8.192uS Steps + ); + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + seqFifoEmpty : out std_logic; -- Sequence number fifo is empty + nackCountInc : out std_logic; -- Nack received count increment + cellRxDone : in std_logic; -- Cell reception done + cellRxCellError : in std_logic; -- Cell receieve error + cellRxSeq : in std_logic_vector(7 downto 0); -- Cell receieve sequence + cellRxAck : in std_logic; -- Cell receieve ACK + cellRxNAck : in std_logic; -- Cell receieve NACK + cidReady : out std_logic; -- CID Engine is ready + cidTimerStart : in std_logic; -- CID timer start + cellTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + cidSave : in std_logic; -- CID value store signal + cellTxSOF : in std_logic; -- Cell contained SOF + cellTxDataSeq : out std_logic_vector(7 downto 0); -- Transmit sequence number + vc0FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc0FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc0FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc0FrameTxAck : out std_logic; -- PGP ACK/NACK + vc1FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc1FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc1FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc1FrameTxAck : out std_logic; -- PGP ACK/NACK + vc2FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc2FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc2FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc2FrameTxAck : out std_logic; -- PGP ACK/NACK + vc3FrameTxCid : in std_logic_vector(31 downto 0); -- User frame data, context ID + vc3FrameTxAckCid : out std_logic_vector(31 downto 0); -- PGP ACK/NACK context ID + vc3FrameTxAckEn : out std_logic; -- PGP ACK/NACK enable + vc3FrameTxAck : out std_logic -- PGP ACK/NACK + ); + end component; + + + -- Cell Receiver Logic + component PgpCellRx + generic ( + PicMode : natural := 0 -- PIC Interface Mode, 1=PIC, 0=Normal + ); + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + cellRxSOF : out std_logic; -- Cell contained SOF + cellRxDataVc : out std_logic_vector(1 downto 0); -- Cell virtual channel + cellRxEOF : out std_logic; -- Cell contained EOF + cellRxEOFE : out std_logic; -- Cell contained EOFE + cellRxEmpty : out std_logic; -- Cell was empty + cellVcInFrame : in std_logic_vector(3 downto 0); -- Cell VC in frame status + cellVcAbort : in std_logic; -- Cell abort flag for current VC + cellRxDone : out std_logic; -- Cell reception done + cellRxShort : out std_logic; -- Cell receieve is short (PIC Mode) + cellRxStart : out std_logic; -- Cell reception start + cellRxCellError : out std_logic; -- Cell receieve CRC error + cellRxSeq : out std_logic_vector(7 downto 0); -- Cell receieve sequence + cellRxAck : out std_logic; -- Cell receieve ACK + cellRxNAck : out std_logic; -- Cell receieve NACK + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxWidth : out std_logic; -- PGP frame data width + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxWidth : out std_logic; -- PGP frame data width + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc2FrameRxWidth : out std_logic; -- PGP frame data width + vc2FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc2FrameRxEOFE : out std_logic; -- PGP frame data error + vc2FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc3FrameRxWidth : out std_logic; -- PGP frame data width + vc3FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc3FrameRxEOFE : out std_logic; -- PGP frame data error + vc3FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + crcRxIn : out std_logic_vector(15 downto 0); -- Receive data for CRC + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxWidth : out std_logic; -- Receive data for CRC width + crcRxOut : in std_logic_vector(31 downto 0); -- Receive calculated CRC value + pibRxSOC : in std_logic; -- Cell data start of cell + pibRxWidth : in std_logic; -- Cell data width + pibRxEOC : in std_logic; -- Cell data end of cell + pibRxEOF : in std_logic; -- Cell data end of frame + pibRxEOFE : in std_logic; -- Cell data end of frame error + pibRxData : in std_logic_vector(15 downto 0) -- Cell data data + ); + end component; + + -- Cell Transmit Logic + component PgpCellTx + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + cellTxDataSeq : in std_logic_vector(7 downto 0); -- Transmit sequence number + cellTxSOF : out std_logic; -- Cell contained SOF + cellTxEOF : out std_logic; -- Cell contained EOF + cellTxIdle : in std_logic; -- Force IDLE transmit + cellTxReq : in std_logic; -- Cell transmit request + cellTxInp : out std_logic; -- Cell transmit in progress + cellTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + cellTxNAck : in std_logic; -- Cell transmit NACK request + cellTxAck : in std_logic; -- Cell transmit ACK request + cellTxAckSeq : in std_logic_vector(7 downto 0); -- Cell transmit ACK sequence + cellTxAcked : out std_logic; -- Cell transmit ACK was sent + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxWidth : in std_logic; -- User frame data width + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxWidth : in std_logic; -- User frame data width + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxWidth : in std_logic; -- User frame data width + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxWidth : in std_logic; -- User frame data width + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + pibTxSOC : out std_logic; -- Cell data start of cell + pibTxWidth : out std_logic; -- Cell data width + pibTxEOC : out std_logic; -- Cell data end of cell + pibTxEOF : out std_logic; -- Cell data end of frame + pibTxEOFE : out std_logic; -- Cell data end of frame error + pibTxData : out std_logic_vector(15 downto 0); -- Cell data data + crcTxIn : out std_logic_vector(15 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxWidth : out std_logic; -- Transmit data for CRC width + crcTxOut : in std_logic_vector(31 downto 0) -- Transmit calculated CRC value + ); + end component; + + + -- Physical Interface Block + component PgpPhy + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibReLink : in std_logic; -- Re-Link control signal + localVersion : in std_logic_vector(7 downto 0); -- Local version ID + remoteVersion : out std_logic_vector(7 downto 0); -- Remote version ID + pibFail : out std_logic; -- PIB fail indication + pibLinkReady : out std_logic; -- PIB link is ready + pibState : out std_logic_vector(2 downto 0); -- PIB State + pibTxSOC : in std_logic; -- Cell data start of cell + pibTxWidth : in std_logic; -- Cell data width + pibTxEOC : in std_logic; -- Cell data end of cell + pibTxEOF : in std_logic; -- Cell data end of frame + pibTxEOFE : in std_logic; -- Cell data end of frame error + pibTxData : in std_logic_vector(15 downto 0); -- Cell data data + pibRxSOC : out std_logic; -- Cell data start of cell + pibRxWidth : out std_logic; -- Cell data width + pibRxEOC : out std_logic; -- Cell data end of cell + pibRxEOF : out std_logic; -- Cell data end of frame + pibRxEOFE : out std_logic; -- Cell data end of frame error + pibRxData : out std_logic_vector(15 downto 0); -- Cell data data + phyRxPolarity : out std_logic; -- PHY receive signal polarity + phyRxData : in std_logic_vector(15 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(1 downto 0); -- PHY receive data is K char + phyTxData : out std_logic_vector(15 downto 0); -- PHY transmit data + phyTxDataK : out std_logic_vector(1 downto 0); -- PHY transmit data is K char + phyInitDone : in std_logic -- PHY init is done + ); + end component; + + -- Receiver Tracking Logic + component PgpRxTrack + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + ackFifoFull : out std_logic; -- ACK FIFO is full + cellRxSOF : in std_logic; -- Cell contained SOF + cellRxDataVc : in std_logic_vector(1 downto 0); -- Cell virtual channel + cellRxEOF : in std_logic; -- Cell contained EOF + cellRxEOFE : in std_logic; -- Cell contained EOFE + cellRxEmpty : in std_logic; -- Cell was empty + cellRxDone : in std_logic; -- Cell reception done + cellRxShort : in std_logic; -- Cell receieve is short (PIC Mode) + cellRxStart : in std_logic; -- Cell reception start + cellRxCellError : in std_logic; -- Cell receieve error + cellRxSeq : in std_logic_vector(7 downto 0); -- Cell receieve sequence + cellVcInFrame : out std_logic_vector(3 downto 0); -- Cell VC in frame status + cellVcAbort : out std_logic; -- Cell abort flag for current VC + cellTxNAck : out std_logic; -- Cell transmit NACK request + cellTxAck : out std_logic; -- Cell transmit ACK request + cellTxAckSeq : out std_logic_vector(7 downto 0); -- Cell transmit ACK sequence + cellTxAcked : in std_logic; -- Cell transmit ACK was sent + cellTxAckReq : out std_logic -- Cell transmit ACK request + ); + end component; + + -- Transmit Schedular + component PgpTxSched + port ( + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + pibLinkReady : in std_logic; -- PIB Link Ready + cidReady : in std_logic; -- CID Engine is ready + cidTimerStart : out std_logic; -- CID timer start + cidSave : out std_logic; -- CID value store signal + cellTxAckReq : in std_logic; -- Cell ACK/NACK transmit request + cellTxSOF : in std_logic; -- Cell contained SOF + cellTxEOF : in std_logic; -- Cell contained EOF + cellTxIdle : out std_logic; -- Force IDLE transmit + cellTxReq : out std_logic; -- Cell transmit request + cellTxInp : in std_logic; -- Cell transmit in progress + cellTxDataVc : out std_logic_vector(1 downto 0); -- Cell transmit virtual channel + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxValid : in std_logic -- User frame data is valid + ); + end component; + + + -- Local Signals + signal intLinkReady : std_logic; -- PIB Link Ready + signal seqFifoEmpty : std_logic; -- Sequence number fifo is empty + signal nackCountInc : std_logic; -- Nack received count increment + signal cellRxDone : std_logic; -- Cell reception done + signal cellRxShort : std_logic; -- Cell receieve is short (PIC Mode) + signal cellRxStart : std_logic; -- Cell reception start + signal cellRxCellError : std_logic; -- Cell receieve CRC error + signal cellVcInFrame : std_logic_vector(3 downto 0); -- Cell VC in frame status + signal cellVcAbort : std_logic; -- Cell VC abort control + signal cellRxSeq : std_logic_vector(7 downto 0); -- Cell receieve sequence + signal cellRxAck : std_logic; -- Cell receieve ACK + signal cellRxNAck : std_logic; -- Cell receieve NACK + signal cidTimerStart : std_logic; -- CID timer start + signal cidReady : std_logic; -- Sequence FIFO ready + signal cidSave : std_logic; -- CID save for later + signal ackFifoFull : std_logic; -- ACK FIFO is full + signal cellTxNAck : std_logic; -- Cell transmit NACK request + signal cellTxAck : std_logic; -- Cell transmit ACK request + signal cellTxAckSeq : std_logic_vector(7 downto 0); -- Cell transmit ACK sequence + signal cellTxAcked : std_logic; -- Cell transmit ACK was sent + signal cellTxAckReq : std_logic; -- Cell transmit ACK request + signal cellRxSOF : std_logic; -- Cell contained SOF + signal cellRxDataVc : std_logic_vector(1 downto 0); -- Cell virtual channel + signal cellRxEOF : std_logic; -- Cell contained EOF + signal cellRxEOFE : std_logic; -- Cell contained EOFE + signal cellRxEmpty : std_logic; -- Cell was empty + signal pibRxSOC : std_logic; -- Cell data start of cell + signal pibRxWidth : std_logic; -- Cell data width + signal pibRxEOC : std_logic; -- Cell data end of cell + signal pibRxEOF : std_logic; -- Cell data end of frame + signal pibRxEOFE : std_logic; -- Cell data end of frame error + signal pibRxData : std_logic_vector(15 downto 0); -- Cell data data + signal cellTxDataSeq : std_logic_vector(7 downto 0); -- Transmit sequence number + signal cellTxSOF : std_logic; -- Cell contained SOF + signal cellTxEOF : std_logic; -- Cell contained EOF + signal cellTxIdle : std_logic; -- Force IDLE transmit + signal cellTxReq : std_logic; -- Cell transmit request + signal cellTxInp : std_logic; -- Cell transmit in progress + signal cellTxDataVc : std_logic_vector(1 downto 0); -- Cell transmit virtual channel + signal pibTxSOC : std_logic; -- Cell data start of cell + signal pibTxWidth : std_logic; -- Cell data width + signal pibTxEOC : std_logic; -- Cell data end of cell + signal pibTxEOF : std_logic; -- Cell data end of frame + signal pibTxEOFE : std_logic; -- Cell data end of frame error + signal pibTxData : std_logic_vector(15 downto 0); -- Cell data data + signal intVersion : std_logic_vector(7 downto 0); -- Local version ID + signal phyLinkErrorDly : std_logic; -- Delayed copy of PIB link error + signal nackCountIncDly : std_logic; -- Delayed copy of nack counter + signal cellRxCellErrorDly : std_logic; -- Delayed copy of error + signal linkDownBlock : std_logic_vector(7 downto 0); -- Delayed copy of link ready signal + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- Set version value + intVersion <= work.pgpVersion.PgpVersion; + + -- Version & Link Failure + localVersion <= intVersion; + pibLinkReady <= intLinkReady; + + + -- ACK/NACK Receive Logic + U_PgpAckRx: PgpAckRx generic map ( AckTimeout => AckTimeout ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + pibLinkReady => intLinkReady, seqFifoEmpty => seqFifoEmpty, + nackCountInc => nackCountInc, cellRxDone => cellRxDone, + cellRxCellError => cellRxCellError, cellRxSeq => cellRxSeq, + cellRxAck => cellRxAck, cellRxNAck => cellRxNAck, + cidReady => cidReady, cellTxDataSeq => cellTxDataSeq, + cellTxSOF => cellTxSOF, cidTimerStart => cidTimerStart, + cellTxDataVc => cellTxDataVc, cidSave => cidSave, + vc0FrameTxCid => vc0FrameTxCid, vc1FrameTxCid => vc1FrameTxCid, + vc2FrameTxCid => vc2FrameTxCid, vc3FrameTxCid => vc3FrameTxCid, + vc0FrameTxAckCid => vc0FrameTxAckCid, vc0FrameTxAckEn => vc0FrameTxAckEn, + vc0FrameTxAck => vc0FrameTxAck, vc1FrameTxAckCid => vc1FrameTxAckCid, + vc1FrameTxAckEn => vc1FrameTxAckEn, vc1FrameTxAck => vc1FrameTxAck, + vc2FrameTxAckCid => vc2FrameTxAckCid, vc2FrameTxAckEn => vc2FrameTxAckEn, + vc2FrameTxAck => vc2FrameTxAck, vc3FrameTxAckCid => vc3FrameTxAckCid, + vc3FrameTxAckEn => vc3FrameTxAckEn, vc3FrameTxAck => vc3FrameTxAck + ); + + -- Cell Receiver Logic + U_PgpCellRx: PgpCellRx generic map ( PicMode => PicMode ) port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + cellRxSOF => cellRxSOF, cellRxDataVc => cellRxDataVc, + cellRxEOF => cellRxEOF, cellRxEOFE => cellRxEOFE, + cellRxEmpty => cellRxEmpty, cellVcInFrame => cellVcInFrame, + cellRxDone => cellRxDone, cellRxCellError => cellRxCellError, + cellRxSeq => cellRxSeq, cellRxAck => cellRxAck, + cellRxNAck => cellRxNAck, vc0FrameRxValid => vc0FrameRxValid, + vc0FrameRxSOF => vc0FrameRxSOF, vc0FrameRxWidth => vc0FrameRxWidth, + vc0FrameRxEOF => vc0FrameRxEOF, vc0FrameRxEOFE => vc0FrameRxEOFE, + vc0FrameRxData => vc0FrameRxData, vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, vc1FrameRxValid => vc1FrameRxValid, + vc1FrameRxSOF => vc1FrameRxSOF, vc1FrameRxWidth => vc1FrameRxWidth, + vc1FrameRxEOF => vc1FrameRxEOF, vc1FrameRxEOFE => vc1FrameRxEOFE, + vc1FrameRxData => vc1FrameRxData, vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, vc2FrameRxValid => vc2FrameRxValid, + vc2FrameRxSOF => vc2FrameRxSOF, vc2FrameRxWidth => vc2FrameRxWidth, + vc2FrameRxEOF => vc2FrameRxEOF, vc2FrameRxEOFE => vc2FrameRxEOFE, + vc2FrameRxData => vc2FrameRxData, vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, vc3FrameRxValid => vc3FrameRxValid, + vc3FrameRxSOF => vc3FrameRxSOF, vc3FrameRxWidth => vc3FrameRxWidth, + vc3FrameRxEOF => vc3FrameRxEOF, vc3FrameRxEOFE => vc3FrameRxEOFE, + vc3FrameRxData => vc3FrameRxData, vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, crcRxIn => crcRxIn, + crcRxInit => crcRxInit, crcRxValid => crcRxValid, + crcRxWidth => crcRxWidth, crcRxOut => crcRxOut, + pibRxSOC => pibRxSOC, pibRxWidth => pibRxWidth, + pibRxEOC => pibRxEOC, pibRxEOF => pibRxEOF, + pibRxEOFE => pibRxEOFE, pibRxData => pibRxData, + cellRxStart => cellRxStart, pibLinkReady => intLinkReady, + cellVcAbort => cellVcAbort, cellRxShort => cellRxShort + ); + + -- Cell Transmitter Logic + U_PgpCellTx: PgpCellTx port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + cellTxDataSeq => cellTxDataSeq, cellTxSOF => cellTxSOF, + cellTxEOF => cellTxEOF, cellTxIdle => cellTxIdle, + cellTxReq => cellTxReq, cellTxInp => cellTxInp, + cellTxDataVc => cellTxDataVc, cellTxNAck => cellTxNAck, + cellTxAck => cellTxAck, cellTxAckSeq => cellTxAckSeq, + cellTxAcked => cellTxAcked, vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxWidth => vc0FrameTxWidth, vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, vc1FrameTxWidth => vc1FrameTxWidth, + vc1FrameTxEOF => vc1FrameTxEOF, vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxWidth => vc2FrameTxWidth, vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, vc3FrameTxWidth => vc3FrameTxWidth, + vc3FrameTxEOF => vc3FrameTxEOF, vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, pibTxSOC => pibTxSOC, + pibTxWidth => pibTxWidth, pibTxEOC => pibTxEOC, + pibTxEOF => pibTxEOF, pibTxEOFE => pibTxEOFE, + pibTxData => pibTxData, crcTxIn => crcTxIn, + crcTxInit => crcTxInit, crcTxValid => crcTxValid, + crcTxWidth => crcTxWidth, crcTxOut => crcTxOut, + pibLinkReady => intLinkReady + ); + + -- Physical Interface Block + U_PgpPhy: PgpPhy port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + pibReLink => pibReLink, localVersion => intVersion, + remoteVersion => remoteVersion, pibFail => pibFail, + pibLinkReady => intLinkReady, pibState => pibState, + pibTxSOC => pibTxSOC, pibTxWidth => pibTxWidth, + pibTxEOC => pibTxEOC, pibTxEOF => pibTxEOF, + pibTxEOFE => pibTxEOFE, pibTxData => pibTxData, + pibRxSOC => pibRxSOC, pibRxWidth => pibRxWidth, + pibRxEOC => pibRxEOC, pibRxEOF => pibRxEOF, + pibRxEOFE => pibRxEOFE, pibRxData => pibRxData, + phyRxPolarity => phyRxPolarity, phyRxData => phyRxData, + phyRxDataK => phyRxDataK, phyTxData => phyTxData, + phyTxDataK => phyTxDataK, phyInitDone => phyInitDone + ); + + -- Receiver Tracking Logic + U_PgpRxTrack: PgpRxTrack port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + pibLinkReady => intLinkReady, ackFifoFull => ackFifoFull, + cellRxSOF => cellRxSOF, cellRxDataVc => cellRxDataVc, + cellRxEOF => cellRxEOF, cellRxEOFE => cellRxEOFE, + cellRxEmpty => cellRxEmpty, cellRxStart => cellRxStart, + cellRxDone => cellRxDone, cellRxCellError => cellRxCellError, + cellRxSeq => cellRxSeq, cellVcInFrame => cellVcInFrame, + cellTxNAck => cellTxNAck, cellTxAck => cellTxAck, + cellTxAckSeq => cellTxAckSeq, cellTxAcked => cellTxAcked, + cellTxAckReq => cellTxAckReq, cellVcAbort => cellVcAbort, + cellRxShort => cellRxShort + ); + + -- Transmit Schedular Logic + U_PgpTxSched: PgpTxSched port map ( + pgpClk => pgpClk, pgpReset => pgpReset, + pibLinkReady => intLinkReady, cidReady => cidReady, + cidTimerStart => cidTimerStart, cidSave => cidSave, + cellTxAckReq => cellTxAckReq, cellTxSOF => cellTxSOF, + cellTxEOF => cellTxEOF, cellTxIdle => cellTxIdle, + cellTxReq => cellTxReq, cellTxInp => cellTxInp, + cellTxDataVc => cellTxDataVc, vc0FrameTxValid => vc0FrameTxValid, + vc1FrameTxValid => vc1FrameTxValid, vc2FrameTxValid => vc2FrameTxValid, + vc3FrameTxValid => vc3FrameTxValid + ); + + + -- Generate error count pulses + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + phyLinkErrorDly <= '0' after tpd; + nackCountIncDly <= '0' after tpd; + cellRxCellErrorDly <= '0' after tpd; + countLinkDown <= '0' after tpd; + countLinkError <= '0' after tpd; + countNack <= '0' after tpd; + countCellError <= '0' after tpd; + pgpSeqError <= '0' after tpd; + linkDownBlock <= (others=>'0') after tpd; + + elsif rising_edge(pgpClk) then + + -- Delay chain to block counts when link is down + if intLinkReady = '0' then + linkDownBlock <= (others=>'0') after tpd; + else + linkDownBlock(7 downto 1) <= linkDownBlock(6 downto 0) after tpd; + linkDownBlock(0) <= '1' after tpd; + end if; + + -- Detect error in sequence logic. Latch until re-link + if linkDownBlock(7) = '0' then + pgpSeqError <= '0' after tpd; + elsif ackFifoFull = '1' or seqFifoEmpty = '1' then + pgpSeqError <= '1' after tpd; + end if; + + -- Delayed copy of signals + phyLinkErrorDly <= phyLinkError after tpd; + nackCountIncDly <= nackCountInc after tpd; + cellRxCellErrorDly <= cellRxCellError after tpd; + + -- Only count when link has been up and is stable + if linkDownBlock(7) = '1' then + + -- Edge detect + countLinkError <= not phyLinkErrorDly and phyLinkError after tpd; + countNack <= not nackCountIncDly and nackCountInc after tpd; + countCellError <= not cellRxCellErrorDly and cellRxCellError after tpd; + else + countLinkError <= '0' after tpd; + countNack <= '0' after tpd; + countCellError <= '0' after tpd; + end if; + + -- Link down counter + countLinkDown <= (not intLinkReady) and linkDownBlock(0) after tpd; + + end if; + end process; + +end PgpTop; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpTxSched.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpTxSched.vhd new file mode 100644 index 0000000000000000000000000000000000000000..402994566c984834c2e5de73db9acc1b3b247439 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpTxSched.vhd @@ -0,0 +1,267 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Transmit Schedular +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpTxSched.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Transmit schedular module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +-- 04/18/2007: Added support to track the number of cells in a frame to detect +-- dropped cells. +-- 06/19/2007: Added two clocks of delay after a cell. This ensures the +-- received cell is always fully processed even if a skip is +-- dropped. +-- 07/19/2007: Removed support to track the number of cells in a frame to detect +-- dropped cells. +-- 09/21/2007: Removed payload imput +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpTxSched is port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- PIB Interface + pibLinkReady : in std_logic; -- PIB Link Ready + + -- ACK/NACK Receiver Logic + cidReady : in std_logic; -- CID Engine is ready + cidTimerStart : out std_logic; -- CID timer start + cidSave : out std_logic; -- CID value store signal + + -- ACK/NACK Transmit Logic + cellTxAckReq : in std_logic; -- Cell ACK/NACK transmit request + + -- Cell Transmit Logic + cellTxSOF : in std_logic; -- Cell contained SOF + cellTxEOF : in std_logic; -- Cell contained EOF + cellTxIdle : out std_logic; -- Force IDLE transmit + cellTxReq : out std_logic; -- Cell transmit request + cellTxInp : in std_logic; -- Cell transmit in progress + cellTxDataVc : out std_logic_vector(1 downto 0); -- Cell transmit virtual channel + + -- User logic interface + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxValid : in std_logic -- User frame data is valid + ); + +end PgpTxSched; + + +-- Define architecture +architecture PgpTxSched of PgpTxSched is + + -- Local Signals + signal arbTxVc : std_logic_vector(1 downto 0); + signal nxtTxVc : std_logic_vector(1 downto 0); + signal arbTxIdle : std_logic; + signal nxtTxValid : std_logic; + signal nxtInFrame : std_logic; + signal arbEn : std_logic; + signal arbEnDly : std_logic; + signal vcInFrame : std_logic_vector(3 downto 0); + + -- Schedular state + constant ST_ARB : std_logic_vector(1 downto 0) := "01"; + constant ST_REQ : std_logic_vector(1 downto 0) := "10"; + constant ST_INP : std_logic_vector(1 downto 0) := "11"; + constant ST_DLY : std_logic_vector(1 downto 0) := "00"; + signal curState : std_logic_vector(1 downto 0); + signal nxtState : std_logic_vector(1 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Outgoing signals + cellTxReq <= arbEnDly; + cellTxDataVc <= arbTxVc; + cellTxIdle <= arbTxIdle; + cidSave <= arbEnDly; + + -- Drive timer start if we think frame is being transmitted and + -- EOF or SOF is transmitted. + cidTimerStart <= vcInFrame(conv_integer(arbTxVc)) and (cellTxSOF or cellTxEOF); + + + -- State transition logic + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + curState <= ST_ARB after tpd; + arbTxVc <= "00" after tpd; + arbTxIdle <= '0' after tpd; + arbEnDly <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Force state to select state when link goes down + if pibLinkReady = '0' then + curState <= ST_ARB after tpd; + else + curState <= nxtState after tpd; + end if; + + -- Delayed version of arb enable + arbEnDly <= arbEn after tpd; + + -- Only select new source if arbitration is enabled + if arbEn = '1' then + + -- No one is requesting or ack/nack tx is required and + -- selected source is not already in frame + -- Transmit idle frame, keep same last VC for next arb + if nxtTxValid = '0' or ( cellTxAckReq = '1' and nxtInFrame = '0' ) then + arbTxIdle <= '1' after tpd; + + -- Choose next vc source + else + arbTxVc <= nxtTxVc after tpd; + arbTxIdle <= '0' after tpd; + end if; + end if; + end if; + end process; + + + -- Scheduler state machine + process ( curState, cidReady, cellTxInp, pibLinkReady ) begin + case curState is + + -- IDLE, wait for ack receiver to be ready + when ST_ARB => + + -- Continue when ack transmitter is ready + if cidReady = '1' and pibLinkReady = '1' then + nxtState <= ST_REQ; + arbEn <= '1'; + else + nxtState <= curState; + arbEn <= '0'; + end if; + + -- REQ, assert request + when ST_REQ => + + -- No arb, transmit already requested + arbEn <= '0'; + + -- Move to in progress state + nxtState <= ST_INP; + + -- Cell transmission in progress, wait for it to be done + when ST_INP => + + -- No arb, no tx + arbEn <= '0'; + + -- Wait for in progress to be done + if cellTxInp = '0' then + nxtState <= ST_DLY; + arbEn <= '0'; + else + nxtState <= curState; + arbEn <= '0'; + end if; + + -- Delay one clock + when ST_DLY => + + -- No arb, transmit already requested + arbEn <= '0'; + + -- Move to arb state + nxtState <= ST_ARB; + + -- Just in case + when others => + arbEn <= '0'; + nxtState <= ST_ARB; + end case; + end process; + + + -- Select in frame status of arb winner + nxtInFrame <= vcInFrame(conv_integer(nxtTxVc)); + + -- Arbitrate for the next VC value based upon current VC value + -- and status of valid inputs + process ( arbTxVc, vc0FrameTxValid, vc1FrameTxValid, + vc2FrameTxValid, vc3FrameTxValid ) begin + case arbTxVc is + when "00" => + if vc1FrameTxValid = '1' then nxtTxVc <= "01"; nxtTxValid <= '1'; + elsif vc2FrameTxValid = '1' then nxtTxVc <= "10"; nxtTxValid <= '1'; + elsif vc3FrameTxValid = '1' then nxtTxVc <= "11"; nxtTxValid <= '1'; + elsif vc0FrameTxValid = '1' then nxtTxVc <= "00"; nxtTxValid <= '1'; + else nxtTxVc <= arbTxVc; nxtTxValid <= '0'; end if; + when "01" => + if vc2FrameTxValid = '1' then nxtTxVc <= "10"; nxtTxValid <= '1'; + elsif vc3FrameTxValid = '1' then nxtTxVc <= "11"; nxtTxValid <= '1'; + elsif vc0FrameTxValid = '1' then nxtTxVc <= "00"; nxtTxValid <= '1'; + elsif vc1FrameTxValid = '1' then nxtTxVc <= "01"; nxtTxValid <= '1'; + else nxtTxVc <= arbTxVc; nxtTxValid <= '0'; end if; + when "10" => + if vc3FrameTxValid = '1' then nxtTxVc <= "11"; nxtTxValid <= '1'; + elsif vc0FrameTxValid = '1' then nxtTxVc <= "00"; nxtTxValid <= '1'; + elsif vc1FrameTxValid = '1' then nxtTxVc <= "01"; nxtTxValid <= '1'; + elsif vc2FrameTxValid = '1' then nxtTxVc <= "10"; nxtTxValid <= '1'; + else nxtTxVc <= arbTxVc; nxtTxValid <= '0'; end if; + when "11" => + if vc0FrameTxValid = '1' then nxtTxVc <= "00"; nxtTxValid <= '1'; + elsif vc1FrameTxValid = '1' then nxtTxVc <= "01"; nxtTxValid <= '1'; + elsif vc2FrameTxValid = '1' then nxtTxVc <= "10"; nxtTxValid <= '1'; + elsif vc3FrameTxValid = '1' then nxtTxVc <= "11"; nxtTxValid <= '1'; + else nxtTxVc <= arbTxVc; nxtTxValid <= '0'; end if; + when others => + nxtTxVc <= "00"; nxtTxValid <= '0'; + end case; + end process; + + + -- Lock in the status of the last cell transmitted + -- Also track the current frame status of each VC + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcInFrame <= "0000" after tpd; + elsif rising_edge(pgpClk) then + + -- Link is down, reset status + if pibLinkReady = '0' then + vcInFrame <= "0000" after tpd; + else + + -- Cell transmission is in progress + if cellTxInp = '1' then + + -- Update state of VC, track if VC is currently in frame or not + -- SOF transmitted + if cellTxSOF = '1' then + vcInFrame(conv_integer(arbTxVc)) <= '1' after tpd; + + -- EOF transmitted + elsif cellTxEOF = '1' then + vcInFrame(conv_integer(arbTxVc)) <= '0' after tpd; + end if; + end if; + end if; + end if; + end process; + +end PgpTxSched; + diff --git a/rce/fw-hsio/modules/pgp/hdl/PgpVersion.vhd b/rce/fw-hsio/modules/pgp/hdl/PgpVersion.vhd new file mode 100644 index 0000000000000000000000000000000000000000..eaef0e25824fa3fcf6469badc8afbd266bc2d957 --- /dev/null +++ b/rce/fw-hsio/modules/pgp/hdl/PgpVersion.vhd @@ -0,0 +1,44 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Version Constant +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpVersion.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/24/2006 +------------------------------------------------------------------------------- +-- Description: +-- Version Constant module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/24/2006: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package PgpVersion is + + constant PgpVersion : std_logic_vector(7 downto 0) := "11001110"; + +end PgpVersion; + +------------------------------------------------------------------------------- +-- Revision History: +-- 10/24/2006 (0x00): Initial Version +-- 03/22/2006 (0xC8): Changed to non-zero version value +-- 06/08/2007 (0xC9): Changed CRC Reset and RX/TX PLL Lock Tracking +-- 06/11/2007 (0xCA): Clock now generated externally. Reverted back to original +-- initialization sequence. +-- 06/14/2007 (0xCB): Fixed link state init to follow Xilinx spec. Fixed +-- generation of error increment signals. +-- 08/27/2007 (0xCC): Link init now matches xilinx exactly. Changed cell structure +-- to close all open error cases. +-- 09/18/2007 (0xCD): Added enforcement of cell size on receive for PIC interface. +-- Also added frame abort if SOF is received while in frame. +-- 09/19/2007 (0xCE): Changed force frame signal to PIC mode signal. Added next +-- cell drop after error cell in order to give time to abort +-- the each active VC to the PIC +------------------------------------------------------------------------------- + diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_afifo_18x1023.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_afifo_18x1023.xco new file mode 100644 index 0000000000000000000000000000000000000000..43a49068aedb5e3f536b84437c30066be7b21c17 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_afifo_18x1023.xco @@ -0,0 +1,84 @@ +############################################################## +# +# Xilinx Core Generator version 11.4 +# Date: Mon May 24 18:29:00 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff672 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -12 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 5.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp2_v4_afifo_18x1023 +CSET data_count=false +CSET data_count_width=10 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET enable_reset_synchronization=true +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=1021 +CSET full_threshold_negate_value=1020 +CSET inject_dbit_error=false +CSET inject_sbit_error=false +CSET input_data_width=18 +CSET input_depth=1024 +CSET output_data_width=18 +CSET output_depth=1024 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=10 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=true +CSET write_data_count_width=10 +# END Parameters +GENERATE +# CRC: dc9f4847 diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_fifo_69x512.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_fifo_69x512.xco new file mode 100644 index 0000000000000000000000000000000000000000..c49206eb7cc9b11d2be964569553f0a97df15fdc --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_fifo_69x512.xco @@ -0,0 +1,84 @@ +############################################################## +# +# Xilinx Core Generator version 11.3 +# Date: Fri Jan 15 08:14:17 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff672 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -12 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 5.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp2_v4_fifo_69x512 +CSET data_count=true +CSET data_count_width=9 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET enable_reset_synchronization=true +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=510 +CSET full_threshold_negate_value=509 +CSET inject_dbit_error=false +CSET inject_sbit_error=false +CSET input_data_width=69 +CSET input_depth=512 +CSET output_data_width=69 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=9 +# END Parameters +GENERATE +# CRC: 9d8b647a diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_icon.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_icon.xco new file mode 100644 index 0000000000000000000000000000000000000000..063d1026fce485b417b7f0571993aa10f24f258d --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_icon.xco @@ -0,0 +1,47 @@ +############################################################## +# +# Xilinx Core Generator version 11.4 +# Date: Thu Jun 3 17:09:25 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff672 +SET removerpms = False +SET simulationfiles = Structural +SET speedgrade = -12 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT ICON_(ChipScope_Pro_-_Integrated_Controller) family Xilinx,_Inc. 1.04.a +# END Select +# BEGIN Parameters +CSET component_name=pgp2_v4_icon +CSET enable_jtag_bufg=true +CSET number_control_ports=2 +CSET use_ext_bscan=false +CSET use_softbscan=false +CSET use_unused_bscan=false +CSET user_scan_chain=USER1 +# END Parameters +GENERATE +# CRC: af7581bc diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_ila.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_ila.xco new file mode 100644 index 0000000000000000000000000000000000000000..459f7cf419e82416ed2d068dd7cf5bff394b6ea3 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_ila.xco @@ -0,0 +1,130 @@ +############################################################## +# +# Xilinx Core Generator version 11.4 +# Date: Thu Jun 3 17:13:17 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff672 +SET removerpms = False +SET simulationfiles = Structural +SET speedgrade = -12 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT ILA_(ChipScope_Pro_-_Integrated_Logic_Analyzer) family Xilinx,_Inc. 1.03.a +# END Select +# BEGIN Parameters +CSET component_name=pgp2_v4_ila +CSET counter_width_1=Disabled +CSET counter_width_10=Disabled +CSET counter_width_11=Disabled +CSET counter_width_12=Disabled +CSET counter_width_13=Disabled +CSET counter_width_14=Disabled +CSET counter_width_15=Disabled +CSET counter_width_16=Disabled +CSET counter_width_2=Disabled +CSET counter_width_3=Disabled +CSET counter_width_4=Disabled +CSET counter_width_5=Disabled +CSET counter_width_6=Disabled +CSET counter_width_7=Disabled +CSET counter_width_8=Disabled +CSET counter_width_9=Disabled +CSET data_port_width=64 +CSET data_same_as_trigger=false +CSET enable_storage_qualification=true +CSET enable_trigger_output_port=false +CSET exclude_from_data_storage_1=true +CSET exclude_from_data_storage_10=true +CSET exclude_from_data_storage_11=true +CSET exclude_from_data_storage_12=true +CSET exclude_from_data_storage_13=true +CSET exclude_from_data_storage_14=true +CSET exclude_from_data_storage_15=true +CSET exclude_from_data_storage_16=true +CSET exclude_from_data_storage_2=true +CSET exclude_from_data_storage_3=true +CSET exclude_from_data_storage_4=true +CSET exclude_from_data_storage_5=true +CSET exclude_from_data_storage_6=true +CSET exclude_from_data_storage_7=true +CSET exclude_from_data_storage_8=true +CSET exclude_from_data_storage_9=true +CSET match_type_1=basic +CSET match_type_10=basic +CSET match_type_11=basic +CSET match_type_12=basic +CSET match_type_13=basic +CSET match_type_14=basic +CSET match_type_15=basic +CSET match_type_16=basic +CSET match_type_2=basic +CSET match_type_3=basic +CSET match_type_4=basic +CSET match_type_5=basic +CSET match_type_6=basic +CSET match_type_7=basic +CSET match_type_8=basic +CSET match_type_9=basic +CSET match_units_1=1 +CSET match_units_10=1 +CSET match_units_11=1 +CSET match_units_12=1 +CSET match_units_13=1 +CSET match_units_14=1 +CSET match_units_15=1 +CSET match_units_16=1 +CSET match_units_2=1 +CSET match_units_3=1 +CSET match_units_4=1 +CSET match_units_5=1 +CSET match_units_6=1 +CSET match_units_7=1 +CSET match_units_8=1 +CSET match_units_9=1 +CSET max_sequence_levels=1 +CSET number_of_trigger_ports=1 +CSET sample_data_depth=2048 +CSET sample_on=Rising +CSET trigger_port_width_1=8 +CSET trigger_port_width_10=8 +CSET trigger_port_width_11=8 +CSET trigger_port_width_12=8 +CSET trigger_port_width_13=8 +CSET trigger_port_width_14=8 +CSET trigger_port_width_15=8 +CSET trigger_port_width_16=8 +CSET trigger_port_width_2=8 +CSET trigger_port_width_3=8 +CSET trigger_port_width_4=8 +CSET trigger_port_width_5=8 +CSET trigger_port_width_6=8 +CSET trigger_port_width_7=8 +CSET trigger_port_width_8=8 +CSET trigger_port_width_9=8 +CSET use_rpms=true +# END Parameters +GENERATE +# CRC: a5b91e94 diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_vio.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_vio.xco new file mode 100644 index 0000000000000000000000000000000000000000..7d83f0cc79aeb3eba096e789d15cd1af31519f25 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v4_vio.xco @@ -0,0 +1,50 @@ +############################################################## +# +# Xilinx Core Generator version 11.4 +# Date: Thu Jun 3 17:14:49 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff672 +SET removerpms = False +SET simulationfiles = Structural +SET speedgrade = -12 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT VIO_(ChipScope_Pro_-_Virtual_Input/Output) family Xilinx,_Inc. 1.03.a +# END Select +# BEGIN Parameters +CSET asynchronous_input_port_width=8 +CSET asynchronous_output_port_width=8 +CSET component_name=pgp2_v4_vio +CSET enable_asynchronous_input_port=false +CSET enable_asynchronous_output_port=false +CSET enable_synchronous_input_port=true +CSET enable_synchronous_output_port=true +CSET invert_clock_input=false +CSET synchronous_input_port_width=16 +CSET synchronous_output_port_width=16 +# END Parameters +GENERATE +# CRC: 41fb01be diff --git a/rce/fw-hsio/modules/pgp2/coregen/pgp2_v5_afifo_18x1023.xco b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v5_afifo_18x1023.xco new file mode 100644 index 0000000000000000000000000000000000000000..4dbd8c6110b7256b0b0e5134dd0465d6fdcd75e6 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/coregen/pgp2_v5_afifo_18x1023.xco @@ -0,0 +1,84 @@ +############################################################## +# +# Xilinx Core Generator version 11.4 +# Date: Mon May 24 18:33:50 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = True +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc5vfx30t +SET devicefamily = virtex5 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff665 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -2 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 5.3 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=pgp2_v5_afifo_18x1023 +CSET data_count=false +CSET data_count_width=10 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET enable_reset_synchronization=true +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=1021 +CSET full_threshold_negate_value=1020 +CSET inject_dbit_error=false +CSET inject_sbit_error=false +CSET input_data_width=18 +CSET input_depth=1024 +CSET output_data_width=18 +CSET output_depth=1024 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=10 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=true +CSET write_data_count_width=10 +# END Parameters +GENERATE +# CRC: 46d643bc diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2AppPackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2AppPackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..bcc3e5f215ba879a7b344bcb808d71987f567486 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2AppPackage.vhd @@ -0,0 +1,141 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Applications Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2AppPackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/23/2009 +------------------------------------------------------------------------------- +-- Description: +-- Application Components package. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/23/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2AppPackage is + + -- Register Slave + component Pgp2RegSlave + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + pgpRxClk : in std_logic; -- PGP Clock + pgpRxReset : in std_logic; -- Synchronous PGP Reset + pgpTxClk : in std_logic; -- PGP Clock + pgpTxReset : in std_logic; -- Synchronous PGP Reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + vcFrameTxValid : out std_logic; -- User frame data is valid + vcFrameTxReady : in std_logic; -- PGP is ready + vcFrameTxSOF : out std_logic; -- User frame data start of frame + vcFrameTxEOF : out std_logic; -- User frame data end of frame + vcFrameTxEOFE : out std_logic; -- User frame data error + vcFrameTxData : out std_logic_vector(15 downto 0); -- User frame data + vcRemBuffAFull : in std_logic; -- Remote buffer almost full + vcRemBuffFull : in std_logic; -- Remote buffer full + regInp : out std_logic; -- Register Access In Progress Flag + regReq : out std_logic; -- Register Access Request + regOp : out std_logic; -- Register OpCode, 0=Read, 1=Write + regAck : in std_logic; -- Register Access Acknowledge + regFail : in std_logic; -- Register Access Fail + regAddr : out std_logic_vector(23 downto 0); -- Register Address + regDataOut : out std_logic_vector(31 downto 0); -- Register Data Out + regDataIn : in std_logic_vector(31 downto 0) -- Register Data In + ); + end component; + + -- Register Slave + component Pgp2CmdSlave + generic ( + DestId : natural := 0; -- Destination ID Value To Match + DestMask : natural := 0; -- Destination ID Mask For Match + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + pgpRxClk : in std_logic; -- PGP Clock + pgpRxReset : in std_logic; -- Synchronous PGP Reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + cmdEn : out std_logic; -- Command Enable + cmdOpCode : out std_logic_vector(7 downto 0); -- Command OpCode + cmdCtxOut : out std_logic_vector(23 downto 0) -- Command Context + ); + end component; + + -- Downstream Buffer + component Pgp2DsBuff + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); + end component; + + + -- Upstream Buffer + component Pgp2UsBuff + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + frameTxValid : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + vcFrameTxValid : out std_logic; + vcFrameTxReady : in std_logic; + vcFrameTxSOF : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcRemBuffAFull : in std_logic; + vcRemBuffFull : in std_logic + ); + end component; + +end Pgp2AppPackage; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2CmdSlave.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2CmdSlave.vhd new file mode 100755 index 0000000000000000000000000000000000000000..812a97c777ff981a5d41f26380642653074187ff --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2CmdSlave.vhd @@ -0,0 +1,290 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Command Slave Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2CmdSlave.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/20/2009 +------------------------------------------------------------------------------- +-- Description: +-- Slave block for Command protocol over the PGP. +-- Packet is 16 bytes. The 16 bit values passed over the PGP will be: +-- Word 0 Data[1:0] = VC +-- Word 0 Data[7:2] = Dest_ID +-- Word 0 Data[15:8] = TID[7:0] +-- Word 1 Data[15:0] = TID[23:8] +-- Word 2 Data[7:0] = OpCode[7:0] +-- Word 2 Data[15:8] = Don't Care +-- Word 3 Data[15:0] = Don't Care +-- Word 4 = Don't Care +-- Word 5 = Don't Care +-- Word 6 = Don't Care +-- Word 7 = Don't Care +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/20/2009: created. +-- 05/24/2010: Modified FIFO +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2CmdSlave is + generic ( + DestId : natural := 0; -- Destination ID Value To Match + DestMask : natural := 0; -- Destination ID Mask For Match + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + + -- PGP Rx Clock And Reset + pgpRxClk : in std_logic; -- PGP Clock + pgpRxReset : in std_logic; -- Synchronous PGP Reset + + -- Local clock and reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + + -- PGP Signals, Virtual Channel Rx Only + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + + -- Local command signals + cmdEn : out std_logic; -- Command Enable + cmdOpCode : out std_logic_vector(7 downto 0); -- Command OpCode + cmdCtxOut : out std_logic_vector(23 downto 0) -- Command Context + ); + +end Pgp2CmdSlave; + + +-- Define architecture +architecture Pgp2CmdSlave of Pgp2CmdSlave is + + -- V4 Async FIFO + component pgp2_v4_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- V5 Async FIFO + component pgp2_v5_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- Local Signals + signal intDestId : std_logic_vector(5 downto 0); + signal selDestId : std_logic_vector(5 downto 0); + signal selDestMask : std_logic_vector(5 downto 0); + signal intCmdEn : std_logic; + signal intCmdOpCode : std_logic_vector(7 downto 0); + signal intCmdCtxOut : std_logic_vector(23 downto 0); + signal fifoDin : std_logic_vector(17 downto 0); + signal fifoDout : std_logic_vector(17 downto 0); + signal fifoRd : std_logic; + signal fifoRdDly : std_logic; + signal fifoCount : std_logic_vector(9 downto 0); + signal fifoEmpty : std_logic; + signal locSOF : std_logic; + signal locEOF : std_logic; + signal locEOFE : std_logic; + signal locData : std_logic_vector(15 downto 0); + signal intCnt : std_logic_vector(2 downto 0); + signal intCntEn : std_logic; + signal fifoErr : std_logic; + signal fifoFull : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_black_box of pgp2_v5_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v5_afifo_18x1023 : component is TRUE; + + +begin + + -- Output signal + cmdEn <= intCmdEn; + cmdOpCode <= intCmdOpCode; + cmdCtxOut <= intCmdCtxOut; + + -- Convert destnation ID and Mask + selDestId <= conv_std_logic_vector(DestId,6); + selDestMask <= conv_std_logic_vector(DestMask,6); + + -- Data going into Rx FIFO + fifoDin(17 downto 16) <= "11" when vcFrameRxEOFE = '1' or fifoErr = '1' else + "10" when vcFrameRxEOF = '1' else + "01" when vcFrameRxSOF = '1' else + "00"; + fifoDin(15 downto 0) <= vcFrameRxData; + + -- V4 FIFO + U_GenV4Fifo: if FifoType = "V4" generate + U_CmdV4Fifo: pgp2_v4_afifo_18x1023 port map ( + din => fifoDin, + rd_clk => locClk, + rd_en => fifoRd, + rst => pgpRxReset, + wr_clk => pgpRxClk, + wr_en => vcFrameRxValid, + dout => fifoDout, + empty => fifoEmpty, + full => fifoFull, + wr_data_count => fifoCount + ); + end generate; + + -- V5 FIFO + U_GenV5Fifo: if FifoType = "V5" generate + U_CmdV5Fifo: pgp2_v5_afifo_18x1023 port map ( + din => fifoDin, + rd_clk => locClk, + rd_en => fifoRd, + rst => pgpRxReset, + wr_clk => pgpRxClk, + wr_en => vcFrameRxValid, + dout => fifoDout, + empty => fifoEmpty, + full => fifoFull, + wr_data_count => fifoCount + ); + end generate; + + + -- Data coming out of Rx FIFO + locSOF <= '1' when fifoDout(17 downto 16) = "01" else '0'; + locEOF <= fifoDout(17); + locEOFE <= '1' when fifoDout(17 downto 16) = "11" else '0'; + locData <= fifoDout(15 downto 0); + + -- FIFO Read Control + fifoRd <= not fifoEmpty; + + + -- Generate flow control + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + fifoErr <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Generate full error + if fifoCount >= 1020 or fifoFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at 1/4 capacity + vcLocBuffAFull <= fifoFull or fifoCount(9) or fifoCount(8); + + -- Full at 1/2 capacity + vcLocBuffFull <= fifoFull or fifoCount(9); + end if; + end process; + + + -- Receive Data Processor + process ( locClk, locReset ) begin + if locReset = '1' then + intCmdEn <= '0' after tpd; + intCmdOpCode <= (others=>'0') after tpd; + intCmdCtxOut <= (others=>'0') after tpd; + intDestId <= (others=>'0') after tpd; + fifoRdDly <= '0' after tpd; + intCnt <= (others=>'0') after tpd; + intCntEn <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Generate delayed read + fifoRdDly <= fifoRd after tpd; + + -- Only process when data has been read + if fifoRdDly = '1' then + + -- Receive Data Counter + -- Reset on SOF or EOF, Start counter on SOF + if locSOF = '1' or locEOF = '1' then + intCnt <= (others=>'0') after tpd; + intCntEn <= not locEOF after tpd; + elsif intCntEn = '1' and intCnt /= "110" then + intCnt <= intCnt + 1 after tpd; + end if; + + -- SOF Received + if locSOF = '1' then + intCmdCtxOut(7 downto 0) <= locData(15 downto 8) after tpd; + intDestId <= locData(7 downto 2) after tpd; + intCmdEn <= '0' after tpd; + + -- Rest of Frame + else case intCnt is + + -- Word 1 + when "000" => + intCmdCtxOut(23 downto 8) <= locData after tpd; + intCmdEn <= '0' after tpd; + + -- Word 2 + when "001" => + intCmdOpCode <= locData(7 downto 0) after tpd; + intCmdEn <= '0' after tpd; + + -- Word 7, Last word + when "110" => + + -- No error and destination ID matches + if locEOF = '1' and locEOFE = '0' and + ( intDestId and selDestMask ) = selDestId then + intCmdEn <= '1' after tpd; + else + intCmdEn <= '0' after tpd; + end if; + + -- Do nothing for others + when others => + intCmdEn <= '0' after tpd; + end case; + end if; + else + intCmdEn <= '0' after tpd; + end if; + end if; + end process; + +end Pgp2CmdSlave; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2DsBuff.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2DsBuff.vhd new file mode 100755 index 0000000000000000000000000000000000000000..f92066834010fb21658db3b02aa72a4e56060709 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2DsBuff.vhd @@ -0,0 +1,195 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Downstream Data Buffer +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : Pgp2DsBuff.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/11/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for buffer block for downstream data. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/11/2010: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2DsBuff is + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + + -- Clock and reset + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + + -- PGP Receive Signals + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + + -- Local data transfer signals + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); +end Pgp2DsBuff; + + +-- Define architecture +architecture Pgp2DsBuff of Pgp2DsBuff is + + -- V4 Async FIFO + component pgp2_v4_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- V5 Async FIFO + component pgp2_v5_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- Local Signals + signal rxFifoDin : std_logic_vector(17 downto 0); + signal rxFifoDout : std_logic_vector(17 downto 0); + signal rxFifoRd : std_logic; + signal rxFifoValid : std_logic; + signal rxFifoCount : std_logic_vector(9 downto 0); + signal rxFifoEmpty : std_logic; + signal rxFifoFull : std_logic; + signal fifoErr : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_black_box of pgp2_v5_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v5_afifo_18x1023 : component is TRUE; + +begin + + -- Data going into Rx FIFO + rxFifoDin(17 downto 16) <= "11" when vcFrameRxEOFE = '1' or fifoErr = '1' else + "10" when vcFrameRxEOF = '1' else + "01" when vcFrameRxSOF = '1' else + "00"; + rxFifoDin(15 downto 0) <= vcFrameRxData; + + -- Generate flow control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + fifoErr <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Generate full error + if rxFifoCount >= 1020 or rxFifoFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at 1/4 capacity + vcLocBuffAFull <= rxFifoFull or rxFifoCount(9) or rxFifoCount(8); + + -- Full at 1/2 capacity + vcLocBuffFull <= rxFifoFull or rxFifoCount(9); + end if; + end process; + + -- V4 Receive FIFO + U_GenRxV4Fifo: if FifoType = "V4" generate + U_RegRxV4Fifo: pgp2_v4_afifo_18x1023 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + end generate; + + -- V5 Receive FIFO + U_GenRxV5Fifo: if FifoType = "V5" generate + U_RegRxV5Fifo: pgp2_v5_afifo_18x1023 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + end generate; + + -- Data valid + process ( locClk, locReset ) begin + if locReset = '1' then + rxFifoValid <= '0' after tpd; + elsif rising_edge(locClk) then + if rxFifoRd = '1' then + rxFifoValid <= '1' after tpd; + elsif frameRxReady = '1' then + rxFifoValid <= '0' after tpd; + end if; + end if; + end process; + + -- Control reads + rxFifoRd <= (not rxFifoEmpty) and ((not rxFifoValid) or frameRxReady); + + -- Outgoing signals + frameRxValid <= rxFifoValid; + frameRxSOF <= '1' when rxFifoDout(17 downto 16) = "01" else '0'; + frameRxEOF <= rxFifoDout(17); + frameRxEOFE <= '1' when rxFifoDout(17 downto 16) = "11" else '0'; + frameRxData <= rxFifoDout(15 downto 0); + +end Pgp2DsBuff; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2RegSlave.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2RegSlave.vhd new file mode 100755 index 0000000000000000000000000000000000000000..e07acd7e4ef7f799feaede34adcd1cdcb4642780 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2RegSlave.vhd @@ -0,0 +1,1104 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Register Slave Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2RegSlave.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/20/2009 +------------------------------------------------------------------------------- +-- Description: +-- Slave block for Register protocol over the PGP2. +-- Packet is 16 bytes. The 16 bit values passed over the PGP will be: +-- Word 0 Data[1:0] = VC +-- Word 0 Data[7:2] = Dest_ID +-- Word 0 Data[15:8] = TID[7:0] +-- Word 1 Data[15:0] = TID[23:8] +-- Word 2 Data[15:0] = Address[15:0] +-- Word 3 Data[15:14] = OpCode, 0x0=Read, 0x1=Write, 0x2=Set, 0x3=Clear +-- Word 3 Data[13:8] = Don't Care +-- Word 3 Data[7:0] = Address[23:16] +-- Word 4 Data[15:0] = WriteData0[15:0] or ReadCount[8:0] +-- Word 5 Data[15:0] = WriteData0[31:16] +-- Word N-3 Data[15:0] = WriteData[15:0] +-- Word N-2 Data[15:0] = WriteData[31:16] +-- Word N-1 = Don't Care +-- Word N Data[15:2] = Don't Care +-- Word N Data[1] = Timeout Flag (response data) +-- Word N Data[0] = Fail Flag (response data) +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/20/2009: created. +-- 05/24/2010: Modified FIFO +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2RegSlave is + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + + -- PGP Rx Clock And Reset + pgpRxClk : in std_logic; -- PGP Clock + pgpRxReset : in std_logic; -- Synchronous PGP Reset + + -- PGP Tx Clock And Reset + pgpTxClk : in std_logic; -- PGP Clock + pgpTxReset : in std_logic; -- Synchronous PGP Reset + + -- Local clock and reset + locClk : in std_logic; -- Local Clock + locReset : in std_logic; -- Synchronous Local Reset + + -- PGP Receive Signals + vcFrameRxValid : in std_logic; -- Data is valid + vcFrameRxSOF : in std_logic; -- Data is SOF + vcFrameRxEOF : in std_logic; -- Data is EOF + vcFrameRxEOFE : in std_logic; -- Data is EOF with Error + vcFrameRxData : in std_logic_vector(15 downto 0); -- Data + vcLocBuffAFull : out std_logic; -- Local buffer almost full + vcLocBuffFull : out std_logic; -- Local buffer full + + -- PGP Transmit Signals + vcFrameTxValid : out std_logic; -- User frame data is valid + vcFrameTxReady : in std_logic; -- PGP is ready + vcFrameTxSOF : out std_logic; -- User frame data start of frame + vcFrameTxEOF : out std_logic; -- User frame data end of frame + vcFrameTxEOFE : out std_logic; -- User frame data error + vcFrameTxData : out std_logic_vector(15 downto 0); -- User frame data + vcRemBuffAFull : in std_logic; -- Remote buffer almost full + vcRemBuffFull : in std_logic; -- Remote buffer full + + -- Local register control signals + regInp : out std_logic; -- Register Access In Progress Flag + regReq : out std_logic; -- Register Access Request + regOp : out std_logic; -- Register OpCode, 0=Read, 1=Write + regAck : in std_logic; -- Register Access Acknowledge + regFail : in std_logic; -- Register Access Fail + regAddr : out std_logic_vector(23 downto 0); -- Register Address + regDataOut : out std_logic_vector(31 downto 0); -- Register Data Out + regDataIn : in std_logic_vector(31 downto 0) -- Register Data In + ); + +end Pgp2RegSlave; + + +-- Define architecture +architecture Pgp2RegSlave of Pgp2RegSlave is + + -- V4 Async FIFO + component pgp2_v4_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- V5 Async FIFO + component pgp2_v5_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- Local Signals + signal rxFifoDin : std_logic_vector(17 downto 0); + signal rxFifoDout : std_logic_vector(17 downto 0); + signal rxFifoRd : std_logic; + signal rxFifoCount : std_logic_vector(9 downto 0); + signal rxFifoEmpty : std_logic; + signal rxFifoErr : std_logic; + signal rxFifoFull : std_logic; + signal locRxSOF : std_logic; + signal locRxEOF : std_logic; + signal locRxEOFE : std_logic; + signal locRxData : std_logic_vector(15 downto 0); + signal intAddress : std_logic_vector(23 downto 0); + signal intData : std_logic_vector(31 downto 0); + signal nxtData : std_logic_vector(31 downto 0); + signal intInp : std_logic; + signal nxtInp : std_logic; + signal intReq : std_logic; + signal nxtReq : std_logic; + signal intOp : std_logic; + signal nxtOp : std_logic; + signal intFail : std_logic; + signal nxtFail : std_logic; + signal intTout : std_logic; + signal nxtTout : std_logic; + signal intEOFE : std_logic; + signal nxtEOFE : std_logic; + signal intReqCnt : std_logic_vector(23 downto 0); + signal regStart : std_logic; + signal regDone : std_logic; + signal intWrData : std_logic_vector(31 downto 0); + signal intOpCode : std_logic_vector(1 downto 0); + signal locTxWr : std_logic; + signal nxtTxWr : std_logic; + signal countEn : std_logic; + signal intCount : std_logic_vector(9 downto 0); + signal locTxSOF : std_logic; + signal nxtTxSOF : std_logic; + signal locTxEOF : std_logic; + signal nxtTxEOF : std_logic; + signal locTxEOFE : std_logic; + signal nxtTxEOFE : std_logic; + signal locTxData : std_logic_vector(15 downto 0); + signal nxtTxData : std_logic_vector(15 downto 0); + signal txFifoValid : std_logic; + signal txFifoRd : std_logic; + signal txFifoWr : std_logic; + signal txFifoDout : std_logic_vector(17 downto 0); + signal txFifoDin : std_logic_vector(17 downto 0); + signal txFifoFull : std_logic; + signal txFifoEmpty : std_logic; + signal txFifoAFull : std_logic; + signal txFifoCount : std_logic_vector(9 downto 0); + + -- Master state machine states + signal curState : std_logic_vector(3 downto 0); + signal nxtState : std_logic_vector(3 downto 0); + constant ST_IDLE : std_logic_vector(3 downto 0) := "0001"; + constant ST_HEAD_A : std_logic_vector(3 downto 0) := "0010"; + constant ST_HEAD_B : std_logic_vector(3 downto 0) := "0011"; + constant ST_HEAD_C : std_logic_vector(3 downto 0) := "0100"; + constant ST_HEAD_D : std_logic_vector(3 downto 0) := "0101"; + constant ST_READ : std_logic_vector(3 downto 0) := "0110"; + constant ST_WRITE_A : std_logic_vector(3 downto 0) := "0111"; + constant ST_WRITE_B : std_logic_vector(3 downto 0) := "1000"; + constant ST_REQ : std_logic_vector(3 downto 0) := "1001"; + constant ST_NEXT : std_logic_vector(3 downto 0) := "1010"; + constant ST_DUMP : std_logic_vector(3 downto 0) := "1011"; + constant ST_DONE_A : std_logic_vector(3 downto 0) := "1100"; + constant ST_DONE_B : std_logic_vector(3 downto 0) := "1101"; + + -- Register access states + signal curRegState : std_logic_vector(2 downto 0); + signal nxtRegState : std_logic_vector(2 downto 0); + constant ST_REG_IDLE : std_logic_vector(2 downto 0) := "001"; + constant ST_REG_WRITE : std_logic_vector(2 downto 0) := "010"; + constant ST_REG_READ : std_logic_vector(2 downto 0) := "011"; + constant ST_REG_SET : std_logic_vector(2 downto 0) := "100"; + constant ST_REG_CLEAR : std_logic_vector(2 downto 0) := "101"; + constant ST_REG_WAIT : std_logic_vector(2 downto 0) := "110"; + constant ST_REG_DONE : std_logic_vector(2 downto 0) := "111"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_black_box of pgp2_v5_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v5_afifo_18x1023 : component is TRUE; + +begin + + ------------------------------------- + -- Inbound FIFO + ------------------------------------- + + -- Data going into Rx FIFO + rxFifoDin(17 downto 16) <= "11" when vcFrameRxEOFE = '1' or rxFifoErr = '1' else + "10" when vcFrameRxEOF = '1' else + "01" when vcFrameRxSOF = '1' else + "00"; + rxFifoDin(15 downto 0) <= vcFrameRxData; + + -- V4 Receive FIFO + U_GenRxV4Fifo: if FifoType = "V4" generate + U_RegRxV4Fifo: pgp2_v4_afifo_18x1023 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpRxReset, + wr_clk => pgpRxClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + end generate; + + -- V5 Receive FIFO + U_GenRxV5Fifo: if FifoType = "V5" generate + U_RegRxV5Fifo: pgp2_v5_afifo_18x1023 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpRxReset, + wr_clk => pgpRxClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + end generate; + + -- Data coming out of Rx FIFO + locRxSOF <= '1' when rxFifoDout(17 downto 16) = "01" else '0'; + locRxEOF <= rxFifoDout(17); + locRxEOFE <= '1' when rxFifoDout(17 downto 16) = "11" else '0'; + locRxData <= rxFifoDout(15 downto 0); + + -- Generate flow control + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + rxFifoErr <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Generate full error + if rxFifoCount >= 1020 or rxFifoFull = '1' then + rxFifoErr <= '1' after tpd; + else + rxFifoErr <= '0' after tpd; + end if; + + -- Almost full at 1/4 capacity + vcLocBuffAFull <= rxFifoFull or rxFifoCount(9) or rxFifoCount(8); + + -- Full at 1/2 capacity + vcLocBuffFull <= rxFifoFull or rxFifoCount(9); + end if; + end process; + + + ------------------------------------- + -- Master State Machine + ------------------------------------- + + -- Master State Machine, Sync Logic + process ( locClk, locReset ) begin + if locReset = '1' then + intCount <= (others=>'0') after tpd; + intAddress <= (others=>'0') after tpd; + intOpCode <= (others=>'0') after tpd; + intWrData <= (others=>'0') after tpd; + locTxWr <= '0' after tpd; + locTxSOF <= '0' after tpd; + locTxEOF <= '0' after tpd; + locTxEOFE <= '0' after tpd; + locTxData <= (others=>'0') after tpd; + intEOFE <= '0' after tpd; + curState <= ST_IDLE after tpd; + elsif rising_edge(locClk) then + + -- Length Counter + if curState = ST_READ then + intCount <= locRxData(9 downto 0) after tpd; + elsif countEn = '1' then + intCount <= intCount -1 after tpd; + end if; + + -- Address counter + if curState = ST_HEAD_C then + intAddress(15 downto 0) <= locRxData after tpd; + elsif curState = ST_HEAD_D then + intAddress(23 downto 16) <= locRxData(7 downto 0) after tpd; + elsif countEn = '1' then + intAddress <= intAddress + 1 after tpd; + end if; + + -- Store opcode + if curState = ST_HEAD_D then + intOpCode <= locRxData(15 downto 14) after tpd; + end if; + + -- Write data + if curState = ST_WRITE_A then + intWrData(15 downto 0) <= locRxData after tpd; + elsif curState = ST_WRITE_B then + intWrData(31 downto 16) <= locRxData after tpd; + end if; + + -- EOFE tracker + intEOFE <= nxtEOFE after tpd; + + -- Outbound data + locTxWr <= nxtTxWr after tpd; + locTxSOF <= nxtTxSOF after tpd; + locTxEOF <= nxtTxEOF after tpd; + locTxEOFE <= nxtTxEOFE after tpd; + locTxData <= nxtTxData after tpd; + + -- State transition + curState <= nxtState after tpd; + + end if; + end process; + + + -- Master state engine + process ( curState, rxFifoEmpty, locRxData, locRxSOF, locRxEOF, intEOFE, txFifoAFull, + locRxEOFE, intData, regDone, intTout, intFail, intOpCode, intCount ) begin + + -- States + case curState is + + -- IDLE, Wait for data + when ST_IDLE => + regStart <= '0'; + nxtEOFE <= '0'; + nxtTxWr <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + countEn <= '0'; + + -- Data is ready + if rxFifoEmpty = '0' and txFifoAFull = '0' then + rxFifoRd <= '1'; + nxtState <= ST_HEAD_A; + else + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- Read Header A + when ST_HEAD_A => + regStart <= '0'; + nxtEOFE <= '0'; + nxtTxSOF <= '1'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= locRxData; + countEn <= '0'; + + -- Bad alignment + if locRxSOF = '0' or locRxEOF = '1' then + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= ST_IDLE; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtTxWr <= '1'; + rxFifoRd <= '1'; + nxtState <= ST_HEAD_B; + else + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- Read Header B + when ST_HEAD_B => + regStart <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= locRxData; + countEn <= '0'; + + -- Alignment Error + if locRxSOF = '1' or locRxEOF = '1' then + nxtEOFE <= '1'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= ST_DUMP; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtEOFE <= '0'; + nxtTxWr <= '1'; + rxFifoRd <= '1'; + nxtState <= ST_HEAD_C; + else + nxtEOFE <= '0'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- Read Header C + when ST_HEAD_C => + regStart <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= locRxData; + countEn <= '0'; + + -- Alignment Error + if locRxSOF = '1' or locRxEOF = '1' then + nxtEOFE <= '1'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= ST_DUMP; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtEOFE <= '0'; + nxtTxWr <= '1'; + rxFifoRd <= '1'; + nxtState <= ST_HEAD_D; + else + nxtEOFE <= '0'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- Read Header D + when ST_HEAD_D => + regStart <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= locRxData; + countEn <= '0'; + + -- Alignment Error + if locRxSOF = '1' or locRxEOF = '1' then + nxtEOFE <= '1'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= ST_DUMP; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtEOFE <= '0'; + nxtTxWr <= '1'; + rxFifoRd <= '1'; + + -- Read + if locRxData(15 downto 14) = "00" then + nxtState <= ST_READ; + else + nxtState <= ST_WRITE_A; + end if; + else + nxtEOFE <= '0'; + nxtTxWr <= '0'; + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- Read command, frame word 0 + when ST_READ => + regStart <= '0'; + nxtTxWr <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + countEn <= '0'; + rxFifoRd <= '0'; + + -- Alignment Error + if locRxSOF = '1' or locRxEOF = '1' then + nxtEOFE <= '1'; + nxtState <= ST_DUMP; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtEOFE <= '0'; + nxtState <= ST_REQ; + else + nxtEOFE <= '0'; + nxtState <= curState; + end if; + + -- Low Write Data + when ST_WRITE_A => + regStart <= '0'; + nxtTxWr <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + countEn <= '0'; + + -- Alignment Error + if locRxSOF = '1' or locRxEOF = '1' then + nxtEOFE <= '1'; + rxFifoRd <= '0'; + nxtState <= ST_DUMP; + + -- Data is ready + elsif rxFifoEmpty = '0' then + nxtEOFE <= '0'; + rxFifoRd <= '1'; + nxtState <= ST_WRITE_B; + else + nxtEOFE <= '0'; + rxFifoRd <= '0'; + nxtState <= curState; + end if; + + -- High Write Data + when ST_WRITE_B => + regStart <= '0'; + nxtTxWr <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + countEn <= '0'; + rxFifoRd <= '0'; + + -- Alignment Error + if locRxSOF = '1' then + nxtEOFE <= '1'; + nxtState <= ST_DUMP; + + -- EOF + elsif locRxEOF = '1' then + nxtEOFE <= locRxEOFE; + nxtState <= ST_DONE_A; + + -- Request write cycle + else + nxtEOFE <= '0'; + nxtState <= ST_REQ; + end if; + + -- Transaction Request + when ST_REQ => + regStart <= '1'; + nxtEOFE <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= intData(15 downto 0); + rxFifoRd <= '0'; + countEn <= '0'; + + -- Machine is done, write lower bits of return data + if regDone = '1' then + nxtTxWr <= '1'; + nxtState <= ST_NEXT; + else + nxtTxWr <= '0'; + nxtState <= curState; + end if; + + -- Determine next command, write upper bits of return data + when ST_NEXT => + regStart <= '0'; + nxtEOFE <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= intData(31 downto 16); + + -- An error occured + if intTout = '1' or intFail = '1' then + rxFifoRd <= '0'; + nxtTxWr <= '1'; + countEn <= '0'; + nxtState <= ST_DUMP; + + -- Read command + elsif intOpCode = "00" then + rxFifoRd <= '0'; + + -- Read is done + if intCount = 0 then + nxtTxWr <= '1'; + countEn <= '0'; + nxtState <= ST_DUMP; + + -- Room in transmit FIFO + elsif txFifoAFull = '0' then + nxtTxWr <= '1'; + countEn <= '1'; + nxtState <= ST_REQ; + else + nxtTxWr <= '0'; + countEn <= '0'; + nxtState <= curState; + end if; + + -- Other command, data is ready + elsif rxFifoEmpty = '0' and txFifoAFull = '0' then + rxFifoRd <= '1'; + nxtTxWr <= '1'; + countEn <= '1'; + nxtState <= ST_WRITE_A; + else + rxFifoRd <= '0'; + nxtTxWr <= '0'; + countEn <= '0'; + nxtState <= curState; + end if; + + -- Dump receive data + when ST_DUMP => + regStart <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + nxtTxWr <= '0'; + countEn <= '0'; + + -- Data is done + if locRxEOF = '1' then + nxtEOFE <= intEOFE or locRxEOFE; + rxFifoRd <= '0'; + nxtState <= ST_DONE_A; + else + nxtEOFE <= intEOFE; + rxFifoRd <= not rxFifoEmpty; + nxtState <= curState; + end if; + + -- Done word 0 + when ST_DONE_A => + regStart <= '0'; + nxtEOFE <= intEOFE; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + nxtTxWr <= '1'; + rxFifoRd <= '0'; + countEn <= '0'; + nxtState <= ST_DONE_B; + + -- Done word 1 + when ST_DONE_B => + regStart <= '0'; + nxtEOFE <= intEOFE; + nxtTxSOF <= '0'; + nxtTxEOF <= '1'; + nxtTxEOFE <= intEOFE; + nxtTxData(15 downto 2) <= (others=>'0'); + nxtTxData(1) <= intTout; + nxtTxData(0) <= intFail; + nxtTxWr <= '1'; + rxFifoRd <= '0'; + countEn <= '0'; + nxtState <= ST_IDLE; + + -- default + when others => + regStart <= '0'; + nxtEOFE <= '0'; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxEOFE <= '0'; + nxtTxData <= (others=>'0'); + nxtTxWr <= '0'; + rxFifoRd <= '0'; + countEn <= '0'; + nxtState <= ST_IDLE; + + end case; + end process; + + + ------------------------------------- + -- Outbound FIFO + ------------------------------------- + + -- Data going into tx fifo + process ( locClk, locReset ) begin + if locReset = '1' then + txFifoWr <= '0' after tpd; + txFifoDin <= (others=>'0') after tpd; + txFifoAFull <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Write control + txFifoWr <= locTxWr after tpd; + + -- Write Data + if locTxEOFE = '1' then + txFifoDin(17 downto 16) <= "11" after tpd; + elsif locTxEOF = '1' then + txFifoDin(17 downto 16) <= "10" after tpd; + elsif locTxSOF = '1' then + txFifoDin(17 downto 16) <= "01" after tpd; + else + txFifoDin(17 downto 16) <= "00" after tpd; + end if; + txFifoDin(15 downto 0) <= locTxData; + + -- Almost full + if txFifoCount > 1000 or txFifoFull = '1' then + txFifoAFull <= '1' after tpd; + else + txFifoAFull <= '0' after tpd; + end if; + end if; + end process; + + + -- V4 Transmit FIFO + U_GenTxV4Fifo: if FifoType = "V4" generate + U_RegTxV4Fifo: pgp2_v4_afifo_18x1023 port map ( + din => txFifoDin, + rd_clk => pgpTxClk, + rd_en => txFifoRd, + rst => pgpTxReset, + wr_clk => locClk, + wr_en => txFifoWr, + dout => txFifoDout, + empty => txFifoEmpty, + full => txFifoFull, + wr_data_count => txFifoCount + ); + end generate; + + -- V5 Transmit FIFO + U_GenTxV5Fifo: if FifoType = "V5" generate + U_RegTxV5Fifo: pgp2_v5_afifo_18x1023 port map ( + din => txFifoDin, + rd_clk => pgpTxClk, + rd_en => txFifoRd, + rst => pgpTxReset, + wr_clk => locClk, + wr_en => txFifoWr, + dout => txFifoDout, + empty => txFifoEmpty, + full => txFifoFull, + wr_data_count => txFifoCount + ); + end generate; + + -- Data valid + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + txFifoValid <= '0' after tpd; + elsif rising_edge(pgpTxClk) then + if txFifoRd = '1' then + txFifoValid <= '1' after tpd; + elsif vcFrameTxReady = '1' then + txFifoValid <= '0' after tpd; + end if; + end if; + end process; + + -- Control reads + txFifoRd <= (not txFifoEmpty) and (not vcRemBuffAFull) and (not vcRemBuffFull) and + ((not txFifoValid) or vcframeTxReady); + + -- Outgoing signals + vcFrameTxValid <= txFifoValid; + vcFrameTxSOF <= '1' when txFifoDout(17 downto 16) = "01" else '0'; + vcFrameTxEOF <= txFifoDout(17); + vcFrameTxEOFE <= '1' when txFifoDout(17 downto 16) = "11" else '0'; + vcFrameTxData <= txFifoDout(15 downto 0); + + + ------------------------------------- + -- Register Access Control + ------------------------------------- + + -- Drive address bus + regAddr <= intAddress; + regDataOut <= intData; + regInp <= intInp; + regReq <= intReq; + regOp <= intOp; + + + -- Register State Machine, Sync Logic + process ( locClk, locReset ) begin + if locReset = '1' then + intInp <= '0' after tpd; + intReq <= '0' after tpd; + intOp <= '0' after tpd; + intData <= (others=>'0') after tpd; + intReqCnt <= (others=>'0') after tpd; + intFail <= '0' after tpd; + intTout <= '0' after tpd; + curRegState <= ST_REG_IDLE after tpd; + elsif rising_edge(locClk) then + + -- State transition + curRegState <= nxtRegState after tpd; + + -- Opcode and write data + intInp <= nxtInp after tpd; + intReq <= nxtReq after tpd; + intOp <= nxtOp after tpd; + + -- Data Storage + intData <= nxtData after tpd; + + -- Timeout & fail flags + intFail <= nxtFail after tpd; + intTout <= nxtTout after tpd; + + -- Timeout counter + if intReq <= '0' then + intReqCnt <= (others=>'0') after tpd; + elsif intReqCnt /= x"FFFFFF" then + intReqCnt <= intReqCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Register state engine + process ( curRegState, intWrData, regStart, intOpCode, intData, + regFail, regAck, regDataIn, intReqCnt, intFail, intTout ) begin + + -- States + case curRegState is + + -- IDLE, Wait for enable from read logic + when ST_REG_IDLE => + regDone <= '0'; + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Register data + nxtdata <= intWrData; + + -- Start + if regStart = '1' then + nxtFail <= '0'; + nxtTout <= '0'; + + -- Write Command + if intOpCode = "01" then + nxtRegState <= ST_REG_WRITE; + + -- Read, Set Bit, Clear Bit + else + nxtRegState <= ST_REG_READ; + end if; + else + nxtFail <= intFail; + nxtTout <= intTout; + nxtRegState <= curRegState; + end if; + + -- Write State + when ST_REG_WRITE => + regDone <= '0'; + nxtInp <= '1'; + nxtReq <= '1'; + nxtOp <= '1'; + nxtdata <= intData; + + -- Ack is passed + if regAck = '1' then + + -- Done + nxtRegState <= ST_REG_WAIT; + + -- Store fail flag, no timeout + nxtFail <= regFail; + nxtTout <= '0'; + + -- Timeout + elsif intReqCnt = x"FFFFFF" then + + -- Done + nxtRegState <= ST_REG_WAIT; + + -- No Fail, set timeout + nxtFail <= '0'; + nxtTout <= '1'; + + -- Keep waiting + else + nxtRegState <= curRegState; + nxtFail <= '0'; + nxtTout <= '0'; + end if; + + -- Read State + when ST_REG_READ => + regDone <= '0'; + nxtInp <= '1'; + nxtReq <= '1'; + nxtOp <= '0'; + + -- Take read data + nxtdata <= regDataIn; + + -- Ack is passed + if regAck = '1' then + + -- Fail + if regFail = '1' then + + -- Store fail flag, no timeout, done + nxtFail <= regFail; + nxtTout <= '0'; + nxtRegState <= ST_REG_WAIT; + + -- Normal termination + else + + -- No fail or timeout + nxtFail <= '0'; + nxtTout <= '0'; + + -- Set bit command + if intOpCode = "10" then + nxtRegState <= ST_REG_SET; + + -- Clear bit command + elsif intOpCode = "11" then + nxtRegState <= ST_REG_CLEAR; + + -- Read command + else + nxtRegState <= ST_REG_WAIT; + end if; + end if; + + -- Timeout + elsif intReqCnt = x"FFFFFF" then + + -- done + nxtRegState <= ST_REG_WAIT; + + -- No Fail, set timeout + nxtFail <= '0'; + nxtTout <= '1'; + + -- Keep waiting + else + nxtRegState <= curRegState; + nxtFail <= '0'; + nxtTout <= '0'; + end if; + + -- Set Bit Command + when ST_REG_SET => + regDone <= '0'; + nxtInp <= '1'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Set bits + nxtdata <= intData or intWrData; + + -- No errors + nxtFail <= '0'; + nxtTout <= '0'; + + -- Go to write state + -- Wait for ack from previous command to clear + if regAck = '0' then + nxtRegState <= ST_REG_WRITE; + else + nxtRegState <= curRegState; + end if; + + -- Clear Bit Command + when ST_REG_CLEAR => + regDone <= '0'; + nxtInp <= '1'; + nxtReq <= '0'; + nxtOp <= '0'; + + -- Clear bits + nxtdata <= intData and (not intWrData); + + -- No errors + nxtFail <= '0'; + nxtTout <= '0'; + + -- Go to write state + -- Wait for ack from previous command to clear + if regAck = '0' then + nxtRegState <= ST_REG_WRITE; + else + nxtRegState <= curRegState; + end if; + + -- Done + when ST_REG_WAIT => + regDone <= '0'; + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + nxtdata <= intData; + nxtFail <= intFail; + nxtTout <= intTout; + + -- Wait for ack to clear + if regAck = '0' then + nxtRegState <= ST_REG_DONE; + else + nxtRegState <= curRegState; + end if; + + -- Done + when ST_REG_DONE => + regDone <= '1'; + nxtInp <= '0'; + nxtReq <= '0'; + nxtOp <= '0'; + nxtdata <= intData; + nxtFail <= intFail; + nxtTout <= intTout; + nxtRegState <= ST_REG_IDLE; + + when others => + regDone <= '0'; + nxtReq <= '0'; + nxtInp <= '0'; + nxtOp <= '0'; + nxtdata <= (others=>'0'); + nxtFail <= '0'; + nxtTout <= '0'; + nxtRegState <= ST_REG_IDLE; + end case; + end process; + + --debug(63 downto 59) <= (others=>'0'); + --debug(58) <= countEn; + --debug(57) <= intInp; + --debug(56) <= intReq; + --debug(55) <= intOp; + --debug(54) <= intFail; + --debug(53) <= intTout; + --debug(52) <= intEOFE; + --debug(51) <= regStart; + --debug(50) <= regDone; + --debug(49 downto 48) <= intOpCode; + --debug(47 downto 44) <= curState; + --debug(43 downto 41) <= curRegState; + --debug(40) <= '0'; + --debug(39 downto 24) <= locTxData; + --debug(23 downto 8) <= locRxData; + --debug(7) <= locTxSOF; + --debug(6) <= locTxEOF; + --debug(5) <= locTxEOFE; + --debug(4) <= locRxSOF; + --debug(3) <= locRxEOF; + --debug(2) <= locRxEOFE; + --debug(1) <= locTxWr; + --debug(0) <= rxFifoRd; + + +end Pgp2RegSlave; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2UsBuff.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2UsBuff.vhd new file mode 100755 index 0000000000000000000000000000000000000000..7ea6aaf19cfae8e9488c4837c156198df1ff624e --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/Pgp2UsBuff.vhd @@ -0,0 +1,194 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Upstream Data Buffer +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : Pgp2UsBuff.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/11/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for buffer block for upstream data. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/11/2010: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2UsBuff is + generic ( + FifoType : string := "V5" -- V5 = Virtex 5, V4 = Virtex 4 + ); + port ( + + -- Clock and reset + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + + -- Local data transfer signals + frameTxValid : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + + -- PGP Transmit Signals + vcFrameTxValid : out std_logic; + vcFrameTxReady : in std_logic; + vcFrameTxSOF : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcRemBuffAFull : in std_logic; + vcRemBuffFull : in std_logic + ); +end Pgp2UsBuff; + + +-- Define architecture +architecture Pgp2UsBuff of Pgp2UsBuff is + + -- V4 Async FIFO + component pgp2_v4_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- V5 Async FIFO + component pgp2_v5_afifo_18x1023 port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(9 downto 0)); + end component; + + -- Local Signals + signal txFifoDin : std_logic_vector(17 downto 0); + signal txFifoDout : std_logic_vector(17 downto 0); + signal txFifoRd : std_logic; + signal txFifoCount : std_logic_vector(9 downto 0); + signal txFifoEmpty : std_logic; + signal txFifoFull : std_logic; + signal txFifoValid : std_logic; + signal fifoErr : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v4_afifo_18x1023 : component is TRUE; + attribute syn_black_box of pgp2_v5_afifo_18x1023 : component is TRUE; + attribute syn_noprune of pgp2_v5_afifo_18x1023 : component is TRUE; + +begin + + -- Data going into Tx FIFO + txFifoDin(17 downto 16) <= "11" when frameTxEOFE = '1' or fifoErr = '1' else + "10" when frameTxEOF = '1' else + "01" when frameTxSOF = '1' else + "00"; + txFifoDin(15 downto 0) <= frameTxData; + + -- Generate fifo error signal + process ( locClk, locReset ) begin + if locReset = '1' then + fifoErr <= '0' after tpd; + frameTxAFull <= '0' after tpd; + elsif rising_edge(locClk) then + + -- Generate full error + if txFifoCount >= 1020 or txFifoFull = '1' then + fifoErr <= '1' after tpd; + else + fifoErr <= '0' after tpd; + end if; + + -- Almost full at 1/2 capacity + frameTxAFull <= txFifoFull or txFifoCount(9); + + end if; + end process; + + -- V4 Receive FIFO + U_GenRxV4Fifo: if FifoType = "V4" generate + U_RegRxV4Fifo: pgp2_v4_afifo_18x1023 port map ( + din => txFifoDin, + rd_clk => pgpClk, + rd_en => txFifoRd, + rst => pgpReset, + wr_clk => locClk, + wr_en => frameTxValid, + dout => txFifoDout, + empty => txFifoEmpty, + full => txFifoFull, + wr_data_count => txFifoCount + ); + end generate; + + -- V5 Receive FIFO + U_GenRxV5Fifo: if FifoType = "V5" generate + U_RegRxV5Fifo: pgp2_v5_afifo_18x1023 port map ( + din => txFifoDin, + rd_clk => pgpClk, + rd_en => txFifoRd, + rst => pgpReset, + wr_clk => locClk, + wr_en => frameTxValid, + dout => txFifoDout, + empty => txFifoEmpty, + full => txFifoFull, + wr_data_count => txFifoCount + ); + end generate; + + -- Data valid + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + txFifoValid <= '0' after tpd; + elsif rising_edge(pgpClk) then + if txFifoRd = '1' then + txFifoValid <= '1' after tpd; + elsif vcFrameTxReady = '1' then + txFifoValid <= '0' after tpd; + end if; + end if; + end process; + + -- Control reads + txFifoRd <= (not txFifoEmpty) and (not vcRemBuffAFull) and (not vcRemBuffFull) and + ((not txFifoValid) or vcframeTxReady); + + -- Outgoing signals + vcFrameTxValid <= txFifoValid; + vcFrameTxSOF <= '1' when txFifoDout(17 downto 16) = "01" else '0'; + vcFrameTxEOF <= txFifoDout(17); + vcFrameTxEOFE <= '1' when txFifoDout(17 downto 16) = "11" else '0'; + vcFrameTxData <= txFifoDout(15 downto 0); + +end Pgp2UsBuff; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/PgpDsBuff.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/PgpDsBuff.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e5d350e0a52febcdbb596d5fcfaeced96acacc7b --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/PgpDsBuff.vhd @@ -0,0 +1,150 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Downstream Data Buffer +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : PgpDsBuff.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/11/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for buffer block for downstream data. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/11/2010: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpDsBuff is port ( + + -- Clock and reset + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + + -- PGP Receive Signals + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxWidth : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + + -- Local data transfer signals + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); +end PgpDsBuff; + + +-- Define architecture +architecture PgpDsBuff of PgpDsBuff is + + -- Async Fifo + component pgp_afifo_20x511 port ( + din: IN std_logic_VECTOR(19 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(19 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + wr_data_count: OUT std_logic_VECTOR(8 downto 0)); + end component; + + -- Local Signals + signal rxFifoDin : std_logic_vector(19 downto 0); + signal rxFifoDout : std_logic_vector(19 downto 0); + signal rxFifoRd : std_logic; + signal rxFifoValid : std_logic; + signal rxFifoCount : std_logic_vector(8 downto 0); + signal rxFifoEmpty : std_logic; + signal rxFifoFull : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp_afifo_20x511 : component is TRUE; + attribute syn_noprune of pgp_afifo_20x511 : component is TRUE; + +begin + + -- Data going into Rx FIFO + rxFifoDin(19) <= '0'; + rxFifoDin(18) <= vcFrameRxSOF; + rxFifoDin(17) <= vcFrameRxEOF; + rxFifoDin(16) <= vcFrameRxEOFE; + rxFifoDin(15 downto 0) <= vcFrameRxData; + + -- Generate flow control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Almost full at quarter capacity + --vcLocBuffAFull <= rxFifoCount(8); + vcLocBuffAFull <= rxFifoCount(8) or rxFifoCount(7); + + -- Full at half capacity + vcLocBuffFull <= rxFifoFull or rxFifoCount(8); + end if; + end process; + + -- Async FIFO + U_RegRxAFifo: pgp_afifo_20x511 port map ( + din => rxFifoDin, + rd_clk => locClk, + rd_en => rxFifoRd, + rst => pgpReset, + wr_clk => pgpClk, + wr_en => vcFrameRxValid, + dout => rxFifoDout, + empty => rxFifoEmpty, + full => rxFifoFull, + wr_data_count => rxFifoCount + ); + + -- Data valid + process ( locClk, locReset ) begin + if locReset = '1' then + rxFifoValid <= '0' after tpd; + elsif rising_edge(locClk) then + if rxFifoRd = '1' then + rxFifoValid <= '1' after tpd; + elsif frameRxReady = '1' then + rxFifoValid <= '0' after tpd; + end if; + end if; + end process; + + -- Control reads + rxFifoRd <= (not rxFifoEmpty) and ((not rxFifoValid) or frameRxReady); + + -- Outgoing signals + frameRxValid <= rxFifoValid; + frameRxSOF <= rxFifoDout(18); + frameRxEOF <= rxFifoDout(17); + frameRxEOFE <= rxFifoDout(16); + frameRxData <= rxFifoDout(15 downto 0); + +end PgpDsBuff; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/applications/PgpFrontEnd.vhd b/rce/fw-hsio/modules/pgp2/hdl/applications/PgpFrontEnd.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2cf085271eeefd535dbe443c4814f7aadee419f4 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/applications/PgpFrontEnd.vhd @@ -0,0 +1,630 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol Applications, Front End Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : PgpFrontEnd.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/24/2007 +------------------------------------------------------------------------------- +-- Description: +-- Wrapper for front end logic connection to the RCE. +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/24/2007: created. +-- 03/06/2008: Removed width signal. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use work.Version.all; +use work.Pgp2MgtPackage.all; +use work.Pgp2AppPackage.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity PgpFrontEnd is + generic ( + MgtMode : string := "A"; -- Default Location + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + + -- Reference Clock, PGP Clock & Reset Signals + -- Use one ref clock, tie other to 0, see RefClkSel above + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + mgtRxRecClk : out std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- Display Digits + pgpDispA : out std_logic_vector(7 downto 0); + pgpDispB : out std_logic_vector(7 downto 0); + + -- Reset output + resetOut : out std_logic; + + -- Local clock and reset + locClk : in std_logic; + locReset : in std_logic; + + -- Local command signal + cmdEn : out std_logic; + cmdOpCode : out std_logic_vector(7 downto 0); + cmdCtxOut : out std_logic_vector(23 downto 0); + + -- Local register control signals + regReq : out std_logic; + regOp : out std_logic; + regInp : out std_logic; + regAck : in std_logic; + regFail : in std_logic; + regAddr : out std_logic_vector(23 downto 0); + regDataOut : out std_logic_vector(31 downto 0); + regDataIn : in std_logic_vector(31 downto 0); + + -- Local data transfer signals + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + frameTxAFull : out std_logic; + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0); + valid : out std_logic; + eof : out std_logic; + sof : out std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + + -- MGT Signals For Simulation, + -- Drive mgtCombusIn to 0's, Leave mgtCombusOut open for real use + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); +end PgpFrontEnd; + + +-- Define architecture +architecture PgpFrontEnd of PgpFrontEnd is + + -- Downstream buffer + component PgpDsBuff + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + locClk : in std_logic; + locReset : in std_logic; + vcFrameRxValid : in std_logic; + vcFrameRxSOF : in std_logic; + vcFrameRxWidth : in std_logic; + vcFrameRxEOF : in std_logic; + vcFrameRxEOFE : in std_logic; + vcFrameRxData : in std_logic_vector(15 downto 0); + vcLocBuffAFull : out std_logic; + vcLocBuffFull : out std_logic; + frameRxValid : out std_logic; + frameRxReady : in std_logic; + frameRxSOF : out std_logic; + frameRxEOF : out std_logic; + frameRxEOFE : out std_logic; + frameRxData : out std_logic_vector(15 downto 0) + ); + end component; + + -- Local Signals + signal pibReLink : std_logic; + signal vc0FrameTxValid : std_logic; + signal vc0FrameTxReady : std_logic; + signal vc0FrameTxSOF : std_logic; + signal vc0FrameTxEOF : std_logic; + signal vc0FrameTxEOFE : std_logic; + signal vc0FrameTxData : std_logic_vector(15 downto 0); + signal vc0RemBuffAFull : std_logic; + signal vc0RemBuffFull : std_logic; + signal vc1FrameTxValid : std_logic; + signal vc1FrameTxReady : std_logic; + signal vc1FrameTxSOF : std_logic; + signal vc1FrameTxEOF : std_logic; + signal vc1FrameTxEOFE : std_logic; + signal vc1FrameTxData : std_logic_vector(15 downto 0); + signal vc1RemBuffAFull : std_logic; + signal vc1RemBuffFull : std_logic; + signal vc2FrameTxValid : std_logic; + signal vc2FrameTxReady : std_logic; + signal vc2FrameTxSOF : std_logic; + signal vc2FrameTxEOF : std_logic; + signal vc2FrameTxEOFE : std_logic; + signal vc2FrameTxData : std_logic_vector(15 downto 0); + signal vc2RemBuffAFull : std_logic; + signal vc2RemBuffFull : std_logic; + signal vc3FrameTxValid : std_logic; + signal vc3FrameTxReady : std_logic; + signal vc3FrameTxSOF : std_logic; + signal vc3FrameTxEOF : std_logic; + signal vc3FrameTxEOFE : std_logic; + signal vc3FrameTxData : std_logic_vector(15 downto 0); + signal vc3RemBuffAFull : std_logic; + signal vc3RemBuffFull : std_logic; + signal vc0FrameRxValid : std_logic; + signal vcFrameRxSOF : std_logic; + signal vcFrameRxEOF : std_logic; + signal vcFrameRxEOFE : std_logic; + signal vcFrameRxData : std_logic_vector(15 downto 0); + signal vc0LocBuffAFull : std_logic; + signal vc0LocBuffFull : std_logic; + signal vc1FrameRxValid : std_logic; + signal vc1LocBuffAFull : std_logic; + signal vc1LocBuffFull : std_logic; + signal vc2FrameRxValid : std_logic; + signal vc2LocBuffAFull : std_logic; + signal vc2LocBuffFull : std_logic; + signal vc3FrameRxValid : std_logic; + signal vc3LocBuffAFull : std_logic; + signal vc3LocBuffFull : std_logic; + signal pibLock : std_logic_vector(1 downto 0); + signal countLinkDown : std_logic; + signal countLinkError : std_logic; + signal countCellError : std_logic; + signal cntLinkError : std_logic_vector(3 downto 0); + signal cntCellError : std_logic_vector(3 downto 0); + signal cntLinkDown : std_logic_vector(3 downto 0); + signal cntOverFlow : std_logic_vector(3 downto 0); + signal pllLock : std_logic; + signal pllLockDly : std_logic; + signal cntPllLock : std_logic_vector(3 downto 0); + signal intRegReq : std_logic; + signal intRegOp : std_logic; + signal intRegAck : std_logic; + signal intRegFail : std_logic; + signal intRegAddr : std_logic_vector(23 downto 0); + signal intRegDataOut : std_logic_vector(31 downto 0); + signal intRegDataIn : std_logic_vector(31 downto 0); + signal intCmdEn : std_logic; + signal intCmdOpCode : std_logic_vector(7 downto 0); + signal intCmdCtxOut : std_logic_vector(23 downto 0); + signal scratchPad : std_logic_vector(31 downto 0); + signal countReset : std_logic; + signal dataOverFlow : std_logic; + signal intCmdAFull : std_logic; + signal intCmdFull : std_logic; + signal extCmdAFull : std_logic; + signal extCmdFull : std_logic; + signal pibError : std_logic; + signal txCount : std_logic_vector(31 downto 0); + signal pibLinkReady : std_logic; + signal iframeTxAFull : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Display values + pgpDispB <= x"0" & txCount(3 downto 0); + pgpDispA <= x"10" when pllLock = '0' else -- Display 'P' + x"11" when pibLinkReady = '0' else -- Display 'N' + x"0E" when pibError = '1' else -- Display 'E' + x"12"; -- Display 'L' + + -- Detect error status + pibError <= '1' when (cntLinkError & cntCellError) /= 0 else '0'; + + -- Transaction Counter + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + txCount <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + if pibLinkReady = '0' then + txCount <= (others=>'0') after tpd; + else + if (vc0FrameTxReady = '1' and vc0FrameTxEOF = '1') or + (vc1FrameTxReady = '1' and vc1FrameTxEOF = '1') or + (vc2FrameTxReady = '1' and vc2FrameTxEOF = '1') or + (vc3FrameTxReady = '1' and vc3FrameTxEOF = '1') then + txCount <= txCount + 1 after tpd; + end if; + end if; + end if; + end process; + + + -- Register read and write + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intRegDataIn <= (others=>'0') after tpd; + intRegAck <= '0' after tpd; + intRegFail <= '0' after tpd; + scratchPad <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Register request is pending + if intRegReq = '1' then + + -- Drive ack + intRegAck <= '1' after tpd; + + -- Read + if intRegOp = '0' then + + -- Which register + case intRegAddr is + + when x"000000" => + intRegDataIn <= FpgaVersion after tpd; + intRegFail <= '0' after tpd; + + when x"000001" => + intRegDataIn <= scratchPad after tpd; + intRegFail <= '0' after tpd; + + when x"000002" => + intRegDataIn(31) <= '0' after tpd; + intRegDataIn(30) <= '0' after tpd; + intRegDataIn(29) <= '0' after tpd; + intRegDataIn(28) <= '0' after tpd; + intRegDataIn(27 downto 24) <= cntOverFlow after tpd; + intRegDataIn(23 downto 20) <= cntPllLock after tpd; + intRegDataIn(19 downto 16) <= cntLinkDown after tpd; + intRegDataIn(15 downto 12) <= cntLinkError after tpd; + intRegDataIn(11 downto 8) <= (others=>'0') after tpd; + intRegDataIn( 7 downto 4) <= cntCellError after tpd; + intRegDataIn( 3 downto 0) <= "0000" after tpd; + intRegFail <= '0' after tpd; + + when x"000003" => + intRegDataIn <= txCount after tpd; + intRegFail <= '0' after tpd; + + when others => + intRegFail <= '1' after tpd; + intRegDataIn <= (others=>'0') after tpd; + end case; + + -- Write + else + + -- Scratchpad write + if intRegAddr = x"000001" then + intRegFail <= '0' after tpd; + scratchPad <= intRegDataOut after tpd; + else + intRegFail <= '1' after tpd; + end if; + end if; + + -- No Request + else + intRegAck <= '0' after tpd; + intRegFail <= '0' after tpd; + intRegDataIn <= (others=>'0') after tpd; + end if; + end if; + end process; + + + -- Internal command receiver + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + resetOut <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Internal command received + if intCmdEn = '1' then + + -- Reset + if intCmdOpCode = "00000000" then + resetOut <= '1' after tpd; + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + + -- Count Reset + elsif intCmdOpCode = "00000001" then + countReset <= '1' after tpd; + pibReLink <= '0' after tpd; + + -- PGP Relink + elsif intCmdOpCode = "00000010" then + countReset <= '0' after tpd; + pibReLink <= '1' after tpd; + + else + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + end if; + else + countReset <= '0' after tpd; + pibReLink <= '0' after tpd; + end if; + end if; + end process; + + + -- Error Counters + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + cntLinkError <= (others=>'0') after tpd; + cntCellError <= (others=>'0') after tpd; + cntLinkDown <= (others=>'0') after tpd; + cntPllLock <= (others=>'0') after tpd; + cntOverFlow <= (others=>'0') after tpd; + pllLock <= '0' after tpd; + pllLockDly <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Link Error Counter, 8-bits + if countReset = '1' or pibLinkReady = '0' then + cntLinkError <= (others=>'0') after tpd; + elsif countLinkError = '1' and cntLinkError /= x"F" then + cntLinkError <= cntLinkError + 1 after tpd; + end if; + + -- Cell Error Counter, 8-bits + if countReset = '1' or pibLinkReady = '0' then + cntCellError <= (others=>'0') after tpd; + elsif countCellError = '1' and cntCellError /= x"F" then + cntCellError <= cntCellError + 1 after tpd; + end if; + + -- Link Down Counter, 8-bits + if countReset = '1' then + cntLinkDown <= (others=>'0') after tpd; + elsif countLinkDown = '1' and cntLinkDown /= x"F" then + cntLinkDown <= cntLinkDown + 1 after tpd; + end if; + + -- PLL Unlock Counter + if countReset = '1' or pibLinkReady = '0' then + cntPllLock <= (others=>'0') after tpd; + elsif pllLock = '0' and pllLockDly = '1' and cntPllLock /= x"F" then + cntPllLock <= cntPllLock + 1 after tpd; + end if; + + -- PLL Lock Edge Detection + pllLock <= pibLock(1) and pibLock(0) after tpd; + pllLockDly <= pllLock after tpd; + + -- Data overflow counter + if countReset = '1' then + cntOverFlow <= (others=>'0') after tpd; + elsif dataOverFlow = '1'and cntOverFlow /= x"F" then + cntOverFlow <= cntOverFlow + 1 after tpd; + end if; + + end if; + end process; + + -- PGP Wrap + U_Pgp2Mgt16: Pgp2Mgt16 + generic map ( + EnShortCells => 1, + VcInterleave => 0, + MgtMode => MgtMode, + RefClkSel => RefClkSel + ) + port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pgpFlush => '0', + pllTxRst => '0', + pllRxRst => pibReLink, + pllRxReady => pibLock(0), + pllTxReady => pibLock(1), + pgpRemData => open, + pgpLocData => (others=>'0'), + pgpTxOpCodeEn => '0', + pgpTxOpCode => (others=>'0'), + pgpRxOpCodeEn => open, + pgpRxOpCode => open, + pgpLocLinkReady => pibLinkReady, + pgpRemLinkReady => open, + pgpRxCellError => countCellError, + pgpRxLinkDown => countLinkDown, + pgpRxLinkError => countLinkError, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + mgtLoopback => '0', + mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, + mgtRxRecClk => mgtRxRecClk, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, + mgtTxN => mgtTxN, + mgtTxP => mgtTxP, + mgtCombusIn => mgtCombusIn, + mgtCombusOut => mgtCombusOut, + debug => open + ); + + -- Lane 0, VC0, External command processor + U_ExtCmd: Pgp2CmdSlave + generic map ( + DestId => 0, + DestMask => 1, + FifoType => "V4" + ) port map ( + pgpRxClk => pgpClk, pgpRxReset => pgpReset, + locClk => locClk, locReset => locReset, + vcFrameRxValid => vc0FrameRxValid, vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, vcLocBuffAFull => extCmdAFull, + vcLocBuffFull => extCmdFull, cmdEn => cmdEn, + cmdOpCode => cmdOpCode, cmdCtxOut => cmdCtxOut + ); + + -- Lane 0, VC0, Internal command processor + U_IntCmd: Pgp2CmdSlave + generic map ( + DestId => 1, + DestMask => 1, + FifoType => "V4" + ) port map ( + pgpRxClk => pgpClk, pgpRxReset => pgpReset, + locClk => pgpClk, locReset => pgpReset, + vcFrameRxValid => vc0FrameRxValid, vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, vcLocBuffAFull => intCmdAFull, + vcLocBuffFull => intCmdFull, cmdEn => intCmdEn, + cmdOpCode => intCmdOpCode, cmdCtxOut => intCmdCtxOut + ); + + -- Generate flow control + vc0LocBuffAFull <= extCmdAFull or intCmdAFull; + vc0LocBuffFull <= extCmdFull or intCmdFull; + + -- Return data, Lane 0, VC0 + U_DataBuff0: Pgp2UsBuff generic map ( FifoType => "V4" ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + locClk => locClk, + locReset => locReset, + frameTxValid => frameTxEnable, + frameTxSOF => frameTxSOF, + frameTxEOF => frameTxEOF, + frameTxEOFE => frameTxEOFE, + frameTxData => frameTxData, + frameTxAFull => iframeTxAFull, + vcFrameTxValid => vc0FrameTxValid, + vcFrameTxReady => vc0FrameTxReady, + vcFrameTxSOF => vc0FrameTxSOF, + vcFrameTxEOF => vc0FrameTxEOF, + vcFrameTxEOFE => vc0FrameTxEOFE, + vcFrameTxData => vc0FrameTxData, + vcRemBuffAFull => vc0RemBuffAFull, + vcRemBuffFull => vc0RemBuffFull + ); + dataOverFlow <= frameTxEnable and iframeTxAFull; + frameTxAFull <= iframeTxAFull; + + valid <= vc0FrameTxValid; + eof <= vc0FrameTxEOF; + sof <= vc0FrameTxSOF; + + -- Lane 0, VC1, External register access control + U_ExtReg: Pgp2RegSlave generic map ( FifoType => "V4" ) port map ( + pgpRxClk => pgpClk, pgpRxReset => pgpReset, + pgpTxClk => pgpClk, pgpTxReset => pgpReset, + locClk => locClk, locReset => locReset, + vcFrameRxValid => vc1FrameRxValid, vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, vcLocBuffAFull => vc1LocBuffAFull, + vcLocBuffFull => vc1LocBuffFull, vcFrameTxValid => vc1FrameTxValid, + vcFrameTxReady => vc1FrameTxReady, vcFrameTxSOF => vc1FrameTxSOF, + vcFrameTxEOF => vc1FrameTxEOF, vcFrameTxEOFE => vc1FrameTxEOFE, + vcFrameTxData => vc1FrameTxData, vcRemBuffAFull => vc1RemBuffAFull, + vcRemBuffFull => vc1RemBuffFull, regInp => regInp, + regReq => regReq, regOp => regOp, + regAck => regAck, regFail => regFail, + regAddr => regAddr, regDataOut => regDataOut, + regDataIn => regDataIn + ); + + -- Lane 0, VC2, Internal register access control + U_IntReg: Pgp2RegSlave generic map ( FifoType => "V4" ) port map ( + pgpRxClk => pgpClk, pgpRxReset => pgpReset, + pgpTxClk => pgpClk, pgpTxReset => pgpReset, + locClk => pgpClk, locReset => pgpReset, + vcFrameRxValid => vc2FrameRxValid, vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, vcLocBuffAFull => vc2LocBuffAFull, + vcLocBuffFull => vc2LocBuffFull, vcFrameTxValid => vc2FrameTxValid, + vcFrameTxReady => vc2FrameTxReady, vcFrameTxSOF => vc2FrameTxSOF, + vcFrameTxEOF => vc2FrameTxEOF, vcFrameTxEOFE => vc2FrameTxEOFE, + vcFrameTxData => vc2FrameTxData, vcRemBuffAFull => vc2RemBuffAFull, + vcRemBuffFull => vc2RemBuffFull, regInp => open, + regReq => intRegReq, regOp => intRegOp, + regAck => intRegAck, regFail => intRegFail, + regAddr => intRegAddr, regDataOut => intRegDataOut, + regDataIn => intRegDataIn + ); + + -- VC3, Downstream data + U_DsBuff: Pgp2DsBuff generic map ( FifoType => "V4" ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + locClk => locClk, + locReset => locReset, + vcFrameRxValid => vc3FrameRxValid, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vcLocBuffAFull => vc3LocBuffAFull, + vcLocBuffFull => vc3LocBuffFull, + frameRxValid => frameRxValid, + frameRxReady => frameRxReady, + frameRxSOF => frameRxSOF, + frameRxEOF => frameRxEOF, + frameRxEOFE => frameRxEOFE, + frameRxData => frameRxData + ); + + -- VC3 transmit is unused + vc3FrameTxValid <= '0'; + vc3FrameTxEOFE <= '0'; + vc3FrameTxEOF <= '0'; + vc3FrameTxSOF <= '0'; + vc3FrameTxData <= (others=>'0'); + +end PgpFrontEnd; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2CorePackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2CorePackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..7caf28fa044b9e8afec83c67232d88ee47e953fb --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2CorePackage.vhd @@ -0,0 +1,341 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, Core Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2CorePackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/27/2009 +------------------------------------------------------------------------------- +-- Description: +-- PGP ID and other global constants. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/27/2009: created. +-- 11/23/2009: Renamed package. +-- 12/13/2010: Added received init line to help linking. +-- 06/25/2010: Added payload size config as generic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2CorePackage is + + -- 8B10B Characters + constant K_COM : std_logic_vector(7 downto 0) := "10111100"; -- K28.5, 0xBC + constant K_LTS : std_logic_vector(7 downto 0) := "00111100"; -- K28.1, 0x3C + constant D_102 : std_logic_vector(7 downto 0) := "01001010"; -- D10.2, 0x4A + constant D_215 : std_logic_vector(7 downto 0) := "10110101"; -- D21.5, 0xB5 + constant K_SKP : std_logic_vector(7 downto 0) := "00011100"; -- K28.0, 0x1C + constant K_OTS : std_logic_vector(7 downto 0) := "01111100"; -- K28.3, 0x7C + constant K_ALN : std_logic_vector(7 downto 0) := "11011100"; -- K28.6, 0xDC + constant K_SOC : std_logic_vector(7 downto 0) := "11111011"; -- K27.7, 0xFB + constant K_SOF : std_logic_vector(7 downto 0) := "11110111"; -- K23.7, 0xF7 + constant K_EOF : std_logic_vector(7 downto 0) := "11111101"; -- K29.7, 0xFD + constant K_EOFE : std_logic_vector(7 downto 0) := "11111110"; -- K30.7, 0xFE + constant K_EOC : std_logic_vector(7 downto 0) := "01011100"; -- K28.2, 0x5C + + -- ID Constant + constant Pgp2Id : std_logic_vector(3 downto 0) := "0101"; + + -- PGP Receive Core + component Pgp2Rx + generic ( + RxLaneCnt : integer := 4; + EnShortCells : integer := 1; + PayloadCntTop : integer := 7 + ); + port ( + pgpRxClk : in std_logic; + pgpRxReset : in std_logic; + pgpRxFlush : in std_logic; + pgpRxLinkReady : out std_logic; + pgpRxCellError : out std_logic; + pgpRxLinkDown : out std_logic; + pgpRxLinkError : out std_logic; + pgpRxOpCodeEn : out std_logic; + pgpRxOpCode : out std_logic_vector(7 downto 0); + pgpRemLinkReady : out std_logic; + pgpRemData : out std_logic_vector(7 downto 0); + vcFrameRxSOF : out std_logic; + vcFrameRxEOF : out std_logic; + vcFrameRxEOFE : out std_logic; + vcFrameRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); + vc0FrameRxValid : out std_logic; + vc0RemBuffAFull : out std_logic; + vc0RemBuffFull : out std_logic; + vc1FrameRxValid : out std_logic; + vc1RemBuffAFull : out std_logic; + vc1RemBuffFull : out std_logic; + vc2FrameRxValid : out std_logic; + vc2RemBuffAFull : out std_logic; + vc2RemBuffFull : out std_logic; + vc3FrameRxValid : out std_logic; + vc3RemBuffAFull : out std_logic; + vc3RemBuffFull : out std_logic; + phyRxPolarity : out std_logic_vector(RxLaneCnt-1 downto 0); + phyRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); + phyRxDataK : in std_logic_vector(RxLaneCnt*2-1 downto 0); + phyRxDispErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); + phyRxDecErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); + phyRxReady : in std_logic; + phyRxInit : out std_logic; + crcRxIn : out std_logic_vector(RxLaneCnt*16-1 downto 0); + crcRxWidth : out std_logic; + crcRxInit : out std_logic; + crcRxValid : out std_logic; + crcRxOut : in std_logic_vector(31 downto 0); + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- PGP Transmit Core + component Pgp2Tx + generic ( + TxLaneCnt : integer := 4; + VcInterleave : integer := 1; + PayloadCntTop : integer := 7 + ); + port ( + pgpTxClk : in std_logic; + pgpTxReset : in std_logic; + pgpTxFlush : in std_logic; + pgpTxLinkReady : out std_logic; + pgpTxOpCodeEn : in std_logic; + pgpTxOpCode : in std_logic_vector(7 downto 0); + pgpLocLinkReady : in std_logic; + pgpLocData : in std_logic_vector(7 downto 0); + vc0FrameTxValid : in std_logic; + vc0FrameTxReady : out std_logic; + vc0FrameTxSOF : in std_logic; + vc0FrameTxEOF : in std_logic; + vc0FrameTxEOFE : in std_logic; + vc0FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); + vc0LocBuffAFull : in std_logic; + vc0LocBuffFull : in std_logic; + vc1FrameTxValid : in std_logic; + vc1FrameTxReady : out std_logic; + vc1FrameTxSOF : in std_logic; + vc1FrameTxEOF : in std_logic; + vc1FrameTxEOFE : in std_logic; + vc1FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); + vc1LocBuffAFull : in std_logic; + vc1LocBuffFull : in std_logic; + vc2FrameTxValid : in std_logic; + vc2FrameTxReady : out std_logic; + vc2FrameTxSOF : in std_logic; + vc2FrameTxEOF : in std_logic; + vc2FrameTxEOFE : in std_logic; + vc2FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); + vc2LocBuffAFull : in std_logic; + vc2LocBuffFull : in std_logic; + vc3FrameTxValid : in std_logic; + vc3FrameTxReady : out std_logic; + vc3FrameTxSOF : in std_logic; + vc3FrameTxEOF : in std_logic; + vc3FrameTxEOFE : in std_logic; + vc3FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); + vc3LocBuffAFull : in std_logic; + vc3LocBuffFull : in std_logic; + phyTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); + phyTxDataK : out std_logic_vector(TxLaneCnt*2-1 downto 0); + phyTxReady : in std_logic; + crcTxIn : out std_logic_vector(TxLaneCnt*16-1 downto 0); + crcTxInit : out std_logic; + crcTxValid : out std_logic; + crcTxOut : in std_logic_vector(31 downto 0); + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- Phy Interface + component Pgp2RxPhy + generic ( + RxLaneCnt : integer := 4 -- Number of receive lanes, 1-4 + ); + port ( + pgpRxClk : in std_logic; -- Master clock + pgpRxReset : in std_logic; -- Synchronous reset input + pgpRxLinkReady : out std_logic; -- Local side has link + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + cellRxPause : out std_logic; -- Cell data pause + cellRxSOC : out std_logic; -- Cell data start of cell + cellRxSOF : out std_logic; -- Cell data start of frame + cellRxEOC : out std_logic; -- Cell data end of cell + cellRxEOF : out std_logic; -- Cell data end of frame + cellRxEOFE : out std_logic; -- Cell data end of frame error + cellRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- Cell data data + phyRxPolarity : out std_logic_vector(RxLaneCnt-1 downto 0); -- PHY receive signal polarity + phyRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyRxDispErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data has disparity error + phyRxDecErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data not in table + phyRxReady : in std_logic; -- PHY receive interface is ready + phyRxInit : out std_logic; + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- Cell Receiver + component Pgp2RxCell + generic ( + RxLaneCnt : integer := 4; + EnShortCells : integer := 1; + PayloadCntTop : integer := 7 + ); + port ( + pgpRxClk : in std_logic; -- Master clock + pgpRxReset : in std_logic; -- Synchronous reset input + pgpRxFlush : in std_logic; -- Flush the link + pgpRxLinkReady : in std_logic; -- Local side has link + pgpRxCellError : out std_logic; -- A cell error has occured + cellRxPause : in std_logic; -- Cell data pause + cellRxSOC : in std_logic; -- Cell data start of cell + cellRxSOF : in std_logic; -- Cell data start of frame + cellRxEOC : in std_logic; -- Cell data end of cell + cellRxEOF : in std_logic; -- Cell data end of frame + cellRxEOFE : in std_logic; -- Cell data end of frame error + cellRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); -- Cell data data + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + crcRxIn : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- Receive data for CRC + crcRxWidth : out std_logic; -- Receive CRC width, 1=full, 0=32-bit + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxOut : in std_logic_vector(31 downto 0) -- Receive calculated CRC value + ); + end component; + + -- Phy Interface + component Pgp2TxPhy + generic ( + TxLaneCnt : integer := 4 -- Number of receive lanes, 1-4 + ); + port ( + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + pgpTxLinkReady : out std_logic; -- Local side has link + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : in std_logic; -- Far end side has link + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + cellTxSOC : in std_logic; -- Cell data start of cell + cellTxSOF : in std_logic; -- Cell data start of frame + cellTxEOC : in std_logic; -- Cell data end of cell + cellTxEOF : in std_logic; -- Cell data end of frame + cellTxEOFE : in std_logic; -- Cell data end of frame error + cellTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- Cell data data + phyTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- PHY receive data + phyTxDataK : out std_logic_vector(TxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyTxReady : in std_logic; -- PHY receive interface is ready + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- Cell Transmit Block + component Pgp2TxCell + generic ( + TxLaneCnt : integer := 4; + PayloadCntTop : integer := 7 + ); + port ( + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + pgpTxLinkReady : in std_logic; -- Local side has link + cellTxSOC : out std_logic; -- Cell data start of cell + cellTxSOF : out std_logic; -- Cell data start of frame + cellTxEOC : out std_logic; -- Cell data end of cell + cellTxEOF : out std_logic; -- Cell data end of frame + cellTxEOFE : out std_logic; -- Cell data end of frame error + cellTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- Cell data data + schTxSOF : out std_logic; -- Cell contained SOF + schTxEOF : out std_logic; -- Cell contained EOF + schTxIdle : in std_logic; -- Force IDLE transmit + schTxReq : in std_logic; -- Cell transmit request + schTxAck : out std_logic; -- Cell transmit acknowledge + schTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + crcTxIn : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxOut : in std_logic_vector(31 downto 0) -- Transmit calculated CRC value + ); + end component; + + -- Scheduler + component Pgp2TxSched + generic ( + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + pgpTxFlush : in std_logic; -- Transmit state flush + pgpTxLinkReady : in std_logic; -- Local side has link + schTxSOF : in std_logic; -- Cell contained SOF + schTxEOF : in std_logic; -- Cell contained EOF + schTxIdle : out std_logic; -- Force IDLE transmit + schTxReq : out std_logic; -- Cell transmit request + schTxAck : in std_logic; -- Cell transmit acknowledge + schTxDataVc : out std_logic_vector(1 downto 0); -- Cell transmit virtual channel + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxValid : in std_logic -- User frame data is valid + ); + end component; + +end Pgp2CorePackage; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Rx.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Rx.vhd new file mode 100755 index 0000000000000000000000000000000000000000..9bcb1a931eaf6b17d4ff5842d4cf7c5e67df667f --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Rx.vhd @@ -0,0 +1,201 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Receive Top Level +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Rx.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- Cell Receive interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +-- 01/13/2010: Added received init line to help linking. +-- 06/25/2010: Added payload size config as generic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2Rx is + generic ( + RxLaneCnt : integer := 4; -- Number of receive lanes, 1-4 + EnShortCells : integer := 1; -- Enable short non-EOF cells + PayloadCntTop : integer := 7 -- Top bit for payload counter + ); + port ( + + -- System clock, reset & control + pgpRxClk : in std_logic; -- Master clock + pgpRxReset : in std_logic; -- Synchronous reset input + + -- Link flush + pgpRxFlush : in std_logic; -- Flush the link + + -- Link is ready + pgpRxLinkReady : out std_logic; -- Local side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Sideband data + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- Physical Interface Signals + phyRxPolarity : out std_logic_vector(RxLaneCnt-1 downto 0); -- PHY receive signal polarity + phyRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyRxDispErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data has disparity error + phyRxDecErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data not in table + phyRxReady : in std_logic; -- PHY receive interface is ready + phyRxInit : out std_logic; + + -- Receive CRC Interface + crcRxIn : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- Receive data for CRC + crcRxWidth : out std_logic; -- Receive CRC width, 1=full, 0=32-bit + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxOut : in std_logic_vector(31 downto 0); -- Receive calculated CRC value + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Rx; + + +-- Define architecture +architecture Pgp2Rx of Pgp2Rx is + + -- Local Signals + signal cellRxPause : std_logic; + signal cellRxSOC : std_logic; + signal cellRxSOF : std_logic; + signal cellRxEOC : std_logic; + signal cellRxEOF : std_logic; + signal cellRxEOFE : std_logic; + signal cellRxData : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal intRxLinkReady : std_logic; + +begin + + -- Link Ready + pgpRxLinkReady <= intRxLinkReady; + + -- PHY Logic + U_Pgp2RxPhy: Pgp2RxPhy + generic map ( + RxLaneCnt => RxLaneCnt + ) port map ( + pgpRxClk => pgpRxClk, + pgpRxReset => pgpRxReset, + pgpRxLinkReady => intRxLinkReady, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + cellRxPause => cellRxPause, + cellRxSOC => cellRxSOC, + cellRxSOF => cellRxSOF, + cellRxEOC => cellRxEOC, + cellRxEOF => cellRxEOF, + cellRxEOFE => cellRxEOFE, + cellRxData => cellRxData, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + debug => debug + ); + + + -- Cell Receiver + U_Pgp2RxCell: Pgp2RxCell + generic map ( + RxLaneCnt => RxLaneCnt, + EnShortCells => EnShortCells, + PayloadCntTop => PayloadCntTop + ) port map ( + pgpRxClk => pgpRxClk, + pgpRxReset => pgpRxReset, + pgpRxFlush => pgpRxFlush, + pgpRxLinkReady => intRxLinkReady, + pgpRxCellError => pgpRxCellError, + cellRxPause => cellRxPause, + cellRxSOC => cellRxSOC, + cellRxSOF => cellRxSOF, + cellRxEOC => cellRxEOC, + cellRxEOF => cellRxEOF, + cellRxEOFE => cellRxEOFE, + cellRxData => cellRxData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + crcRxIn => crcRxIn, + crcRxWidth => crcRxWidth, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut + ); + +end Pgp2Rx; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxCell.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxCell.vhd new file mode 100755 index 0000000000000000000000000000000000000000..ff6ea5166154455db88068758715f4aca95b9f21 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxCell.vhd @@ -0,0 +1,744 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Cell Receive Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2RxCell.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- Cell Receive interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +-- 06/25/2010: Added payload size config as generic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2RxCell is + generic ( + RxLaneCnt : integer := 4; -- Number of receive lanes, 1-4 + EnShortCells : integer := 1; -- Enable short non-EOF cells + PayloadCntTop : integer := 7 -- Top bit for payload counter + ); + port ( + + -- System clock, reset & control + pgpRxClk : in std_logic; -- Master clock + pgpRxReset : in std_logic; -- Synchronous reset input + + -- Link flush + pgpRxFlush : in std_logic; -- Flush the link + + -- Link is ready + pgpRxLinkReady : in std_logic; -- Local side has link + + -- Cell Error, one pulse per error + pgpRxCellError : out std_logic; -- A cell error has occured + + -- Interface to PHY Logic + cellRxPause : in std_logic; -- Cell data pause + cellRxSOC : in std_logic; -- Cell data start of cell + cellRxSOF : in std_logic; -- Cell data start of frame + cellRxEOC : in std_logic; -- Cell data end of cell + cellRxEOF : in std_logic; -- Cell data end of frame + cellRxEOFE : in std_logic; -- Cell data end of frame error + cellRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); -- Cell data data + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- Receive CRC Interface + crcRxIn : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- Receive data for CRC + crcRxWidth : out std_logic; -- Receive CRC width, 1=full, 0=32-bit + crcRxInit : out std_logic; -- Receive CRC value init + crcRxValid : out std_logic; -- Receive data for CRC is valid + crcRxOut : in std_logic_vector(31 downto 0) -- Receive calculated CRC value + ); + +end Pgp2RxCell; + + +-- Define architecture +architecture Pgp2RxCell of Pgp2RxCell is + + -- Local Signals + signal dly0SOC : std_logic; + signal dly0SOF : std_logic; + signal dly0EOC : std_logic; + signal dly0EOF : std_logic; + signal dly0EOFE : std_logic; + signal dly0Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly1SOC : std_logic; + signal dly1SOF : std_logic; + signal dly1EOC : std_logic; + signal dly1EOF : std_logic; + signal dly1EOFE : std_logic; + signal dly1Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly2SOC : std_logic; + signal dly2SOF : std_logic; + signal dly2EOC : std_logic; + signal dly2EOF : std_logic; + signal dly2EOFE : std_logic; + signal dly2Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly3SOC : std_logic; + signal dly3SOF : std_logic; + signal dly3EOC : std_logic; + signal dly3EOF : std_logic; + signal dly3EOFE : std_logic; + signal dly3Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly4SOC : std_logic; + signal dly4SOF : std_logic; + signal dly4EOC : std_logic; + signal dly4EOF : std_logic; + signal dly4EOFE : std_logic; + signal dly4Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly5SOC : std_logic; + signal dly5SOF : std_logic; + signal dly5EOC : std_logic; + signal dly5EOF : std_logic; + signal dly5EOFE : std_logic; + signal dly5Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly6SOC : std_logic; + signal dly6SOF : std_logic; + signal dly6EOC : std_logic; + signal dly6EOF : std_logic; + signal dly6EOFE : std_logic; + signal dly6Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly7SOC : std_logic; + signal dly7SOF : std_logic; + signal dly7EOC : std_logic; + signal dly7EOF : std_logic; + signal dly7EOFE : std_logic; + signal dly7Data : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal intCrcRxValid : std_logic; + signal crcNotZero : std_logic; + signal linkDownCnt : std_logic_vector(4 downto 0); + signal compSOC : std_logic; + signal compData : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal detSOC : std_logic; + signal detSOF : std_logic; + signal outData : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal detEOC : std_logic; + signal detEOF : std_logic; + signal detEOFE : std_logic; + signal inCellEn : std_logic; + signal nxtCellEn : std_logic; + signal inCellSerErr : std_logic; + signal inCellSOF : std_logic; + signal inCellEOC : std_logic; + signal inCellEOF : std_logic; + signal inCellEOFE : std_logic; + signal inCellCnt : std_logic_vector(PayloadCntTop downto 0); + signal vcInFrame : std_logic_vector(3 downto 0); + signal currVc : std_logic_vector(1 downto 0); + signal serErr : std_logic; + signal vc0Serial : std_logic_vector(5 downto 0); + signal vc0Valid : std_logic; + signal vc1Serial : std_logic_vector(5 downto 0); + signal vc1Valid : std_logic; + signal vc2Serial : std_logic_vector(5 downto 0); + signal vc2Valid : std_logic; + signal vc3Serial : std_logic_vector(5 downto 0); + signal vc3Valid : std_logic; + signal abortVc : std_logic_vector(1 downto 0); + signal abortEn : std_logic; + signal intCellError : std_logic; + signal dlyCellError : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Delay stages to line up data with CRC calculation + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + dly0SOC <= '0' after tpd; + dly0SOF <= '0' after tpd; + dly0EOC <= '0' after tpd; + dly0EOF <= '0' after tpd; + dly0EOFE <= '0' after tpd; + dly0Data <= (others=>'0') after tpd; + dly1SOC <= '0' after tpd; + dly1SOF <= '0' after tpd; + dly1EOC <= '0' after tpd; + dly1EOF <= '0' after tpd; + dly1EOFE <= '0' after tpd; + dly1Data <= (others=>'0') after tpd; + dly2SOC <= '0' after tpd; + dly2SOF <= '0' after tpd; + dly2EOC <= '0' after tpd; + dly2EOF <= '0' after tpd; + dly2EOFE <= '0' after tpd; + dly2Data <= (others=>'0') after tpd; + dly3SOC <= '0' after tpd; + dly3SOF <= '0' after tpd; + dly3EOC <= '0' after tpd; + dly3EOF <= '0' after tpd; + dly3EOFE <= '0' after tpd; + dly3Data <= (others=>'0') after tpd; + dly4SOC <= '0' after tpd; + dly4SOF <= '0' after tpd; + dly4EOC <= '0' after tpd; + dly4EOF <= '0' after tpd; + dly4EOFE <= '0' after tpd; + dly4Data <= (others=>'0') after tpd; + dly5SOC <= '0' after tpd; + dly5SOF <= '0' after tpd; + dly5EOC <= '0' after tpd; + dly5EOF <= '0' after tpd; + dly5EOFE <= '0' after tpd; + dly5Data <= (others=>'0') after tpd; + dly6SOC <= '0' after tpd; + dly6SOF <= '0' after tpd; + dly6EOC <= '0' after tpd; + dly6EOF <= '0' after tpd; + dly6EOFE <= '0' after tpd; + dly6Data <= (others=>'0') after tpd; + dly7SOC <= '0' after tpd; + dly7SOF <= '0' after tpd; + dly7EOC <= '0' after tpd; + dly7EOF <= '0' after tpd; + dly7EOFE <= '0' after tpd; + dly7Data <= (others=>'0') after tpd; + intCrcRxValid <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Shift when not paused + if cellRxPause = '0' then + + -- Delay stage 0 + dly0SOC <= cellRxSOC after tpd; + dly0SOF <= cellRxSOF after tpd; + dly0EOC <= cellRxEOC after tpd; + dly0EOF <= cellRxEOF after tpd; + dly0EOFE <= cellRxEOFE after tpd; + dly0Data <= cellRxData after tpd; + + -- Delay stage 1 + dly1SOC <= dly0SOC after tpd; + dly1SOF <= dly0SOF after tpd; + dly1EOC <= dly0EOC after tpd; + dly1EOF <= dly0EOF after tpd; + dly1EOFE <= dly0EOFE after tpd; + dly1Data <= dly0Data after tpd; + + -- Delay stage 2 + dly2SOC <= dly1SOC after tpd; + dly2SOF <= dly1SOF after tpd; + dly2EOC <= dly1EOC after tpd; + dly2EOF <= dly1EOF after tpd; + dly2EOFE <= dly1EOFE after tpd; + dly2Data <= dly1Data after tpd; + + -- Delay stage 3 + dly3SOC <= dly2SOC after tpd; + dly3SOF <= dly2SOF after tpd; + dly3EOC <= dly2EOC after tpd; + dly3EOF <= dly2EOF after tpd; + dly3EOFE <= dly2EOFE after tpd; + dly3Data <= dly2Data after tpd; + + -- Delay stage 4 + dly4SOC <= dly3SOC after tpd; + dly4SOF <= dly3SOF after tpd; + dly4EOC <= dly3EOC after tpd; + dly4EOF <= dly3EOF after tpd; + dly4EOFE <= dly3EOFE after tpd; + dly4Data <= dly3Data after tpd; + + -- Delay stage 5 + dly5SOC <= dly4SOC after tpd; + dly5SOF <= dly4SOF after tpd; + dly5EOC <= dly4EOC after tpd; + dly5EOF <= dly4EOF after tpd; + dly5EOFE <= dly4EOFE after tpd; + dly5Data <= dly4Data after tpd; + + -- Delay stage 6 + dly6SOC <= dly5SOC after tpd; + dly6SOF <= dly5SOF after tpd; + dly6EOC <= dly5EOC after tpd; + dly6EOF <= dly5EOF after tpd; + dly6EOFE <= dly5EOFE after tpd; + dly6Data <= dly5Data after tpd; + + -- Delay stage 7 + dly7SOC <= dly6SOC after tpd; + dly7SOF <= dly6SOF after tpd; + dly7EOC <= dly6EOC after tpd; + dly7EOF <= dly6EOF after tpd; + dly7EOFE <= dly6EOFE after tpd; + dly7Data <= dly6Data after tpd; + + -- CRC Enable & partial flag + if cellRxSOC = '1' then + intCrcRxValid <= '1' after tpd; + elsif cellRxEOC = '1' then + intCrcRxValid <= '0' after tpd; + end if; + end if; + end if; + end process; + + + -- CRC Data Output, SOC field overwritten with zeros + GEN_CRC: for i in 0 to (RxLaneCnt-1) generate + process ( dly0SOC, dly0Data ) begin + if dly0SOC = '1' then + crcRxIn(i*16+7 downto i*16) <= (others=>'0'); + else + crcRxIn(i*16+7 downto i*16) <= dly0Data(i*16+7 downto i*16); + end if; + crcRxIn(i*16+15 downto i*16+8) <= dly0Data(i*16+15 downto i*16+8); + end process; + end generate; + + + -- Output to CRC engine + crcRxWidth <= '0' when ( cellRxEOC = '1' and RxLaneCnt > 2 ) else '1'; + crcRxInit <= dly0SOC; + crcRxValid <= intCrcRxValid and not cellRxPause; + + + -- Choose tap positions in delay chain + + -- Serial number compare position, detSOC - 1 + compSOC <= dly6SOC; + compData <= dly6Data; + + -- SOC detect position, + detSOC <= dly7SOC; + detSOF <= dly7SOF; + outData <= dly7Data; + + -- EOC detect position, depends on lane count + -- detSOC - 4 when 1 lane, detSOC - 3 when multiple lanes + detEOC <= dly3EOC when RxLaneCnt = 1 else dly4EOC; + detEOF <= dly3EOF when RxLaneCnt = 1 else dly4EOF; + detEOFE <= dly3EOFE when RxLaneCnt = 1 else dly4EOFE; + + + -- Detect current VC, check cell serial number + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + currVc <= (others=>'0') after tpd; + serErr <= '0' after tpd; + vc0Serial <= (others=>'0') after tpd; + vc0Valid <= '0' after tpd; + vc1Serial <= (others=>'0') after tpd; + vc1Valid <= '0' after tpd; + vc2Serial <= (others=>'0') after tpd; + vc2Valid <= '0' after tpd; + vc3Serial <= (others=>'0') after tpd; + vc3Valid <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Link is down, init counts + if pgpRxLinkReady = '0' then + currVc <= (others=>'0') after tpd; + serErr <= '0' after tpd; + vc0Serial <= (others=>'0') after tpd; + vc0Valid <= '0' after tpd; + vc1Serial <= (others=>'0') after tpd; + vc1Valid <= '0' after tpd; + vc2Serial <= (others=>'0') after tpd; + vc2Valid <= '0' after tpd; + vc3Serial <= (others=>'0') after tpd; + vc3Valid <= '0' after tpd; + + -- Pipeline enable + elsif cellRxPause = '0' then + + -- SOC for compare + if compSOC = '1' then + + -- Register VC value + currVc <= compData(15 downto 14) after tpd; + + -- Compare current count, store current count for future increment + case compData(15 downto 14) is + + -- VC 0 + when "00" => + if compData(13 downto 8) = vc0Serial then + serErr <= '0' after tpd; + else + vc0Serial <= compData(13 downto 8) after tpd; + serErr <= vc0Valid after tpd; + end if; + vc0Valid <= '1' after tpd; + + -- VC 1 + when "01" => + if compData(13 downto 8) = vc1Serial then + serErr <= '0' after tpd; + else + vc1Serial <= compData(13 downto 8) after tpd; + serErr <= vc1Valid after tpd; + end if; + vc1Valid <= '1' after tpd; + + -- VC 2 + when "10" => + if compData(13 downto 8) = vc2Serial then + serErr <= '0' after tpd; + else + vc2Serial <= compData(13 downto 8) after tpd; + serErr <= vc2Valid after tpd; + end if; + vc2Valid <= '1' after tpd; + + -- VC 3 + when others => + if compData(13 downto 8) = vc3Serial then + serErr <= '0' after tpd; + else + vc3Serial <= compData(13 downto 8) after tpd; + serErr <= vc3Valid after tpd; + end if; + vc3Valid <= '1' after tpd; + end case; + + -- SOC for increment + elsif detSOC = '1' then + case currVc is + when "00" => vc0Serial <= vc0Serial + 1 after tpd; + when "01" => vc1Serial <= vc1Serial + 1 after tpd; + when "10" => vc2Serial <= vc2Serial + 1 after tpd; + when others => vc3Serial <= vc3Serial + 1 after tpd; + end case; + end if; + end if; + end if; + end process; + + + -- Receive cell tracking + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + crcNotZero <= '0' after tpd; + linkDownCnt <= (others=>'0') after tpd; + inCellEn <= '0' after tpd; + inCellSerErr <= '0' after tpd; + inCellSOF <= '0' after tpd; + inCellEOC <= '0' after tpd; + inCellEOF <= '0' after tpd; + inCellEOFE <= '0' after tpd; + inCellCnt <= (others=>'0') after tpd; + abortEn <= '0' after tpd; + abortVc <= (others=>'0') after tpd; + intCellError <= '0' after tpd; + dlyCellError <= '0' after tpd; + pgpRxCellError <= '0' after tpd; + vcInFrame <= (others=>'0') after tpd; + elsif rising_edge(pgpRxClk) then + + -- Cell error edge generation + dlyCellError <= intCellError after tpd; + pgpRxCellError <= intCellError and not dlyCellError after tpd; + + -- CRC Error + if crcRxOut = 0 then + crcNotZero <= '0' after tpd; + else + crcNotZero <= '1' after tpd; + end if; + + -- Link down counter + if pgpRxLinkReady = '1' then + linkDownCnt <= (others=>'0') after tpd; + elsif linkDownCnt(4) = '0' then + linkDownCnt <= linkDownCnt + 1 after tpd; + end if; + + -- Count size of each cell received + if cellRxPause = '0' then + if inCellEn = '1' then + inCellCnt <= inCellCnt - 1 after tpd; + else + inCellCnt <= (others=>'1') after tpd; + end if; + end if; + + -- Link is down. Terminate transmission for any active VCs + if pgpRxLinkReady = '0' then + + -- Enabled every 4 clocks to ensure proper spacing between generated EOFs + if linkDownCnt(1 downto 0) = "11" then + + -- VC is active + if vcInFrame(conv_integer(linkDownCnt(3 downto 2))) = '1' then + abortEn <= '1' after tpd; + vcInFrame(conv_integer(linkDownCnt(3 downto 2))) <= '0' after tpd; + else + abortEn <= '0' after tpd; + end if; + else + abortEn <= '0' after tpd; + end if; + + -- VC for abort + abortVc <= linkDownCnt(3 downto 2) after tpd; + + -- Clear cell control signals + inCellEn <= '0' after tpd; + inCellSerErr <= '0' after tpd; + inCellSOF <= '0' after tpd; + inCellEOC <= '0' after tpd; + inCellEOF <= '0' after tpd; + inCellEOFE <= '0' after tpd; + intCellError <= '0' after tpd; + + -- Link is ready + else + + -- Clear abort flags + abortVc <= (others=>'0') after tpd; + abortEn <= '0' after tpd; + + -- Link flush set + if pgpRxFlush = '1' then + vcInFrame <= (others=>'0') after tpd; + + -- Pipeline enable + elsif cellRxPause = '0' then + + -- SOC Received + if detSOC = '1' then + + -- Do we output data and mark in frame? + -- Yes if SOF is set and serial number is ok + -- Yes if already in frame + if nxtCellEn = '1' then + inCellEn <= '1' after tpd; + vcInFrame(conv_integer(currVc)) <= '1' after tpd; + end if; + + -- Do we mark output as SOF? + -- Yes if SOF is seen and the serial number is ok and we are not already in frame + if detSOF = '1' and serErr = '0' and vcInFrame(conv_integer(currVc)) = '0' then + inCellSOF <= '1' after tpd; + end if; + + -- Do we mark serial error flag? + -- Yes if SOF is set and we are already in frame + -- Yes if serial number error + if (detSOF = '1' and vcInFrame(conv_integer(currVc)) = '1') or serErr = '1' then + inCellSerErr <= '1' after tpd; + end if; + + -- Mark out of cell after EOC + elsif inCellEOC = '1' then + inCellEn <= '0' after tpd; + inCellSerErr <= '0' after tpd; + inCellSOF <= '0' after tpd; + + -- Clear frame state if EOF + if inCellEOF = '1' then + vcInFrame(conv_integer(currVc)) <= '0' after tpd; + end if; + + -- Clear SOF + else + inCellSOF <= '0' after tpd; + end if; + + -- End of cell, check for short cell case + if detEOC = '1' and (inCellEn = '1' or nxtCellEn = '1') then + inCellEOC <= '1' after tpd; + intCellError <= inCellSerErr or crcNotZero after tpd; + + -- Cell is too short + if detEOF = '0' and inCellCnt /= 1 and EnShortCells = 0 then + inCellEOF <= '1' after tpd; + inCellEOFE <= '1' after tpd; + intCellError <= '1' after tpd; + else + inCellEOF <= detEOF or inCellSerErr or crcNotZero after tpd; + inCellEOFE <= detEOFE or inCellSerErr or crcNotZero after tpd; + intCellError <= inCellSerErr or crcNotZero after tpd; + end if; + + -- Cell might be too long + elsif inCellEn = '1' and inCellCnt = 0 and inCellEOC = '0' then + inCellEOC <= '1' after tpd; + inCellEOF <= '1' after tpd; + inCellEOFE <= '1' after tpd; + intCellError <= '1' after tpd; + else + inCellEOC <= '0' after tpd; + inCellEOF <= '0' after tpd; + inCellEOFE <= '0' after tpd; + intCellError <= '0' after tpd; + end if; + end if; + end if; + end if; + end process; + + + -- Do we output data and mark in frame? + -- Yes if SOF is set and serial number is ok + -- Yes if already in frame + nxtCellEn <= '1' when ((detSOF = '1' and serErr = '0') or vcInFrame(conv_integer(currVc)) = '1') else '0'; + + + -- Data Output + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + vcFrameRxData <= (others=>'0') after tpd; + vcFrameRxSOF <= '0' after tpd; + vcFrameRxEOF <= '0' after tpd; + vcFrameRxEOFE <= '0' after tpd; + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Data abort is enabled + if abortEn = '1' then + case abortVc is + when "00" => + vc0FrameRxValid <= '1' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + when "01" => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '1' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + when "10" => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '1' after tpd; + vc3FrameRxValid <= '0' after tpd; + when others => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '1' after tpd; + end case; + + -- Abort output + vcFrameRxSOF <= '0' after tpd; + vcFrameRxEOF <= '1' after tpd; + vcFrameRxEOFE <= '1' after tpd; + + -- Pipeline is enabled + elsif cellRxPause = '0' and inCellEn = '1' then + case currVc is + when "00" => + vc0FrameRxValid <= '1' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + when "01" => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '1' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + when "10" => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '1' after tpd; + vc3FrameRxValid <= '0' after tpd; + when others => + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '1' after tpd; + end case; + + -- Data output + vcFrameRxData <= outData after tpd; + vcFrameRxSOF <= inCellSOF after tpd; + vcFrameRxEOF <= inCellEOF after tpd; + vcFrameRxEOFE <= inCellEOFE after tpd; + + -- Paused or no data + else + vc0FrameRxValid <= '0' after tpd; + vc1FrameRxValid <= '0' after tpd; + vc2FrameRxValid <= '0' after tpd; + vc3FrameRxValid <= '0' after tpd; + end if; + end if; + end process; + + + -- Update buffer status on successfull cell reception + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + vc0RemBuffAFull <= '1' after tpd; + vc0RemBuffFull <= '1' after tpd; + vc1RemBuffAFull <= '1' after tpd; + vc1RemBuffFull <= '1' after tpd; + vc2RemBuffAFull <= '1' after tpd; + vc2RemBuffFull <= '1' after tpd; + vc3RemBuffAFull <= '1' after tpd; + vc3RemBuffFull <= '1' after tpd; + elsif rising_edge(pgpRxClk) then + + -- Link is not ready, force buffer states to bad + if pgpRxLinkReady = '0' then + vc0RemBuffAFull <= '1' after tpd; + vc0RemBuffFull <= '1' after tpd; + vc1RemBuffAFull <= '1' after tpd; + vc1RemBuffFull <= '1' after tpd; + vc2RemBuffAFull <= '1' after tpd; + vc2RemBuffFull <= '1' after tpd; + vc3RemBuffAFull <= '1' after tpd; + vc3RemBuffFull <= '1' after tpd; + + -- Update buffer status + elsif cellRxEOC = '1' then + vc0RemBuffAFull <= cellRxData(8) after tpd; + vc0RemBuffFull <= cellRxData(12) after tpd; + vc1RemBuffAFull <= cellRxData(9) after tpd; + vc1RemBuffFull <= cellRxData(13) after tpd; + vc2RemBuffAFull <= cellRxData(10) after tpd; + vc2RemBuffFull <= cellRxData(14) after tpd; + vc3RemBuffAFull <= cellRxData(11) after tpd; + vc3RemBuffFull <= cellRxData(15) after tpd; + end if; + end if; + end process; + +end Pgp2RxCell; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxPhy.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxPhy.vhd new file mode 100755 index 0000000000000000000000000000000000000000..6697c247b58f0719b119d7096b1a934c2a885a4a --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2RxPhy.vhd @@ -0,0 +1,715 @@ +--------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol V2, Physical Interface Receive Module +-- Project : General Purpose Core +--------------------------------------------------------------------------------- +-- File : Pgp2RxPhy.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +--------------------------------------------------------------------------------- +-- Description: +-- Physical interface receive module for the Pretty Good Protocol version 2 core. +--------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +--------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +-- 01/13/2010: Added init of reset controller if failed to link after 1023 clocks. +-- fixed bug in dealing with an inverted receive link. +-- 02/01/2011: Rem data and rem link not updated if EOF fields don't match. +--------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2RxPhy is + generic ( + RxLaneCnt : integer := 4 -- Number of receive lanes, 1-4 + ); + port ( + + -- System clock, reset & control + pgpRxClk : in std_logic; -- Master clock + pgpRxReset : in std_logic; -- Synchronous reset input + + -- Link is ready + pgpRxLinkReady : out std_logic; -- Local side has link + + -- Error Flags, one pulse per event + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Sideband data + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + + -- Cell Receive Interface + cellRxPause : out std_logic; -- Cell data pause + cellRxSOC : out std_logic; -- Cell data start of cell + cellRxSOF : out std_logic; -- Cell data start of frame + cellRxEOC : out std_logic; -- Cell data end of cell + cellRxEOF : out std_logic; -- Cell data end of frame + cellRxEOFE : out std_logic; -- Cell data end of frame error + cellRxData : out std_logic_vector(RxLaneCnt*16-1 downto 0); -- Cell data data + + -- Physical Interface Signals + phyRxPolarity : out std_logic_vector(RxLaneCnt-1 downto 0); -- PHY receive signal polarity + phyRxData : in std_logic_vector(RxLaneCnt*16-1 downto 0); -- PHY receive data + phyRxDataK : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyRxDispErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data has disparity error + phyRxDecErr : in std_logic_vector(RxLaneCnt*2-1 downto 0); -- PHY receive data not in table + phyRxReady : in std_logic; -- PHY receive interface is ready + phyRxInit : out std_logic; -- PHY receive interface init; + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2RxPhy; + + +-- Define architecture +architecture Pgp2RxPhy of Pgp2RxPhy is + + -- Local Signals + signal dly0RxData : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly0RxDataK : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal dly0RxDispErr : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal dly0RxDecErr : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal dly1RxData : std_logic_vector(RxLaneCnt*16-1 downto 0); + signal dly1RxDataK : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal dly1RxDispErr : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal dly1RxDecErr : std_logic_vector(RxLaneCnt*2-1 downto 0); + signal rxDetectLts : std_logic; + signal rxDetectLtsOk : std_logic; + signal rxDetectLtsRaw : std_logic_vector(3 downto 0); + signal rxDetectInvert : std_logic_vector(RxLaneCnt-1 downto 0); + signal rxDetectInvertRaw : std_logic_vector(RxLaneCnt-1 downto 0); + signal rxDetectRemLink : std_logic; + signal rxDetectRemData : std_logic_vector(7 downto 0); + signal rxDetectOpCodeEn : std_logic; + signal rxDetectOpCodeEnRaw : std_logic_vector(3 downto 0); + signal rxDetectSOC : std_logic; + signal rxDetectSOCRaw : std_logic_vector(3 downto 0); + signal rxDetectSOF : std_logic; + signal rxDetectSOFRaw : std_logic_vector(3 downto 0); + signal rxDetectEOC : std_logic; + signal rxDetectEOCRaw : std_logic_vector(3 downto 0); + signal rxDetectEOF : std_logic; + signal rxDetectEOFRaw : std_logic_vector(3 downto 0); + signal rxDetectEOFE : std_logic; + signal rxDetectEOFERaw : std_logic_vector(3 downto 0); + signal nxtRxLinkReady : std_logic; + signal stateCntRst : std_logic; + signal stateCnt : std_logic_vector(19 downto 0); + signal ltsCntRst : std_logic; + signal ltsCntEn : std_logic; + signal ltsCnt : std_logic_vector(7 downto 0); + signal intRxLinkReady : std_logic; + signal intRxPolarity : std_logic_vector(RxLaneCnt-1 downto 0); + signal nxtRxPolarity : std_logic_vector(RxLaneCnt-1 downto 0); + signal dlyRxLinkDown : std_logic; + signal intRxLinkError : std_logic; + signal dlyRxLinkError : std_logic; + signal intRxInit : std_logic; + signal nxtRxInit : std_logic; + signal dbgRxData : std_logic_vector(31 downto 0); + signal dbgRxDataK : std_logic_vector(3 downto 0); + signal dbgInvert : std_logic_vector(1 downto 0); + signal dbgPolarity : std_logic_vector(1 downto 0); + signal dbgRxDispErr : std_logic_vector(3 downto 0); + signal dbgRxDecErr : std_logic_vector(3 downto 0); + + -- Physical Link State + constant ST_RESET : std_logic_vector(2 downto 0) := "001"; + constant ST_LOCK : std_logic_vector(2 downto 0) := "010"; + constant ST_WAIT : std_logic_vector(2 downto 0) := "011"; + constant ST_INVRT : std_logic_vector(2 downto 0) := "100"; + constant ST_READY : std_logic_vector(2 downto 0) := "101"; + signal curState : std_logic_vector(2 downto 0); + signal nxtState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Link status + pgpRxLinkReady <= intRxLinkReady; + + -- RX Interface Init + phyRxInit <= intRxInit; + + -- Opcode Receive Interface + pgpRxOpCodeEn <= rxDetectOpCodeEn; + pgpRxOpCode <= dly1RxData(15 downto 8); + + -- Cell Receive Interface + cellRxPause <= rxDetectOpCodeEn; + cellRxSOC <= rxDetectSOC; + cellRxSOF <= rxDetectSOF; + cellRxEOC <= rxDetectEOC; + cellRxEOF <= rxDetectEOF; + cellRxEOFE <= rxDetectEOFE; + cellRxData <= dly1RxData; + + -- Drive active polarity control signals + GEN_POL: for i in 0 to (RxLaneCnt-1) generate + phyRxPolarity(i) <= intRxPolarity(i); + end generate; + + -- State transition sync logic. + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + curState <= ST_RESET after tpd; + stateCnt <= (others=>'0') after tpd; + ltsCnt <= (others=>'0') after tpd; + intRxLinkReady <= '0' after tpd; + intRxPolarity <= (others=>'0') after tpd; + dlyRxLinkDown <= '0' after tpd; + pgpRxLinkDown <= '0' after tpd; + intRxLinkError <= '0' after tpd; + dlyRxLinkError <= '0' after tpd; + pgpRxLinkError <= '0' after tpd; + intRxInit <= '0' after tpd; + pgpRemLinkReady <= '0' after tpd; + pgpRemData <= (others=>'0') after tpd; + elsif rising_edge(pgpRxClk) then + + -- Sideband data + if intRxLinkReady = '1' then + pgpRemLinkReady <= rxDetectRemLink; + pgpRemData <= rxDetectRemData; + else + pgpRemLinkReady <= '0' after tpd; + pgpRemData <= (others=>'0') after tpd; + end if; + + -- Link down edge detection + dlyRxLinkDown <= (not intRxLinkReady) after tpd; + pgpRxLinkDown <= (not intRxLinkReady) and (not dlyRxLinkDown) after tpd; + + -- Link error generation + if (phyRxDispErr /= 0 or phyRxDecErr /= 0) and intRxLinkReady = '1' then + intRxLinkError <= '1' after tpd; + else + intRxLinkError <= '0' after tpd; + end if; + + -- Link error edge detection + dlyRxLinkError <= intRxLinkError after tpd; + pgpRxLinkError <= intRxLinkError and not dlyRxLinkError after tpd; + + -- Status signals + intRxLinkReady <= nxtRxLinkReady after tpd; + intRxPolarity <= nxtRxPolarity after tpd; + intRxInit <= nxtRxInit after tpd; + + -- State transition + curState <= nxtState after tpd; + + -- In state counter + if stateCntRst = '1' then + stateCnt <= (others=>'0') after tpd; + else + stateCnt <= stateCnt + 1 after tpd; + end if; + + -- LTS Counter + if ltsCntRst = '1' then + ltsCnt <= (others=>'0') after tpd; + elsif ltsCntEn = '1' and ltsCnt /= 255 then + ltsCnt <= ltsCnt + 1 after tpd; + end if; + + end if; + end process; + + + -- Link control state machine + process ( curState, stateCnt, ltsCnt, rxDetectLts, rxDetectLtsOk, + rxDetectInvert, intRxPolarity, phyRxReady, phyRxDecErr, phyRxDispErr ) begin + case curState is + + -- Hold in rx reset for 8 clocks + when ST_RESET => + nxtRxLinkReady <= '0'; + nxtRxPolarity <= (others=>'0'); + ltsCntRst <= '1'; + ltsCntEn <= '0'; + nxtRxInit <= '1'; + + -- Hold reset for 255 clocks + if stateCnt(7 downto 0) = 255 then + stateCntRst <= '1'; + nxtState <= ST_LOCK; + else + stateCntRst <= '0'; + nxtState <= curState; + end if; + + -- Wait for lock state + when ST_LOCK => + nxtRxLinkReady <= '0'; + nxtRxPolarity <= (others=>'0'); + ltsCntRst <= '1'; + ltsCntEn <= '0'; + nxtRxInit <= '0'; + + -- Wait for lock + if phyRxReady = '1' then + nxtState <= ST_WAIT; + stateCntRst <= '1'; + + -- Terminal count without lock + elsif stateCnt = x"FFFFF" then + nxtState <= ST_RESET; + stateCntRst <= '1'; + else + nxtState <= curState; + stateCntRst <= '0'; + end if; + + -- Wait for training pattern + when ST_WAIT => + nxtRxLinkReady <= '0'; + nxtRxInit <= '0'; + + -- Lock is lost + if phyRxReady = '0' then + stateCntRst <= '1'; + ltsCntEn <= '0'; + ltsCntRst <= '0'; + nxtRxPolarity <= intRxPolarity; + nxtState <= ST_RESET; + + -- Decode or disparity error, clear lts count + elsif phyRxReady = '0' or phyRxDispErr /= 0 or phyRxDecErr /= 0 then + stateCntRst <= '0'; + ltsCntEn <= '0'; + ltsCntRst <= '1'; + nxtRxPolarity <= intRxPolarity; + nxtState <= curState; + + -- Training pattern seen + elsif rxDetectLts = '1' then + stateCntRst <= '1'; + + -- No Inversion + if rxDetectInvert = 0 then + nxtRxPolarity <= intRxPolarity; + nxtState <= curState; + + -- ID & Lane Count Ok + if rxDetectLtsOk = '1' then + ltsCntEn <= '1'; + ltsCntRst <= '0'; + else + ltsCntEn <= '0'; + ltsCntRst <= '1'; + end if; + + -- Inverted + else + ltsCntEn <= '0'; + ltsCntRst <= '1'; + nxtRxPolarity <= intRxPolarity xor rxDetectInvert; + nxtState <= ST_INVRT; + end if; + + -- Run after we have seen 256 non-inverted training sequences + -- without any disparity or decode errors. + elsif ltsCnt = 255 then + stateCntRst <= '1'; + ltsCntEn <= '0'; + ltsCntRst <= '1'; + nxtRxPolarity <= intRxPolarity; + nxtState <= ST_READY; + + -- Terminal count without seeing a valid LTS + elsif stateCnt = x"FFFFF" then + stateCntRst <= '1'; + ltsCntEn <= '0'; + ltsCntRst <= '1'; + nxtRxPolarity <= intRxPolarity; + nxtState <= ST_RESET; + + -- Count cycles without LTS + else + stateCntRst <= '0'; + ltsCntEn <= '0'; + ltsCntRst <= '0'; + nxtRxPolarity <= intRxPolarity; + nxtState <= curState; + end if; + + -- Wait a few clocks after inverting receive interface + when ST_INVRT => + nxtRxLinkReady <= '0'; + nxtRxPolarity <= intRxPolarity; + ltsCntRst <= '1'; + ltsCntEn <= '0'; + nxtRxInit <= '0'; + + -- Wait 128 clocks + if stateCnt(6 downto 0) = 127 then + nxtState <= ST_WAIT; + stateCntRst <= '1'; + else + nxtState <= curState; + stateCntRst <= '0'; + end if; + + -- Ready + when ST_READY => + nxtRxLinkReady <= '1'; + nxtRxPolarity <= intRxPolarity; + ltsCntRst <= '1'; + ltsCntEn <= '0'; + nxtRxInit <= '0'; + + -- Lock is lost + if phyRxReady = '0' then + nxtState <= ST_RESET; + stateCntRst <= '1'; + + -- Training sequence seen + elsif rxDetectLts = '1' then + + -- Link is inverted or bad lts, reset and relink + if rxDetectInvert /= 0 or rxDetectLtsOk = '0' then + nxtState <= ST_RESET; + stateCntRst <= '1'; + + -- Good LTS + else + nxtState <= curState; + stateCntRst <= '1'; + end if; + + -- Link is down after long period without seeing a LTS + -- Min spacing of LTS is 2 Cells = 2 * 256 = 512 + -- Timeout set at 4096 = 8 cells + elsif stateCnt(11 downto 0) = x"FFF" then + nxtState <= ST_RESET; + stateCntRst <= '1'; + + -- Count cycles without LTS + else + nxtState <= curState; + stateCntRst <= '0'; + end if; + + -- Default + when others => + nxtRxLinkReady <= '0'; + nxtRxPolarity <= (others=>'0'); + stateCntRst <= '0'; + ltsCntRst <= '0'; + ltsCntEn <= '0'; + nxtRxInit <= '0'; + nxtState <= ST_LOCK; + end case; + end process; + + + -- Receive data pipeline + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + dly0RxData <= (others=>'0') after tpd; + dly0RxDataK <= (others=>'0') after tpd; + dly0RxDispErr <= (others=>'0') after tpd; + dly0RxDecErr <= (others=>'0') after tpd; + dly1RxData <= (others=>'0') after tpd; + dly1RxDataK <= (others=>'0') after tpd; + dly1RxDispErr <= (others=>'0') after tpd; + dly1RxDecErr <= (others=>'0') after tpd; + elsif rising_edge(pgpRxClk) then + dly0RxData <= phyRxData after tpd; + dly0RxDataK <= phyRxDataK after tpd; + dly0RxDispErr <= phyRxDispErr after tpd; + dly0RxDecErr <= phyRxDecErr after tpd; + dly1RxData <= dly0RxData after tpd; + dly1RxDataK <= dly0RxDataK after tpd; + dly0RxDispErr <= dly0RxDispErr after tpd; + dly0RxDecErr <= dly0RxDecErr after tpd; + end if; + end process; + + + -- Link init ordered set detect + process ( pgpRxClk, pgpRxReset ) begin + if pgpRxReset = '1' then + rxDetectLts <= '0' after tpd; + rxDetectLtsOk <= '0' after tpd; + rxDetectInvert <= (others=>'0') after tpd; + rxDetectRemLink <= '0' after tpd; + rxDetectRemData <= (others=>'0') after tpd; + rxDetectOpCodeEn <= '0' after tpd; + rxDetectSOC <= '0' after tpd; + rxDetectSOF <= '0' after tpd; + rxDetectEOC <= '0' after tpd; + rxDetectEOF <= '0' after tpd; + rxDetectEOFE <= '0' after tpd; + elsif rising_edge(pgpRxClk) then + + -- LTS is detected when phy is ready + if phyRxReady = '1' then + + -- Detect link init ordered sets + if rxDetectLtsRaw(0) = '1' and + ( rxDetectLtsRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectLtsRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectLtsRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectInvert <= rxDetectInvertRaw after tpd; + rxDetectLts <= '1' after tpd; + + -- Lane count and ID must match + if dly0RxData(13 downto 12) = conv_std_logic_vector(RxLaneCnt-1,2) and + dly0RxData(11 downto 8) = Pgp2Id then + rxDetectLtsOk <= '1' after tpd; + rxDetectRemLink <= dly0RxData(15) after tpd; + rxDetectRemData <= dly0RxData(7 downto 0) after tpd; + else + rxDetectLtsOk <= '0' after tpd; + end if; + else + rxDetectLts <= '0' after tpd; + rxDetectLtsOk <= '0' after tpd; + end if; + else + rxDetectLts <= '0' after tpd; + rxDetectLtsOk <= '0' after tpd; + rxDetectInvert <= (others=>'0') after tpd; + rxDetectRemLink <= '0' after tpd; + rxDetectRemData <= (others=>'0') after tpd; + end if; + + -- The remaining opcodes are only detected when the link is up + if intRxLinkReady = '1' then + + -- Detect opCode ordered set + if rxDetectOpCodeEnRaw(0) = '1' and + ( rxDetectOpCodeEnRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectOpCodeEnRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectOpCodeEnRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectOpCodeEn <= '1' after tpd; + else + rxDetectOpCodeEn <= '0' after tpd; + end if; + + -- Detect SOC ordered set + if rxDetectSOCRaw(0) = '1' and + ( rxDetectSOCRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectSOCRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectSOCRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectSOC <= '1' after tpd; + rxDetectSOF <= '0' after tpd; + + -- Detect SOF ordered set + elsif rxDetectSOFRaw(0) = '1' and + ( rxDetectSOFRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectSOFRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectSOFRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectSOC <= '1' after tpd; + rxDetectSOF <= '1' after tpd; + else + rxDetectSOC <= '0' after tpd; + rxDetectSOF <= '0' after tpd; + end if; + + -- Detect EOC ordered set + if rxDetectEOCRaw(0) = '1' and + ( rxDetectEOCRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectEOCRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectEOCRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectEOC <= '1' after tpd; + rxDetectEOF <= '0' after tpd; + rxDetectEOFE <= '0' after tpd; + + -- Detect EOF ordered set + elsif rxDetectEOFRaw(0) = '1' and + ( rxDetectEOFRaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectEOFRaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectEOFRaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectEOC <= '1' after tpd; + rxDetectEOF <= '1' after tpd; + rxDetectEOFE <= '0' after tpd; + + -- Detect EOFE ordered set + elsif rxDetectEOFERaw(0) = '1' and + ( rxDetectEOFERaw(1) = '1' or RxLaneCnt < 2 ) and + ( rxDetectEOFERaw(2) = '1' or RxLaneCnt < 3 ) and + ( rxDetectEOFERaw(3) = '1' or RxLaneCnt < 4 ) then + rxDetectEOC <= '1' after tpd; + rxDetectEOF <= '1' after tpd; + rxDetectEOFE <= '1' after tpd; + else + rxDetectEOC <= '0' after tpd; + rxDetectEOF <= '0' after tpd; + rxDetectEOFE <= '0' after tpd; + end if; + else + rxDetectOpCodeEn <= '0' after tpd; + rxDetectSOC <= '0' after tpd; + rxDetectSOF <= '0' after tpd; + rxDetectEOC <= '0' after tpd; + rxDetectEOF <= '0' after tpd; + rxDetectEOFE <= '0' after tpd; + end if; + end if; + end process; + + -- Generate Loop + GEN_LANES: for i in 0 to (RxLaneCnt-1) generate + + -- Ordered Set Detection + process ( dly1RxDataK, dly1RxData, dly0RxDataK, dly0RxData, phyRxDispErr, phyRxDecErr ) begin + + -- Skip errored decodes + if phyRxDispErr(i*2) = '0' and phyRxDispErr(i*2+1) = '0' and + phyRxDecErr(i*2) = '0' and phyRxDecErr(i*2+1) = '0' then + + -- Link init ordered set + if ( dly1RxDataK(i*2) = '1' and dly1RxDataK(i*2+1) = '0' and + dly0RxDataK(i*2) = '0' and dly0RxDataK(i*2+1) = '0' and + dly1RxData(i*16+7 downto i*16) = K_LTS and + ( dly1RxData(i*16+15 downto i*16+8) = D_102 or dly1RxData(i*16+15 downto i*16+8) = D_215 ) ) then + rxDetectLtsRaw(i) <= '1'; + + -- Detect Link Inversion + if dly1RxData(i*16+15 downto i*16+8) = D_102 then + rxDetectInvertRaw(i) <= '0'; + else + rxDetectInvertRaw(i) <= '1'; + end if; + else + rxDetectLtsRaw(i) <= '0'; + rxDetectInvertRaw(i) <= '0'; + end if; + + -- OpCode Enable + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_OTS ) then + rxDetectOpCodeEnRaw(i) <= '1'; + else + rxDetectOpCodeEnRaw(i) <= '0'; + end if; + + -- SOC Detect + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_SOC ) then + rxDetectSOCRaw(i) <= '1'; + else + rxDetectSOCRaw(i) <= '0'; + end if; + + -- SOF Detect + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_SOF ) then + rxDetectSOFRaw(i) <= '1'; + else + rxDetectSOFRaw(i) <= '0'; + end if; + + -- EOC Detect + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_EOC ) then + rxDetectEOCRaw(i) <= '1'; + else + rxDetectEOCRaw(i) <= '0'; + end if; + + -- EOF Detect + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_EOF ) then + rxDetectEOFRaw(i) <= '1'; + else + rxDetectEOFRaw(i) <= '0'; + end if; + + -- EOFE Detect + if ( dly0RxDataK(i*2) = '1' and dly0RxDataK(i*2+1) = '0' and dly0RxData(i*16+7 downto i*16) = K_EOFE ) then + rxDetectEOFERaw(i) <= '1'; + else + rxDetectEOFERaw(i) <= '0'; + end if; + else + rxDetectLtsRaw(i) <= '0'; + rxDetectInvertRaw(i) <= '0'; + rxDetectOpCodeEnRaw(i) <= '0'; + rxDetectSOCRaw(i) <= '0'; + rxDetectSOFRaw(i) <= '0'; + rxDetectEOCRaw(i) <= '0'; + rxDetectEOFRaw(i) <= '0'; + rxDetectEOFERaw(i) <= '0'; + end if; + end process; + end generate; + + -- Generate Loop for unused lanes + GEN_SPARE: for i in RxLaneCnt to 3 generate + rxDetectLtsRaw(i) <= '0'; + rxDetectOpCodeEnRaw(i) <= '0'; + rxDetectSOCRaw(i) <= '0'; + rxDetectSOFRaw(i) <= '0'; + rxDetectEOCRaw(i) <= '0'; + rxDetectEOFRaw(i) <= '0'; + rxDetectEOFERaw(i) <= '0'; + end generate; + + ----------------------------- + -- Debug + ----------------------------- + + -- Upper debug bits + GEN_DBGA: if RxLaneCnt > 1 generate + dbgInvert(1) <= rxDetectInvert(1); + dbgPolarity(1) <= intRxPolarity(1); + dbgRxDataK(3 downto 2) <= dly0RxDataK(3 downto 2); + dbgRxData(31 downto 16) <= dly0RxData(31 downto 16); + dbgRxDispErr(3 downto 2) <= phyRxDispErr(3 downto 2); + dbgRxDecErr(3 downto 2) <= phyRxDecErr(3 downto 2); + end generate; + GEN_DBGB: if RxLaneCnt = 1 generate + dbgInvert(1) <= '0'; + dbgPolarity(1) <= '0'; + dbgRxDataK(3 downto 2) <= (others=>'0'); + dbgRxData(31 downto 16) <= (others=>'0'); + dbgRxDispErr(3 downto 2) <= (others=>'0'); + dbgRxDecErr(3 downto 2) <= (others=>'0'); + end generate; + dbgInvert(0) <= rxDetectInvert(0); + dbgPolarity(0) <= intRxPolarity(0); + dbgRxDataK(1 downto 0) <= dly0RxDataK(1 downto 0); + dbgRxData(15 downto 0) <= dly0RxData(15 downto 0); + dbgRxDispErr(1 downto 0) <= phyRxDispErr(1 downto 0); + dbgRxDecErr(1 downto 0) <= phyRxDecErr(1 downto 0); + + -- Debug + debug(63 downto 32) <= dbgRxData; + debug(31 downto 28) <= dbgRxDataK; + debug(27 downto 26) <= dbgInvert; + debug(25 downto 24) <= dbgPolarity; + debug(23 downto 21) <= curState; + debug(20) <= ltsCntEn; + debug(19) <= ltsCntRst; + debug(18) <= rxDetectSOF; + debug(17) <= rxDetectEOF; + debug(16) <= phyRxReady; + debug(15 downto 12) <= dbgRxDispErr; + debug(11 downto 8) <= dbgRxDecErr; + debug(7) <= rxDetectRemLink; + debug(6) <= intRxInit; + debug(5) <= rxDetectSOC; + debug(4) <= rxDetectEOC; + debug(3) <= rxDetectLtsOk; + debug(2) <= rxDetectLts; + debug(1) <= rxDetectOpCodeEn; + debug(0) <= intRxLinkReady; + +end Pgp2RxPhy; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Tx.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Tx.vhd new file mode 100755 index 0000000000000000000000000000000000000000..50d7c58e2b433fa16792f486c96a84812ec3e8e4 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2Tx.vhd @@ -0,0 +1,241 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Top Level Transmit Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Tx.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- Top Level Transmit interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +-- 01/13/2010: Added received init line to help linking. +-- 06/25/2010: Added payload size config as generic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2Tx is + generic ( + TxLaneCnt : integer := 4; -- Number of receive lanes, 1-4 + VcInterleave : integer := 1; -- Interleave Frames + PayloadCntTop : integer := 7 -- Top bit for payload counter + ); + port ( + + -- System clock, reset & control + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + + -- Link flush + pgpTxFlush : in std_logic; -- Flush the link + + -- Link is ready + pgpTxLinkReady : out std_logic; -- Local side has link + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Sideband data + pgpLocLinkReady : in std_logic; -- Far end side has link + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Physical Interface + phyTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- PHY receive data + phyTxDataK : out std_logic_vector(TxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyTxReady : in std_logic; -- PHY receive interface is ready + + -- Transmit CRC Interface + crcTxIn : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxOut : in std_logic_vector(31 downto 0); -- Transmit calculated CRC value + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Tx; + + +-- Define architecture +architecture Pgp2Tx of Pgp2Tx is + + -- Local Signals + signal cellTxSOC : std_logic; + signal cellTxSOF : std_logic; + signal cellTxEOC : std_logic; + signal cellTxEOF : std_logic; + signal cellTxEOFE : std_logic; + signal cellTxData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal schTxSOF : std_logic; + signal schTxEOF : std_logic; + signal schTxIdle : std_logic; + signal schTxReq : std_logic; + signal schTxAck : std_logic; + signal schTxDataVc : std_logic_vector(1 downto 0); + signal intTxLinkReady : std_logic; + +begin + + -- Link Ready + pgpTxLinkReady <= intTxLinkReady; + + -- Physical Interface + U_Pgp2TxPhy: Pgp2TxPhy + generic map ( + TxLaneCnt => TxLaneCnt + ) port map ( + pgpTxClk => pgpTxClk, + pgpTxReset => pgpTxReset, + pgpTxLinkReady => intTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpLocLinkReady, + pgpLocData => pgpLocData, + cellTxSOC => cellTxSOC, + cellTxSOF => cellTxSOF, + cellTxEOC => cellTxEOC, + cellTxEOF => cellTxEOF, + cellTxEOFE => cellTxEOFE, + cellTxData => cellTxData, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + debug => debug + ); + + + -- Scheduler + U_Pgp2TxSched: Pgp2TxSched + generic map ( + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpTxClk, + pgpTxReset => pgpTxReset, + pgpTxFlush => pgpTxFlush, + pgpTxLinkReady => intTxLinkReady, + schTxSOF => schTxSOF, + schTxEOF => schTxEOF, + schTxIdle => schTxIdle, + schTxReq => schTxReq, + schTxAck => schTxAck, + schTxDataVc => schTxDataVc, + vc0FrameTxValid => vc0FrameTxValid, + vc1FrameTxValid => vc1FrameTxValid, + vc2FrameTxValid => vc2FrameTxValid, + vc3FrameTxValid => vc3FrameTxValid + ); + + + -- Cell Transmitter + U_Pgp2TxCell: Pgp2TxCell + generic map ( + TxLaneCnt => TxLaneCnt + ) port map ( + pgpTxClk => pgpTxClk, + pgpTxReset => pgpTxReset, + pgpTxLinkReady => intTxLinkReady, + cellTxSOC => cellTxSOC, + cellTxSOF => cellTxSOF, + cellTxEOC => cellTxEOC, + cellTxEOF => cellTxEOF, + cellTxEOFE => cellTxEOFE, + cellTxData => cellTxData, + schTxSOF => schTxSOF, + schTxEOF => schTxEOF, + schTxIdle => schTxIdle, + schTxReq => schTxReq, + schTxAck => schTxAck, + schTxDataVc => schTxDataVc, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut + ); + +end Pgp2Tx; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxCell.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxCell.vhd new file mode 100755 index 0000000000000000000000000000000000000000..16e507bc03d387af0e835a27e4efb6a34b5203a4 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxCell.vhd @@ -0,0 +1,655 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Cell Transmit Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2TxCell.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- Cell Transmit interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +-- 06/25/2010: Added payload size config as generic. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2TxCell is + generic ( + TxLaneCnt : integer := 4; -- Number of receive lanes, 1-4 + PayloadCntTop : integer := 7 -- Top bit for payload counter + ); + port ( + + -- System clock, reset & control + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + + -- Link is ready + pgpTxLinkReady : in std_logic; -- Local side has link + + -- Phy Transmit Interface + cellTxSOC : out std_logic; -- Cell data start of cell + cellTxSOF : out std_logic; -- Cell data start of frame + cellTxEOC : out std_logic; -- Cell data end of cell + cellTxEOF : out std_logic; -- Cell data end of frame + cellTxEOFE : out std_logic; -- Cell data end of frame error + cellTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- Cell data data + + -- Transmit Scheduler Interface + schTxSOF : out std_logic; -- Cell contained SOF + schTxEOF : out std_logic; -- Cell contained EOF + schTxIdle : in std_logic; -- Force IDLE transmit + schTxReq : in std_logic; -- Cell transmit request + schTxAck : out std_logic; -- Cell transmit acknowledge + schTxDataVc : in std_logic_vector(1 downto 0); -- Cell transmit virtual channel + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Transmit CRC Interface + crcTxIn : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- Transmit data for CRC + crcTxInit : out std_logic; -- Transmit CRC value init + crcTxValid : out std_logic; -- Transmit data for CRC is valid + crcTxOut : in std_logic_vector(31 downto 0) -- Transmit calculated CRC value + ); + +end Pgp2TxCell; + + +-- Define architecture +architecture Pgp2TxCell of Pgp2TxCell is + + -- Local Signals + signal muxFrameTxValid : std_logic; + signal muxFrameTxSOF : std_logic; + signal muxFrameTxEOF : std_logic; + signal muxFrameTxEOFE : std_logic; + signal muxFrameTxData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal cellCnt : std_logic_vector(PayloadCntTop downto 0); + signal cellCntRst : std_logic; + signal nxtFrameTxReady : std_logic; + signal nxtType : std_logic_vector(2 downto 0); + signal nxtTypeLast : std_logic_vector(2 downto 0); + signal curTypeLast : std_logic_vector(2 downto 0); + signal nxtTxSOF : std_logic; + signal nxtTxEOF : std_logic; + signal nxtTxAck : std_logic; + signal nxtData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal eocWord : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal socWord : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal crcWordA : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal crcWordB : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal serialCntEn : std_logic; + signal vc0Serial : std_logic_vector(5 downto 0); + signal vc1Serial : std_logic_vector(5 downto 0); + signal vc2Serial : std_logic_vector(5 downto 0); + signal vc3Serial : std_logic_vector(5 downto 0); + signal muxSerial : std_logic_vector(5 downto 0); + signal dly0Data : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dly0Type : std_logic_vector(2 downto 0); + signal dly1Data : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dly1Type : std_logic_vector(2 downto 0); + signal dly2Data : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dly2Type : std_logic_vector(2 downto 0); + signal dly3Data : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dly3Type : std_logic_vector(2 downto 0); + signal dly4Data : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dly4Type : std_logic_vector(2 downto 0); + signal int0FrameTxReady : std_logic; + signal int1FrameTxReady : std_logic; + signal int2FrameTxReady : std_logic; + signal int3FrameTxReady : std_logic; + + -- Transmit Data Marker + constant TX_DATA : std_logic_vector(2 downto 0) := "000"; + constant TX_SOC : std_logic_vector(2 downto 0) := "001"; + constant TX_SOF : std_logic_vector(2 downto 0) := "010"; + constant TX_EOC : std_logic_vector(2 downto 0) := "011"; + constant TX_EOF : std_logic_vector(2 downto 0) := "100"; + constant TX_EOFE : std_logic_vector(2 downto 0) := "101"; + constant TX_CRCA : std_logic_vector(2 downto 0) := "110"; + constant TX_CRCB : std_logic_vector(2 downto 0) := "111"; + + -- Transmit states + signal curState : std_logic_vector(2 downto 0); + signal nxtState : std_logic_vector(2 downto 0); + constant ST_IDLE : std_logic_vector(2 downto 0) := "001"; + constant ST_EMPTY : std_logic_vector(2 downto 0) := "010"; + constant ST_SOC : std_logic_vector(2 downto 0) := "011"; + constant ST_DATA : std_logic_vector(2 downto 0) := "100"; + constant ST_CRCA : std_logic_vector(2 downto 0) := "101"; + constant ST_CRCB : std_logic_vector(2 downto 0) := "110"; + constant ST_EOC : std_logic_vector(2 downto 0) := "111"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- Mux incoming data + process ( vc0FrameTxValid, vc0FrameTxSOF, vc0FrameTxEOF, vc0FrameTxEOFE, vc0FrameTxData, + vc1FrameTxValid, vc1FrameTxSOF, vc1FrameTxEOF, vc1FrameTxEOFE, vc1FrameTxData, + vc2FrameTxValid, vc2FrameTxSOF, vc2FrameTxEOF, vc2FrameTxEOFE, vc2FrameTxData, + vc3FrameTxValid, vc3FrameTxSOF, vc3FrameTxEOF, vc3FrameTxEOFE, vc3FrameTxData, + vc0Serial, vc1Serial, vc2Serial, vc3Serial, schTxDataVc ) begin + case schTxDataVc is + when "00" => + muxFrameTxValid <= vc0FrameTxValid; + muxFrameTxSOF <= vc0FrameTxSOF; + muxFrameTxEOF <= vc0FrameTxEOF; + muxFrameTxEOFE <= vc0FrameTxEOFE; + muxFrameTxData <= vc0FrameTxData; + muxSerial <= vc0Serial; + when "01" => + muxFrameTxValid <= vc1FrameTxValid; + muxFrameTxSOF <= vc1FrameTxSOF; + muxFrameTxEOF <= vc1FrameTxEOF; + muxFrameTxEOFE <= vc1FrameTxEOFE; + muxFrameTxData <= vc1FrameTxData; + muxSerial <= vc1Serial; + when "10" => + muxFrameTxValid <= vc2FrameTxValid; + muxFrameTxSOF <= vc2FrameTxSOF; + muxFrameTxEOF <= vc2FrameTxEOF; + muxFrameTxEOFE <= vc2FrameTxEOFE; + muxFrameTxData <= vc2FrameTxData; + muxSerial <= vc2Serial; + when others => + muxFrameTxValid <= vc3FrameTxValid; + muxFrameTxSOF <= vc3FrameTxSOF; + muxFrameTxEOF <= vc3FrameTxEOF; + muxFrameTxEOFE <= vc3FrameTxEOFE; + muxFrameTxData <= vc3FrameTxData; + muxSerial <= vc3Serial; + end case; + end process; + + + -- Choose data for SOF & EOF Positions + GEN_DATA: for i in 0 to (TxLaneCnt-1) generate + + -- SOF, vc number and serial number + socWord(i*16+15 downto i*16+14) <= schTxDataVc; + socWord(i*16+13 downto i*16+8) <= muxSerial; + socWord(i*16+7 downto i*16) <= (others=>'0'); + + -- EOF, buffer status + eocWord(i*16+15 downto i*16+12) <= vc3LocBuffFull & vc2LocBuffFull & vc1LocBuffFull & vc0LocBuffFull; + eocWord(i*16+11 downto i*16+8) <= vc3LocBuffAFull & vc2LocBuffAFull & vc1LocBuffAFull & vc0LocBuffAFull; + eocWord(i*16+7 downto i*16) <= (others=>'0'); + end generate; + + + -- Simple state machine to control transmission of data frames + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + curState <= ST_IDLE after tpd; + cellCnt <= (others=>'0') after tpd; + int0FrameTxReady <= '0' after tpd; + int1FrameTxReady <= '0' after tpd; + int2FrameTxReady <= '0' after tpd; + int3FrameTxReady <= '0' after tpd; + schTxSOF <= '0' after tpd; + schTxEOF <= '0' after tpd; + schTxAck <= '0' after tpd; + vc0Serial <= (others=>'0') after tpd; + vc1Serial <= (others=>'0') after tpd; + vc2Serial <= (others=>'0') after tpd; + vc3Serial <= (others=>'0') after tpd; + curTypeLast <= (others=>'0') after tpd; + elsif rising_edge(pgpTxClk) then + + -- State control + if pgpTxLinkReady = '0' then + curState <= ST_IDLE after tpd; + else + curState <= nxtState after tpd; + end if; + + -- Payload Counter + if cellCntRst = '1' then + cellCnt <= (others=>'1') after tpd; + elsif cellCnt /= 0 then + cellCnt <= cellCnt - 1 after tpd; + end if; + + -- Outgoing ready signal + case schTxDataVc is + when "00" => + int0FrameTxReady <= nxtFrameTxReady after tpd; + int1FrameTxReady <= '0' after tpd; + int2FrameTxReady <= '0' after tpd; + int3FrameTxReady <= '0' after tpd; + when "01" => + int0FrameTxReady <= '0' after tpd; + int1FrameTxReady <= nxtFrameTxReady after tpd; + int2FrameTxReady <= '0' after tpd; + int3FrameTxReady <= '0' after tpd; + when "10" => + int0FrameTxReady <= '0' after tpd; + int1FrameTxReady <= '0' after tpd; + int2FrameTxReady <= nxtFrameTxReady after tpd; + int3FrameTxReady <= '0' after tpd; + when others => + int0FrameTxReady <= '0' after tpd; + int1FrameTxReady <= '0' after tpd; + int2FrameTxReady <= '0' after tpd; + int3FrameTxReady <= nxtFrameTxReady after tpd; + end case; + + -- Update Last Type + curTypeLast <= nxtTypeLast after tpd; + + -- VC Serial Numbers + if pgpTxLinkReady = '0' then + vc0Serial <= (others=>'0') after tpd; + vc1Serial <= (others=>'0') after tpd; + vc2Serial <= (others=>'0') after tpd; + vc3Serial <= (others=>'0') after tpd; + elsif serialCntEn = '1' then + case schTxDataVc is + when "00" => vc0Serial <= vc0Serial + 1 after tpd; + when "01" => vc1Serial <= vc1Serial + 1 after tpd; + when "10" => vc2Serial <= vc2Serial + 1 after tpd; + when others => vc3Serial <= vc3Serial + 1 after tpd; + end case; + end if; + + -- Scheduler Signals + schTxSOF <= nxtTxSOF after tpd; + schTxEOF <= nxtTxEOF after tpd; + schTxAck <= nxtTxAck after tpd; + + end if; + end process; + + + -- Drive TX Ready + vc0FrameTxReady <= int0FrameTxReady; + vc1FrameTxReady <= int1FrameTxReady; + vc2FrameTxReady <= int2FrameTxReady; + vc3FrameTxReady <= int3FrameTxReady; + + + -- Async state control + process ( curState, schTxIdle, schTxReq, cellCnt, eocWord, socWord, curTypeLast, + muxFrameTxValid, muxFrameTxSOF, muxFrameTxEOF, muxFrameTxEOFE, muxFrameTxData ) begin + case curState is + + -- Idle + when ST_IDLE => + cellCntRst <= '1'; + nxtFrameTxReady <= '0'; + nxtType <= TX_DATA; + nxtData <= (others=>'0'); + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtTypeLast <= (others=>'0'); + + -- Idle request + if schTxIdle = '1' then + nxtState <= ST_EMPTY; + + -- Cell transmit request + elsif schTxReq = '1' then + nxtState <= ST_SOC; + else + nxtState <= curState; + end if; + + -- Send empty cell + when ST_EMPTY => + cellCntRst <= '1'; + nxtFrameTxReady <= '0'; + nxtType <= TX_EOC; + nxtTxSOF <= '0'; + nxtTxEOF <= '0'; + nxtTxAck <= '1'; + serialCntEn <= '0'; + nxtData <= eocWord; + nxtTypeLast <= (others=>'0'); + + -- Go back to idle + nxtState <= ST_IDLE; + + -- Send first charactor of cell, assert ready + when ST_SOC => + cellCntRst <= '1'; + nxtFrameTxReady <= '1'; + nxtTxEOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtData <= socWord; + nxtTypeLast <= (others=>'0'); + + -- Determine type + if muxFrameTxSOF = '1' then + nxtType <= TX_SOF; + nxtTxSOF <= '1'; + else + nxtType <= TX_SOC; + nxtTxSOF <= '0'; + end if; + + -- Move on to normal data + nxtState <= ST_DATA; + + -- Send data + when ST_DATA => + cellCntRst <= '0'; + nxtTxEOF <= '0'; + nxtTxSOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtData <= muxFrameTxData; + nxtType <= TX_DATA; + + -- Valid is de-asserted + if muxFrameTxValid = '0' then + nxtTypeLast <= TX_EOC; + nxtFrameTxReady <= '0'; + nxtType <= TX_CRCA; + + -- One or two CRC words? + if TxLaneCnt = 1 then + nxtState <= ST_CRCB; + else + nxtState <= ST_EOC; + end if; + else + nxtType <= TX_DATA; + + -- EOFE is asserted + if muxFrameTxEOFE = '1' then + nxtTypeLast <= TX_EOFE; + nxtState <= ST_CRCA; + nxtFrameTxReady <= '0'; + + -- EOF is asserted + elsif muxFrameTxEOF = '1' then + nxtTypeLast <= TX_EOF; + nxtState <= ST_CRCA; + nxtFrameTxReady <= '0'; + + -- Cell size reached + elsif cellCnt = 0 then + nxtTypeLast <= TX_EOC; + nxtState <= ST_CRCA; + nxtFrameTxReady <= '0'; + + -- Keep sending cell data + else + nxtTypeLast <= curTypeLast; + nxtState <= curState; + nxtFrameTxReady <= '1'; + nxtType <= TX_DATA; + end if; + end if; + + -- Send CRC A + when ST_CRCA => + cellCntRst <= '1'; + nxtTxEOF <= '0'; + nxtTxSOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtData <= (others=>'0'); + nxtType <= TX_CRCA; + nxtTypeLast <= curTypeLast; + nxtFrameTxReady <= '0'; + + -- One or two CRC words? + if TxLaneCnt = 1 then + nxtState <= ST_CRCB; + else + nxtState <= ST_EOC; + end if; + + -- Send CRC B + when ST_CRCB => + cellCntRst <= '1'; + nxtTxEOF <= '0'; + nxtTxSOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtData <= (others=>'0'); + nxtType <= TX_CRCB; + nxtTypeLast <= curTypeLast; + nxtFrameTxReady <= '0'; + nxtState <= ST_EOC; + + -- Send End of Cell + when ST_EOC => + cellCntRst <= '1'; + nxtTxSOF <= '0'; + nxtTxAck <= '1'; + serialCntEn <= '1'; + nxtData <= eocWord; + nxtType <= curTypeLast; + nxtTypeLast <= curTypeLast; + nxtFrameTxReady <= '0'; + nxtState <= ST_IDLE; + + -- EOF? + if curTypeLast /= TX_EOC then + nxtTxEOF <= '1'; + else + nxtTxEOF <= '0'; + end if; + + -- Default State + when others => + cellCntRst <= '0'; + nxtTxEOF <= '0'; + nxtTxSOF <= '0'; + nxtTxAck <= '0'; + serialCntEn <= '0'; + nxtData <= (others=>'0'); + nxtType <= (others=>'0'); + nxtTypeLast <= (others=>'0'); + nxtFrameTxReady <= '0'; + nxtState <= ST_IDLE; + end case; + end process; + + + -- Delay chain to allow CRC data to catch up. + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + dly0Data <= (others=>'0'); + dly0Type <= (others=>'0'); + dly1Data <= (others=>'0'); + dly1Type <= (others=>'0'); + dly2Data <= (others=>'0'); + dly2Type <= (others=>'0'); + dly3Data <= (others=>'0'); + dly3Type <= (others=>'0'); + dly4Data <= (others=>'0'); + dly4Type <= (others=>'0'); + elsif rising_edge(pgpTxClk) then + + -- Delay stage 1 + dly0Data <= nxtData after tpd; + dly0Type <= nxtType after tpd; + + -- Delay stage 2 + dly1Data <= dly0Data after tpd; + dly1Type <= dly0Type after tpd; + + -- Delay stage 3 + dly2Data <= dly1Data after tpd; + dly2Type <= dly1Type after tpd; + + -- Delay stage 3 + dly3Data <= dly2Data after tpd; + dly3Type <= dly2Type after tpd; + + -- Delay stage 3 + dly4Data <= dly3Data after tpd; + dly4Type <= dly3Type after tpd; + end if; + end process; + + + -- Output to CRC engine + crcTxIn <= dly0Data; + crcTxInit <= '1' when (dly0Type = TX_SOC or dly0Type = TX_SOF) else '0'; + crcTxValid <= '1' when (dly0Type = TX_SOC or dly0Type = TX_SOF or dly0Type = TX_DATA) else '0'; + + + -- CRC Data, Single lane, split into two 16-bit values + GEN_CRC_NARROW: if TxLaneCnt = 1 generate + crcWordA(7 downto 0) <= crcTxOut(31 downto 24); + crcWordA(15 downto 8) <= crcTxOut(23 downto 16); + crcWordB(7 downto 0) <= crcTxOut(15 downto 8); + crcWordB(15 downto 8) <= crcTxOut(7 downto 0); + end generate; + + -- CRC Data, Multi lane, send one 32-bit value + GEN_CRC_WIDE: if TxLaneCnt /= 1 generate + crcWordA(7 downto 0) <= crcTxOut(31 downto 24); + crcWordA(15 downto 8) <= crcTxOut(23 downto 16); + crcWordA(23 downto 16) <= crcTxOut(15 downto 8); + crcWordA(31 downto 24) <= crcTxOut(7 downto 0); + crcWordB(31 downto 0) <= (others=>'0'); + end generate; + + -- CRC Data, 3 or 4 lanes, Set upper bits to 0. + GEN_CRC_OTHER: if TxLaneCnt >= 3 generate + crcWordA(TxLaneCnt*16-1 downto 32) <= (others=>'0'); + crcWordB(TxLaneCnt*16-1 downto 32) <= (others=>'0'); + end generate; + + -- Output stage + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= (others=>'0') after tpd; + elsif rising_edge(pgpTxClk) then + + -- Which data type + case dly2Type is + when TX_DATA => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= dly2Data after tpd; + when TX_SOC => + cellTxSOC <= '1' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= dly2Data after tpd; + when TX_SOF => + cellTxSOC <= '1' after tpd; + cellTxSOF <= '1' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= dly2Data after tpd; + when TX_CRCA => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= crcWordA after tpd; + when TX_CRCB => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= crcWordB after tpd; + when TX_EOC => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '1' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= dly2Data after tpd; + when TX_EOF => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '1' after tpd; + cellTxEOF <= '1' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= dly2Data after tpd; + when TX_EOFE => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '1' after tpd; + cellTxEOF <= '1' after tpd; + cellTxEOFE <= '1' after tpd; + cellTxData <= dly2Data after tpd; + when others => + cellTxSOC <= '0' after tpd; + cellTxSOF <= '0' after tpd; + cellTxEOC <= '0' after tpd; + cellTxEOF <= '0' after tpd; + cellTxEOFE <= '0' after tpd; + cellTxData <= (others=>'0') after tpd; + end case; + end if; + end process; + +end Pgp2TxCell; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxPhy.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxPhy.vhd new file mode 100755 index 0000000000000000000000000000000000000000..a1e99ac855bd6ed37fdf7bad5fb8c3753ff88f98 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxPhy.vhd @@ -0,0 +1,413 @@ +--------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol V2, Physical Interface Transmit Module +-- Project : General Purpose Core +--------------------------------------------------------------------------------- +-- File : Pgp2TxPhy.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +--------------------------------------------------------------------------------- +-- Description: +-- Physical interface receive module for the Pretty Good Protocol version 2 core. +--------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +--------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +-- 11/23/2009: Renamed package. +--------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2TxPhy is + generic ( + TxLaneCnt : integer := 4 -- Number of receive lanes, 1-4 + ); + port ( + + -- System clock, reset & control + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + + -- Link is ready + pgpTxLinkReady : out std_logic; -- Local side has link + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Sideband data + pgpLocLinkReady : in std_logic; -- Far end side has link + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Cell Transmit Interface + cellTxSOC : in std_logic; -- Cell data start of cell + cellTxSOF : in std_logic; -- Cell data start of frame + cellTxEOC : in std_logic; -- Cell data end of cell + cellTxEOF : in std_logic; -- Cell data end of frame + cellTxEOFE : in std_logic; -- Cell data end of frame error + cellTxData : in std_logic_vector(TxLaneCnt*16-1 downto 0); -- Cell data data + + -- Physical Interface Signals + phyTxData : out std_logic_vector(TxLaneCnt*16-1 downto 0); -- PHY receive data + phyTxDataK : out std_logic_vector(TxLaneCnt*2-1 downto 0); -- PHY receive data is K character + phyTxReady : in std_logic; -- PHY receive interface is ready + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2TxPhy; + + +-- Define architecture +architecture Pgp2TxPhy of Pgp2TxPhy is + + -- Local Signals + signal algnCnt : std_logic_vector(6 downto 0); + signal algnCntRst : std_logic; + signal intTxLinkReady : std_logic; + signal nxtTxLinkReady : std_logic; + signal nxtTxData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal nxtTxDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal dlyTxData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal dlyTxDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal dlySelect : std_logic; + signal intTxData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal intTxDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal intTxOpCode : std_logic_vector(7 downto 0); + signal intTxOpCodeEn : std_logic; + signal skpAData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal skpADataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal skpBData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal skpBDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal alnAData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal alnADataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal alnBData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal alnBDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal ltsAData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal ltsADataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal ltsBData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal ltsBDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal cellData : std_logic_vector(TxLaneCnt*16-1 downto 0); + signal cellDataK : std_logic_vector(TxLaneCnt*2-1 downto 0); + signal dlyTxEOC : std_logic; + + -- Physical Link State + constant ST_LOCK : std_logic_vector(3 downto 0) := "0000"; + constant ST_SKP_A : std_logic_vector(3 downto 0) := "0001"; + constant ST_SKP_B : std_logic_vector(3 downto 0) := "0010"; + constant ST_LTS_A : std_logic_vector(3 downto 0) := "0011"; + constant ST_LTS_B : std_logic_vector(3 downto 0) := "0100"; + constant ST_ALN_A : std_logic_vector(3 downto 0) := "0101"; + constant ST_ALN_B : std_logic_vector(3 downto 0) := "0110"; + constant ST_CELL : std_logic_vector(3 downto 0) := "0111"; + constant ST_EMPTY : std_logic_vector(3 downto 0) := "1000"; + signal curState : std_logic_vector(3 downto 0); + signal nxtState : std_logic_vector(3 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Link status + pgpTxLinkReady <= intTxLinkReady; + + -- State transition sync logic. + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + curState <= ST_LOCK after tpd; + algnCnt <= (others=>'0') after tpd; + intTxLinkReady <= '0' after tpd; + intTxOpCode <= (others=>'0') after tpd; + intTxOpCodeEn <= '0' after tpd; + elsif rising_edge(pgpTxClk) then + + -- Opcode Transmit + if pgpTxOpCodeEn = '1' then + intTxOpCode <= pgpTxOpCode after tpd; + end if; + intTxOpCodeEn <= pgpTxOpCodeEn after tpd; + + -- Status signal + intTxLinkReady <= nxtTxLinkReady after tpd; + + -- PLL Lock is lost + if phyTxReady = '0' then + curState <= ST_LOCK after tpd; + else + curState <= nxtState after tpd; + end if; + + -- Cell Counter + if algnCntRst = '1' then + algnCnt <= (others=>'1') after tpd; + elsif algnCnt /= 0 and cellTxEOC = '1' then + algnCnt <= algnCnt - 1 after tpd; + end if; + end if; + end process; + + + -- Link control state machine + process ( curState, intTxLinkReady, cellTxEOC, algnCnt, + skpAData, skpADataK, skpBData, skpBDataK, alnAData, alnADataK, alnBData, + alnBDataK, ltsAData, ltsADataK, ltsBData, ltsBDataK, cellData, cellDataK ) begin + case curState is + + -- Wait for lock state + when ST_LOCK => + algnCntRst <= '1'; + nxtTxLinkReady <= '0'; + nxtTxData <= (others=>'0'); + nxtTxDataK <= (others=>'0'); + nxtState <= ST_SKP_A; + + -- Transmit SKIP word A + when ST_SKP_A => + nxtTxData <= skpAData; + nxtTxDataK <= skpADataK; + algnCntRst <= '0'; + nxtTxLinkReady <= intTxLinkReady; + nxtState <= ST_SKP_B; + + -- Transmit SKIP word B + when ST_SKP_B => + nxtTxData <= skpBData; + nxtTxDataK <= skpBDataK; + algnCntRst <= '0'; + nxtTxLinkReady <= intTxLinkReady; + nxtState <= ST_LTS_A; + + -- Transmit Align word A + when ST_ALN_A => + nxtTxData <= alnAData; + nxtTxDataK <= alnADataK; + algnCntRst <= '0'; + nxtTxLinkReady <= intTxLinkReady; + nxtState <= ST_ALN_B; + + -- Transmit Align word B + when ST_ALN_B => + nxtTxData <= alnBData; + nxtTxDataK <= alnBDataK; + algnCntRst <= '0'; + nxtTxLinkReady <= intTxLinkReady; + nxtState <= ST_LTS_A; + + -- Transmit Link Training word A + when ST_LTS_A => + nxtTxData <= ltsAData; + nxtTxDataK <= ltsADataK; + algnCntRst <= '0'; + nxtTxLinkReady <= intTxLinkReady; + nxtState <= ST_LTS_B; + + -- Transmit Link Training word B + when ST_LTS_B => + nxtTxData <= ltsBData; + nxtTxDataK <= ltsBDataK; + algnCntRst <= '0'; + nxtTxLinkReady <= '1'; + nxtState <= ST_CELL; + + -- Transmit Cell Data + when ST_CELL => + nxtTxLinkReady <= '1'; + nxtTxData <= cellData; + nxtTxDataK <= cellDataK; + algnCntRst <= '0'; + + -- State transition + if cellTxEOC = '1' then + nxtState <= ST_EMPTY; + else + nxtState <= curState; + end if; + + -- Empty location, used to re-adjust delay pipeline + when ST_EMPTY => + nxtTxLinkReady <= '1'; + nxtTxData <= (others=>'0'); + nxtTxDataK <= (others=>'0'); + + -- After enough cells send alignment word + if algnCnt = 0 then + algnCntRst <= '1'; + nxtState <= ST_ALN_A; + else + algnCntRst <= '0'; + nxtState <= ST_SKP_A; + end if; + + -- Default state + when others => + algnCntRst <= '0'; + nxtTxLinkReady <= '0'; + nxtTxData <= (others=>'0'); + nxtTxDataK <= (others=>'0'); + nxtState <= ST_LOCK; + end case; + end process; + + + -- Generate Data + GEN_DATA: for i in 0 to (TxLaneCnt-1) generate + + -- Skip word A + skpAData(i*16+7 downto i*16) <= K_COM; + skpADataK(i*2) <= '1'; + skpAData(i*16+15 downto i*16+8) <= K_SKP; + skpADataK(i*2+1) <= '1'; + + -- Skip word B + skpBData(i*16+7 downto i*16) <= K_SKP; + skpBDataK(i*2) <= '1'; + skpBData(i*16+15 downto i*16+8) <= K_SKP; + skpBDataK(i*2+1) <= '1'; + + -- Alignment Word A + alnAData(i*16+7 downto i*16) <= K_COM; + alnADataK(i*2) <= '1'; + alnAData(i*16+15 downto i*16+8) <= K_ALN; + alnADataK(i*2+1) <= '1'; + + -- Alignment Word B + alnBData(i*16+7 downto i*16) <= K_ALN; + alnBDataK(i*2) <= '1'; + alnBData(i*16+15 downto i*16+8) <= K_ALN; + alnBDataK(i*2+1) <= '1'; + + -- Link Training Word A + ltsAData(i*16+7 downto i*16) <= K_LTS; + ltsADataK(i*2) <= '1'; + ltsAData(i*16+15 downto i*16+8) <= D_102; + ltsADataK(i*2+1) <= '0'; + + -- Link Training Word B + ltsBData(i*16+7 downto i*16) <= pgpLocData; + ltsBDataK(i*2) <= '0'; + ltsBData(i*16+14) <= '0'; -- Spare + ltsBData(i*16+13 downto i*16+12) <= conv_std_logic_vector(TxLaneCnt-1,2); + ltsBData(i*16+11 downto i*16+8) <= pgp2Id; + ltsBData(i*16+15) <= pgpLocLinkReady; + ltsBDataK(i*2+1) <= '0'; + + -- Cell Data, lower byte + cellData(i*16+7 downto i*16) <= K_SOF when cellTxSOF = '1' else + K_SOC when cellTxSOC = '1' else + K_EOFE when cellTxEOFE = '1' else + K_EOF when cellTxEOF = '1' else + K_EOC when cellTxEOC = '1' else + cellTxData(i*16+7 downto i*16); + + -- Cell Data, upper byte + cellData(i*16+15 downto i*16+8) <= cellTxData(i*16+15 downto i*16+8); + + -- Cell Data, lower control + cellDataK(i*2) <= '1' when cellTxSOF = '1' or cellTxSOC = '1' or cellTxEOFE = '1' or + cellTxEOF = '1' or cellTxEOC = '1' else '0'; + + -- Cell Data, upper control + cellDataK(i*2+1) <= '0'; + end generate; + + + -- Delay chain select, used when an opcode is transmitted. + -- opcode will overwrite current position and delay chain will + -- be selected until an EOC is transmitted. At that time the + -- non-delayed chain will be select. An empty position is inserted + -- after EOC so that valid opcodes are not lost. + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + dlySelect <= '0' after tpd; + dlyTxEOC <= '0' after tpd; + elsif rising_edge(pgpTxClk) then + + -- Choose delay chain when opcode is transmitted + if intTxOpCodeEn = '1' then + dlySelect <= '1' after tpd; + + -- Reset delay chain when delayed EOC is transmitted + elsif dlyTxEOC = '1' then + dlySelect <= '0' after tpd; + end if; + + -- Delayed copy of EOC + dlyTxEOC <= cellTxEOC after tpd; + + end if; + end process; + + + -- Outgoing data + GEN_OUT: for i in 0 to (TxLaneCnt-1) generate + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + intTxData(i*16+15 downto i*16) <= (others=>'0') after tpd; + intTxDataK(i*2+1 downto i*2) <= (others=>'0') after tpd; + dlyTxData(i*16+15 downto i*16) <= (others=>'0') after tpd; + dlyTxDataK(i*2+1 downto i*2) <= (others=>'0') after tpd; + elsif rising_edge(pgpTxClk) then + + -- Delayed copy of data + dlyTxData(i*16+15 downto i*16) <= nxtTxData(i*16+15 downto i*16) after tpd; + dlyTxDataK(i*2+1 downto i*2) <= nxtTxDataK(i*2+1 downto i*2) after tpd; + + -- PLL Lock is lost + if phyTxReady = '0' then + intTxData(i*16+15 downto i*16) <= (others=>'0') after tpd; + intTxDataK(i*2+1 downto i*2) <= (others=>'0') after tpd; + else + + -- Delayed data, opcode transmission is not allowed until delay line resets + if dlySelect = '1' then + intTxData(i*16+15 downto i*16) <= dlyTxData(i*16+15 downto i*16) after tpd; + intTxDataK(i*2+1 downto i*2) <= dlyTxDataK(i*2+1 downto i*2) after tpd; + + -- Transmit opcode + elsif intTxOpCodeEn = '1' then + intTxData(i*16+7 downto i*16) <= K_OTS after tpd; + intTxDataK(i*2) <= '1' after tpd; + intTxData(i*16+15 downto i*16+8) <= intTxOpCode after tpd; + intTxDataK(i*2+1) <= '0' after tpd; + + -- Nornal Data + else + intTxData(i*16+15 downto i*16) <= nxtTxData(i*16+15 downto i*16) after tpd; + intTxDataK(i*2+1 downto i*2) <= nxtTxDataK(i*2+1 downto i*2) after tpd; + end if; + end if; + end if; + end process; + end generate; + + -- Outgoing data + phyTxData <= intTxData; + phyTxDataK <= intTxDataK; + + -- Debug + debug(63 downto 52) <= (others=>'0'); + debug(51) <= cellTxSOC; + debug(50) <= cellTxSOF; + debug(49) <= cellTxEOF; + debug(48) <= cellTxEOFE; + debug(47 downto 32) <= cellTxData(15 downto 0); + debug(31) <= dlySelect; + debug(30) <= dlyTxEOC; + debug(29 downto 26) <= (others=>'0'); + debug(25 downto 24) <= intTxDataK(1 downto 0); + debug(23 downto 8) <= intTxData(15 downto 0); + debug(7) <= '0'; + debug(6 downto 3) <= curState; + debug(2) <= pgpTxOpCodeEn; + debug(1) <= intTxOpCodeEn; + debug(0) <= cellTxEOC; + +end Pgp2TxPhy; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxSched.vhd b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxSched.vhd new file mode 100755 index 0000000000000000000000000000000000000000..94d9b75f7fd20ebda3393aa9955f17952be3867d --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/core/Pgp2TxSched.vhd @@ -0,0 +1,257 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Transmit Scheduler +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2TxSched.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- Transmit scheduler interface module for the Pretty Good Protocol core. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/18/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE work.ALL; +USE work.Pgp2CorePackage.ALL; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2TxSched is + generic ( + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpTxClk : in std_logic; -- Master clock + pgpTxReset : in std_logic; -- Synchronous reset input + + -- Link flush + pgpTxFlush : in std_logic; -- Flush the link + + -- Link is ready + pgpTxLinkReady : in std_logic; -- Local side has link + + -- Cell Transmit Interface + schTxSOF : in std_logic; -- Cell contained SOF + schTxEOF : in std_logic; -- Cell contained EOF + schTxIdle : out std_logic; -- Force IDLE transmit + schTxReq : out std_logic; -- Cell transmit request + schTxAck : in std_logic; -- Cell transmit acknowledge + schTxDataVc : out std_logic_vector(1 downto 0); -- Cell transmit virtual channel + + -- VC Data Valid Signals + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxValid : in std_logic -- User frame data is valid + ); + +end Pgp2TxSched; + + +-- Define architecture +architecture Pgp2TxSched of Pgp2TxSched is + + -- Local Signals + signal currValid : std_logic; + signal currVc : std_logic_vector(1 downto 0); + signal nextVc : std_logic_vector(1 downto 0); + signal arbVc : std_logic_vector(1 downto 0); + signal arbValid : std_logic; + signal vcInFrame : std_logic_vector(3 downto 0); + signal intTxReq : std_logic; + signal intTxIdle : std_logic; + signal nxtTxReq : std_logic; + signal nxtTxIdle : std_logic; + + -- Schedular state + constant ST_RST : std_logic_vector(2 downto 0) := "001"; + constant ST_ARB : std_logic_vector(2 downto 0) := "010"; + constant ST_CELL : std_logic_vector(2 downto 0) := "011"; + constant ST_GAP_A : std_logic_vector(2 downto 0) := "100"; + constant ST_GAP_B : std_logic_vector(2 downto 0) := "101"; + constant ST_GAP_C : std_logic_vector(2 downto 0) := "110"; + signal curState : std_logic_vector(2 downto 0); + signal nxtState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Outgoing signals + schTxReq <= intTxReq; + schTxIdle <= intTxIdle; + schTxDataVc <= currVc; + + + -- State transition logic + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + curState <= ST_ARB after tpd; + currVc <= "00" after tpd; + intTxReq <= '0' after tpd; + intTxIdle <= '0' after tpd; + elsif rising_edge(pgpTxClk) then + + -- Force state to select state when link goes down + if pgpTxLinkReady = '0' then + curState <= ST_RST after tpd; + else + curState <= nxtState after tpd; + end if; + + -- Control signals + currVc <= nextVc after tpd; + intTxReq <= nxtTxReq after tpd; + intTxIdle <= nxtTxIdle after tpd; + + end if; + end process; + + + -- Scheduler state machine + process ( curState, arbValid, arbVc, currVc, schTxAck, vcInFrame, currValid ) begin + case curState is + + -- Held in reset due to non-link + when ST_RST => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= (others=>'0'); + nxtState <= ST_ARB; + + -- IDLE, wait for ack receiver to be ready + when ST_ARB => + + -- Non-interleave mode and current is in frame + if VcInterleave = 0 and vcInFrame(conv_integer(currVc)) = '1' then + nxtTxIdle <= not currValid; + nxtTxReq <= currValid; + nextVc <= currVc; + + -- Else use new arb winner if valid + else + nxtTxIdle <= not arbValid; + nxtTxReq <= arbValid; + nextVc <= arbVc; + end if; + nxtState <= ST_CELL; + + -- Transmit Cell Data + when ST_CELL => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= currVc; + + -- Cell is done + if schTxAck = '1' then + nxtState <= ST_GAP_A; + else + nxtState <= curState; + end if; + + -- Wait between cells + when ST_GAP_A => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= currVc; + nxtState <= ST_GAP_B; + + -- Wait between cells + when ST_GAP_B => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= currVc; + nxtState <= ST_GAP_C; + + -- Wait between cells + when ST_GAP_C => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= currVc; + nxtState <= ST_ARB; + + -- Just in case + when others => + nxtTxIdle <= '0'; + nxtTxReq <= '0'; + nextVc <= (others=>'0'); + nxtState <= ST_ARB; + end case; + end process; + + + -- Current owner has valid asserted + currValid <= vc0FrameTxValid when currVc = "00" else + vc1FrameTxValid when currVc = "01" else + vc2FrameTxValid when currVc = "10" else + vc3FrameTxValid; + + + -- Arbitrate for the next VC value based upon current VC value and status of valid inputs + process ( currVc, vc0FrameTxValid, vc1FrameTxValid, vc2FrameTxValid, vc3FrameTxValid ) begin + case currVc is + when "00" => + if vc1FrameTxValid = '1' then arbVc <= "01"; arbValid <= '1'; + elsif vc2FrameTxValid = '1' then arbVc <= "10"; arbValid <= '1'; + elsif vc3FrameTxValid = '1' then arbVc <= "11"; arbValid <= '1'; + elsif vc0FrameTxValid = '1' then arbVc <= "00"; arbValid <= '1'; + else arbVc <= currVc; arbValid <= '0'; end if; + when "01" => + if vc2FrameTxValid = '1' then arbVc <= "10"; arbValid <= '1'; + elsif vc3FrameTxValid = '1' then arbVc <= "11"; arbValid <= '1'; + elsif vc0FrameTxValid = '1' then arbVc <= "00"; arbValid <= '1'; + elsif vc1FrameTxValid = '1' then arbVc <= "01"; arbValid <= '1'; + else arbVc <= currVc; arbValid <= '0'; end if; + when "10" => + if vc3FrameTxValid = '1' then arbVc <= "11"; arbValid <= '1'; + elsif vc0FrameTxValid = '1' then arbVc <= "00"; arbValid <= '1'; + elsif vc1FrameTxValid = '1' then arbVc <= "01"; arbValid <= '1'; + elsif vc2FrameTxValid = '1' then arbVc <= "10"; arbValid <= '1'; + else arbVc <= currVc; arbValid <= '0'; end if; + when "11" => + if vc0FrameTxValid = '1' then arbVc <= "00"; arbValid <= '1'; + elsif vc1FrameTxValid = '1' then arbVc <= "01"; arbValid <= '1'; + elsif vc2FrameTxValid = '1' then arbVc <= "10"; arbValid <= '1'; + elsif vc3FrameTxValid = '1' then arbVc <= "11"; arbValid <= '1'; + else arbVc <= currVc; arbValid <= '0'; end if; + when others => + arbVc <= "00"; arbValid <= '0'; + end case; + end process; + + + -- Lock in the status of the last cell transmitted + process ( pgpTxClk, pgpTxReset ) begin + if pgpTxReset = '1' then + vcInFrame <= "0000" after tpd; + elsif rising_edge(pgpTxClk) then + + -- Link is down or flush requested, reset status + if pgpTxLinkReady = '0' or pgpTxFlush = '1' then + vcInFrame <= "0000" after tpd; + else + + -- Update state of VC, track if VC is currently in frame or not + -- SOF transmitted + if schTxSOF = '1' then + vcInFrame(conv_integer(currVc)) <= '1' after tpd; + + -- EOF transmitted + elsif schTxEOF = '1' then + vcInFrame(conv_integer(currVc)) <= '0' after tpd; + end if; + end if; + end if; + end process; + +end Pgp2TxSched; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp16.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp16.vhd new file mode 100755 index 0000000000000000000000000000000000000000..ffb82400692333cc66295e9b6b6c8269bff384f5 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp16.vhd @@ -0,0 +1,861 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTP Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Gtp16.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTP and CRC blocks. +-- This module also contains the logic to control the reset of the GTP. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2Gtp16 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state flash + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- GTP loopback control + gtpLoopback : in std_logic; -- GTP Serial Loopback Control + + -- GTP Signals + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic; -- GTP Rx Recovered Clock + gtpRxN : in std_logic; -- GTP Serial Receive Negative + gtpRxP : in std_logic; -- GTP Serial Receive Positive + gtpTxN : out std_logic; -- GTP Serial Transmit Negative + gtpTxP : out std_logic; -- GTP Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Gtp16; + + +-- Define architecture +architecture Pgp2Gtp16 of Pgp2Gtp16 is + + -- Local Signals + signal crcTxIn : std_logic_vector(15 downto 0); + signal crcTxInGtp : std_logic_vector(31 downto 0); + signal crcTxInit : std_logic; + signal crcTxRst : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcTxOutGtp : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(15 downto 0); + signal crcRxInGtp : std_logic_vector(31 downto 0); + signal crcRxInit : std_logic; + signal crcRxRst : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal crcRxOutGtp : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(0 downto 0); + signal phyRxData : std_logic_vector(15 downto 0); + signal phyRxDataK : std_logic_vector(1 downto 0); + signal phyTxData : std_logic_vector(15 downto 0); + signal phyTxDataK : std_logic_vector(1 downto 0); + signal phyRxDispErr : std_logic_vector(1 downto 0); + signal phyRxDecErr : std_logic_vector(1 downto 0); + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal phyRxReset : std_logic; + signal phyRxElecIdleRst : std_logic; + signal phyRxElecIdle : std_logic; + signal phyRxCdrReset : std_logic; + signal phyRstDone : std_logic; + signal phyRxBuffStatus : std_logic_vector(2 downto 0); + signal phyTxReset : std_logic; + signal phyTxBuffStatus : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal intRxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + signal txKerr : std_logic_vector(1 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- PGP RX Block + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP TX Block + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crcTxWidth <= "001"; + crcRxWidth <= "001"; + crcRxRst <= intRxRst or crcRxInit; + crcTxRst <= intTxRst or crcTxInit; + + -- Pass CRC data in on proper bits + crcTxInGtp(31 downto 24) <= crcTxIn(7 downto 0); + crcTxInGtp(23 downto 16) <= crcTxIn(15 downto 8); + crcTxInGtp(15 downto 0) <= (others=>'0'); + crcRxInGtp(31 downto 24) <= crcRxIn(7 downto 0); + crcRxInGtp(23 downto 16) <= crcRxIn(15 downto 8); + crcRxInGtp(15 downto 0) <= (others=>'0'); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + -- Invert Output CRC + crcRxOut <= not crcRxOutGtp; + crcTxOut <= not crcTxOutGtp; + + + -- TX CRC BLock + Tx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcTxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crcTxValid, + CRCDATAWIDTH => crcTxWidth, + CRCIN => crcTxInGtp, + CRCRESET => crcTxRst + ); + + + -- RX CRC BLock + Rx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcRxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crcRxValid, + CRCDATAWIDTH => crcRxWidth, + CRCIN => crcRxInGtp, + CRCRESET => crcRxRst + ); + + + -- RX Reset Control + U_Pgp2GtpRxRst: Pgp2GtpPackage.Pgp2GtpRxRst + port map ( + gtpRxClk => pgpClk, + gtpRxRst => intRxRst, + gtpRxReady => phyRxReady, + gtpRxInit => phyRxInit, + gtpLockDetect => phyLockDetect, + gtpRxElecIdle => phyRxElecIdle, + gtpRxBuffStatus => phyRxBuffStatus, + gtpRstDone => phyRstDone, + gtpRxElecIdleRst => phyRxElecIdleRst, + gtpRxReset => phyRxReset, + gtpRxCdrReset => phyRxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtpTxRst: Pgp2GtpPackage.Pgp2GtpTxRst + port map ( + gtpTxClk => pgpClk, + gtpTxRst => intTxRst, + gtpTxReady => phyTxReady, + gtpLockDetect => phyLockDetect, + gtpTxBuffStatus => phyTxBuffStatus, + gtpRstDone => phyRstDone, + gtpTxReset => phyTxReset + ); + + + ----------------------------- GTP_DUAL Instance -------------------------- + UGtpDual:GTP_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_GTPRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + PLL_TXDIVSEL_COMM_OUT => 1, + TX_SYNC_FILTERB => 1, + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "00000", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "00000", + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + TX_DIFF_BOOST_0 => TRUE, + + TX_DIFF_BOOST_1 => TRUE, + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + + COM_BURST_VAL_1 => "1111", + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "001", + PMA_CDR_SCAN_0 => x"6c07640", + PMA_RX_CFG_0 => x"09f0089", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_MID_0 => FALSE, + RCV_TERM_VTTRX_0 => FALSE, + TERMINATION_IMP_0 => 50, + + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "001", + PMA_CDR_SCAN_1 => x"6c07640", + PMA_RX_CFG_1 => x"09f0089", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_MID_1 => FALSE, + RCV_TERM_VTTRX_1 => FALSE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => TRUE, + + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => TRUE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "1101111100", + CLK_COR_SEQ_1_2_1 => "1000111100", + CLK_COR_SEQ_1_3_1 => "1000111100", + CLK_COR_SEQ_1_4_1 => "1000111100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CHAN_BOND_1_MAX_SKEW_0 => 1, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 0, + CHAN_BOND_MODE_0 => "OFF", + CHAN_BOND_SEQ_1_1_0 => "0000000000", + CHAN_BOND_SEQ_1_2_0 => "0000000000", + CHAN_BOND_SEQ_1_3_0 => "0000000000", + CHAN_BOND_SEQ_1_4_0 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CHAN_BOND_1_MAX_SKEW_1 => 1, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "OFF", + CHAN_BOND_SEQ_1_1_1 => "0000000000", + CHAN_BOND_SEQ_1_2_1 => "0000000000", + CHAN_BOND_SEQ_1_3_1 => "0000000000", + CHAN_BOND_SEQ_1_4_1 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"0060", + TRANS_TIME_NON_P2_0 => x"0025", + TRANS_TIME_TO_P2_0 => x"0100", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"0060", + TRANS_TIME_NON_P2_1 => x"0025", + TRANS_TIME_TO_P2_1 => x"0100" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0(0) => '0', + LOOPBACK0(1) => gtpLoopback, + LOOPBACK0(2) => '0', + LOOPBACK1 => "000", + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0 => phyRxDataK, + RXCHARISK1 => open, + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0 => phyRxDispErr, + RXDISPERR1 => open, + RXNOTINTABLE0 => phyRxDecErr, + RXNOTINTABLE1 => open, + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => (others=>'0'), + RXCHBONDO0 => open, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '0', + RXENCHANSYNC1 => '0', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0 => phyRxData, + RXDATA1 => open, + RXDATAWIDTH0 => '1', + RXDATAWIDTH1 => '1', + RXRECCLK0 => intRxRecClk, + RXRECCLK1 => open, + RXRESET0 => phyRxReset, + RXRESET1 => '0', + RXUSRCLK0 => pgpClk2x, + RXUSRCLK1 => pgpClk2x, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => phyRxCdrReset, + RXCDRRESET1 => '0', + RXELECIDLE0 => phyRxElecIdle, + RXELECIDLE1 => open, + RXELECIDLERESET0 => phyRxElecIdleRst, + RXELECIDLERESET1 => '0', + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => gtpRxN, + RXN1 => '1', + RXP0 => gtpRxP, + RXP1 => '0', + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => phyRxBuffStatus, + RXBUFSTATUS1 => open, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => phyRxPolarity(0), + RXPOLARITY1 => '0', + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtpClkIn, + GTPRESET => pgpReset, + GTPTEST => (others=>'0'), + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => phyRstDone, + RESETDONE1 => open, + RXENELECIDLERESETB => '1', + TXENPMAPHASEALIGN => '0', + TXPMASETPHASE => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0 => phyTxDataK, + TXCHARISK1 => "00", + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => txKerr, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => phyTxBuffStatus, + TXBUFSTATUS1 => open, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0 => phyTxData, + TXDATA1 => (others=>'0'), + TXDATAWIDTH0 => '1', + TXDATAWIDTH1 => '1', + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => phyTxReset, + TXRESET1 => '0', + TXUSRCLK0 => pgpClk2x, + TXUSRCLK1 => pgpClk2x, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => gtpTxN, + TXN1 => open, + TXP0 => gtpTxP, + TXP1 => open, + TXPREEMPHASIS0 => "011", -- 4.5% + TXPREEMPHASIS1 => "011", + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtpRefClkOut, + I => tmpRefClkOut + ); + gtpRxRecClk <= intRxRecClk; + + +end Pgp2Gtp16; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp32.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp32.vhd new file mode 100755 index 0000000000000000000000000000000000000000..f624cf61f2210ad734683a344d0be0949d76c2bf --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2Gtp32.vhd @@ -0,0 +1,899 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTP Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Gtp32.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTP and CRC blocks. +-- This module also contains the logic to control the reset of the GTP. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2Gtp32 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame status reset + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(31 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- GTP loopback control + gtpLoopback : in std_logic; -- GTP Serial Loopback Control + + -- GTP Signals + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic; -- GTP Rx Recovered Clock + gtpRxN : in std_logic_vector(1 downto 0); -- GTP Serial Receive Negative + gtpRxP : in std_logic_vector(1 downto 0); -- GTP Serial Receive Positive + gtpTxN : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Negative + gtpTxP : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Gtp32; + + +-- Define architecture +architecture Pgp2Gtp32 of Pgp2Gtp32 is + + -- Local Signals + signal crcTxIn : std_logic_vector(31 downto 0); + signal crcTxInGtp : std_logic_vector(31 downto 0); + signal crcTxInit : std_logic; + signal crcTxRst : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcTxOutGtp : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(31 downto 0); + signal crcRxInGtp : std_logic_vector(31 downto 0); + signal crcRxInit : std_logic; + signal crcRxRst : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal crcRxOutGtp : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(1 downto 0); + signal phyRxData : std_logic_vector(31 downto 0); + signal phyRxDataK : std_logic_vector(3 downto 0); + signal phyTxData : std_logic_vector(31 downto 0); + signal phyTxDataK : std_logic_vector(3 downto 0); + signal phyRxDispErr : std_logic_vector(3 downto 0); + signal phyRxDecErr : std_logic_vector(3 downto 0); + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal intRxReady : std_logic_vector(1 downto 0); + signal phyTxReady : std_logic; + signal intTxReady : std_logic_vector(1 downto 0); + signal phyRxReset : std_logic_vector(1 downto 0); + signal phyRxElecIdleRst : std_logic_vector(1 downto 0); + signal phyRxElecIdle : std_logic_vector(1 downto 0); + signal phyRxCdrReset : std_logic_vector(1 downto 0); + signal phyRstDone : std_logic_vector(1 downto 0); + signal phyRxBuffStatusA : std_logic_vector(2 downto 0); + signal phyRxBuffStatusB : std_logic_vector(2 downto 0); + signal phyTxReset : std_logic_vector(1 downto 0); + signal phyTxBuffStatusA : std_logic_vector(1 downto 0); + signal phyTxBuffStatusB : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal intRxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + signal phyChanBond : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- PGP RX Block + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 2, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP TX Block + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 2, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crcTxWidth <= "011"; + crcRxWidth <= "011"; + crcRxRst <= intRxRst or crcRxInit; + crcTxRst <= intTxRst or crcTxInit; + + -- Pass CRC data in on proper bits + crcTxInGtp(31 downto 24) <= crcTxIn(7 downto 0); + crcTxInGtp(23 downto 16) <= crcTxIn(15 downto 8); + crcTxInGtp(15 downto 8) <= crcTxIn(23 downto 16); + crcTxInGtp(7 downto 0) <= crcTxIn(31 downto 24); + crcRxInGtp(31 downto 24) <= crcRxIn(7 downto 0); + crcRxInGtp(23 downto 16) <= crcRxIn(15 downto 8); + crcRxInGtp(15 downto 8) <= crcRxIn(23 downto 16); + crcRxInGtp(7 downto 0) <= crcRxIn(31 downto 24); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + phyRxReady <= '1' when intRxReady = "11" else '0'; + phyTxReady <= '1' when intTxReady = "11" else '0'; + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + -- Invert Output CRC + crcRxOut <= not crcRxOutGtp; + crcTxOut <= not crcTxOutGtp; + + + -- TX CRC BLock + Tx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcTxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crcTxValid, + CRCDATAWIDTH => crcTxWidth, + CRCIN => crcTxInGtp, + CRCRESET => crcTxRst + ); + + + -- RX CRC BLock + Rx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcRxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crcRxValid, + CRCDATAWIDTH => crcRxWidth, + CRCIN => crcRxInGtp, + CRCRESET => crcRxRst + ); + + + -- RXA Reset Control + U_Pgp2GtpRxRstA: Pgp2GtpPackage.Pgp2GtpRxRst + port map ( + gtpRxClk => pgpClk, + gtpRxRst => intRxRst, + gtpRxReady => intRxReady(0), + gtpRxInit => phyRxInit, + gtpLockDetect => phyLockDetect, + gtpRxElecIdle => phyRxElecIdle(0), + gtpRxBuffStatus => phyRxBuffStatusA, + gtpRstDone => phyRstDone(0), + gtpRxElecIdleRst => phyRxElecIdleRst(0), + gtpRxReset => phyRxReset(0), + gtpRxCdrReset => phyRxCdrReset(0) + ); + + + -- TXA Reset Control + U_Pgp2GtpTxRstA: Pgp2GtpPackage.Pgp2GtpTxRst + port map ( + gtpTxClk => pgpClk, + gtpTxRst => intTxRst, + gtpTxReady => intTxReady(0), + gtpLockDetect => phyLockDetect, + gtpTxBuffStatus => phyTxBuffStatusA, + gtpRstDone => phyRstDone(0), + gtpTxReset => phyTxReset(0) + ); + + + -- RXB Reset Control + U_Pgp2GtpRxRstB: Pgp2GtpPackage.Pgp2GtpRxRst + port map ( + gtpRxClk => pgpClk, + gtpRxRst => intRxRst, + gtpRxReady => intRxReady(1), + gtpRxInit => phyRxInit, + gtpLockDetect => phyLockDetect, + gtpRxElecIdle => phyRxElecIdle(1), + gtpRxBuffStatus => phyRxBuffStatusB, + gtpRstDone => phyRstDone(1), + gtpRxElecIdleRst => phyRxElecIdleRst(1), + gtpRxReset => phyRxReset(1), + gtpRxCdrReset => phyRxCdrReset(1) + ); + + + -- TXA Reset Control + U_Pgp2GtpTxRstB: Pgp2GtpPackage.Pgp2GtpTxRst + port map ( + gtpTxClk => pgpClk, + gtpTxRst => intTxRst, + gtpTxReady => intTxReady(1), + gtpLockDetect => phyLockDetect, + gtpTxBuffStatus => phyTxBuffStatusB, + gtpRstDone => phyRstDone(1), + gtpTxReset => phyTxReset(1) + ); + + + ----------------------------- GTP_DUAL Instance -------------------------- + UGtpDual:GTP_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_GTPRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + PLL_TXDIVSEL_COMM_OUT => 1, + TX_SYNC_FILTERB => 1, + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "00000", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "00000", + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + TX_DIFF_BOOST_0 => TRUE, + + TX_DIFF_BOOST_1 => TRUE, + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + + COM_BURST_VAL_1 => "1111", + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "001", + PMA_CDR_SCAN_0 => x"6c07640", + PMA_RX_CFG_0 => x"09f0089", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_MID_0 => FALSE, + RCV_TERM_VTTRX_0 => FALSE, + TERMINATION_IMP_0 => 50, + + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "001", + PMA_CDR_SCAN_1 => x"6c07640", + PMA_RX_CFG_1 => x"09f0089", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_MID_1 => FALSE, + RCV_TERM_VTTRX_1 => FALSE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => TRUE, + + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => TRUE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "0110111100", + CLK_COR_SEQ_1_2_1 => "0100011100", + CLK_COR_SEQ_1_3_1 => "0100011100", + CLK_COR_SEQ_1_4_1 => "0100011100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CHAN_BOND_1_MAX_SKEW_0 => 10, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 1, + CHAN_BOND_MODE_0 => "MASTER", + CHAN_BOND_SEQ_1_1_0 => "0110111100", + CHAN_BOND_SEQ_1_2_0 => "0111011100", + CHAN_BOND_SEQ_1_3_0 => "0111011100", + CHAN_BOND_SEQ_1_4_0 => "0111011100", + CHAN_BOND_SEQ_1_ENABLE_0 => "1111", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CHAN_BOND_1_MAX_SKEW_1 => 10, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "SLAVE", + CHAN_BOND_SEQ_1_1_1 => "0110111100", + CHAN_BOND_SEQ_1_2_1 => "0111011100", + CHAN_BOND_SEQ_1_3_1 => "0111011100", + CHAN_BOND_SEQ_1_4_1 => "0111011100", + CHAN_BOND_SEQ_1_ENABLE_1 => "1111", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"0060", + TRANS_TIME_NON_P2_0 => x"0025", + TRANS_TIME_TO_P2_0 => x"0100", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"0060", + TRANS_TIME_NON_P2_1 => x"0025", + TRANS_TIME_TO_P2_1 => x"0100" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0(0) => '0', + LOOPBACK0(1) => gtpLoopback, + LOOPBACK0(2) => '0', + LOOPBACK1 => "000", + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0 => phyRxDataK(1 downto 0), + RXCHARISK1 => phyRxDataK(3 downto 2), + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0 => phyRxDispErr(1 downto 0), + RXDISPERR1 => phyRxDispErr(3 downto 2), + RXNOTINTABLE0 => phyRxDecErr(1 downto 0), + RXNOTINTABLE1 => phyRxDecErr(3 downto 2), + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => phyChanBond, + RXCHBONDO0 => phyChanBond, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '1', + RXENCHANSYNC1 => '1', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0 => phyRxData(15 downto 0), + RXDATA1 => phyRxData(31 downto 16), + RXDATAWIDTH0 => '1', + RXDATAWIDTH1 => '1', + RXRECCLK0 => intRxRecClk, + RXRECCLK1 => open, + RXRESET0 => phyRxReset(0), + RXRESET1 => phyRxReset(1), + RXUSRCLK0 => pgpClk2x, + RXUSRCLK1 => pgpClk2x, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => phyRxCdrReset(0), + RXCDRRESET1 => phyRxCdrReset(1), + RXELECIDLE0 => phyRxElecIdle(0), + RXELECIDLE1 => phyRxElecIdle(1), + RXELECIDLERESET0 => phyRxElecIdleRst(0), + RXELECIDLERESET1 => phyRxElecIdleRst(1), + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => gtpRxN(0), + RXN1 => gtpRxN(1), + RXP0 => gtpRxP(0), + RXP1 => gtpRxP(1), + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => phyRxBuffStatusA, + RXBUFSTATUS1 => phyRxBuffStatusB, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => phyRxPolarity(0), + RXPOLARITY1 => phyRxPolarity(1), + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtpClkIn, + GTPRESET => pgpReset, + GTPTEST => (others=>'0'), + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => phyRstDone(0), + RESETDONE1 => phyRstDone(1), + RXENELECIDLERESETB => '1', + TXENPMAPHASEALIGN => '0', + TXPMASETPHASE => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0 => phyTxDataK(1 downto 0), + TXCHARISK1 => phyTxDataK(3 downto 2), + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => open, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => phyTxBuffStatusA, + TXBUFSTATUS1 => phyTxBuffStatusB, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0 => phyTxData(15 downto 0), + TXDATA1 => phyTxData(31 downto 16), + TXDATAWIDTH0 => '1', + TXDATAWIDTH1 => '1', + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => phyTxReset(0), + TXRESET1 => phyTxReset(1), + TXUSRCLK0 => pgpClk2x, + TXUSRCLK1 => pgpClk2x, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => gtpTxN(0), + TXN1 => gtpTxN(1), + TXP0 => gtpTxP(0), + TXP1 => gtpTxP(1), + TXPREEMPHASIS0 => "011", -- 4.5% + TXPREEMPHASIS1 => "011", + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtpRefClkOut, + I => tmpRefClkOut + ); + gtpRxRecClk <= intRxRecClk; + + +end Pgp2Gtp32; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpClk.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpClk.vhd new file mode 100755 index 0000000000000000000000000000000000000000..f19b9539fe917776f3ab7ac48bf6cbca33d11902 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpClk.vhd @@ -0,0 +1,226 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Clock Generation Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtpClk.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/08/2009 +------------------------------------------------------------------------------- +-- Description: +-- PGP Clock Module. Contains DCM to support PGP clocking for GTP in Virtex5. +-- Used to generate global buffer clocks at the PGP interface rate and the 2X +-- clock required for the internal GTP logic. +-- Will also generate an optional user global clock and reset for external +-- logic use. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/08/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +Library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2GtpClk is + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Input. + -- This is provided as an output from the GTP tile. + pgpRefClk : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpReset : out std_logic; + + -- 2x clock required by the GTP internal logic + pgpClk2x : out std_logic; + + -- Global Clock & Reset For User Logic + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + +end Pgp2GtpClk; + + +-- Define architecture +architecture Pgp2GtpClk of Pgp2GtpClk is + + -- Local Signals + signal ponReset : std_logic; + signal tmpPgpClk : std_logic; + signal intPgpClk : std_logic; + signal tmpPgpClk2x : std_logic; + signal intPgpClk2x : std_logic; + signal intPgpRst : std_logic; + signal tmpLocClk : std_logic; + signal intUsrClk : std_logic; + signal intUsrRst : std_logic; + signal syncPgpRstIn : std_logic_vector(2 downto 0); + signal pgpRstCnt : std_logic_vector(3 downto 0); + signal syncLocRstIn : std_logic_vector(2 downto 0); + signal locRstCnt : std_logic_vector(3 downto 0); + signal dcmLock : std_logic; + signal resetIn : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output Generated Clock And Reset Signals + pgpClk <= intPgpClk; + pgpClk2x <= intPgpClk2x; + pgpReset <= intPgpRst; + userClk <= intUsrClk; + userReset <= intUsrRst; + + -- Invert power on reset + ponReset <= not ponResetL; + + + -- DCM For PGP Clock & User Clock + U_PgpDcm: DCM_ADV + generic map ( + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "HIGH", + CLKIN_DIVIDE_BY_2 => FALSE, + CLK_FEEDBACK => "1X", + CLKOUT_PHASE_SHIFT => "NONE", + STARTUP_WAIT => false, + PHASE_SHIFT => 0, + CLKFX_MULTIPLY => UserFxMult, + CLKFX_DIVIDE => UserFxDiv, + CLKDV_DIVIDE => 2.0, + CLKIN_PERIOD => 6.4, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + FACTORY_JF => X"F0F0", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS" + ) + port map ( + CLKIN => pgpRefClk, CLKFB => intPgpClk, + CLK0 => tmpPgpClk, CLK90 => open, + CLK180 => open, CLK270 => open, + CLK2X => tmpPgpClk2x, CLK2X180 => open, + CLKDV => open, CLKFX => tmpLocClk, + CLKFX180 => open, LOCKED => dcmLock, + PSDONE => open, PSCLK => '0', + PSINCDEC => '0', PSEN => '0', + DCLK => '0', DADDR => (others=>'0'), + DI => (others=>'0'), DO => open, + DRDY => open, DWE => '0', + DEN => '0', RST => ponReset + ); + + + -- Global Buffer For PGP Clock + U_PgpClkBuff: BUFG port map ( + O => intPgpClk, + I => tmpPgpClk + ); + + + -- Global Buffer For PGP 2x Clock + U_PgpClk2xBuff: BUFG port map ( + O => intPgpClk2x, + I => tmpPgpClk2x + ); + + + -- Global Buffer For User Clock + U_LocClkBuff: BUFG port map ( + O => intUsrClk, + I => tmpLocClk + ); + + + -- Generate reset input + resetIn <= (not dcmLock) or ponReset or locReset; + + -- PGP Clock Synced Reset + process ( pgpClkIn, resetIn ) begin + if resetIn = '1' then + syncPgpRstIn <= (others=>'0') after tpd; + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + elsif rising_edge(pgpClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncPgpRstIn(0) <= '1' after tpd; + syncPgpRstIn(1) <= syncPgpRstIn(0) after tpd; + syncPgpRstIn(2) <= syncPgpRstIn(1) after tpd; + + -- Reset counter on reset + if syncPgpRstIn(2) = '0' then + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + + -- Count Up To Max Value + elsif pgpRstCnt = "1111" then + intPgpRst <= '0' after tpd; + + -- Increment counter + else + intPgpRst <= '1' after tpd; + pgpRstCnt <= pgpRstCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Local User Clock Synced Reset + process ( userClkIn, resetIn ) begin + if resetIn = '1' then + syncLocRstIn <= (others=>'0') after tpd; + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + elsif rising_edge(userClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncLocRstIn(0) <= '1' after tpd; + syncLocRstIn(1) <= syncLocRstIn(0) after tpd; + syncLocRstIn(2) <= syncLocRstIn(1) after tpd; + + -- Reset counter on reset + if syncLocRstIn(2) = '0' then + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + + -- Count Up To Max Value + elsif locRstCnt = "1111" then + intUsrRst <= '0' after tpd; + + -- Increment counter + else + intUsrRst <= '1' after tpd; + locRstCnt <= locRstCnt + 1 after tpd; + end if; + end if; + end process; + +end Pgp2GtpClk; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpDual.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpDual.vhd new file mode 100755 index 0000000000000000000000000000000000000000..5911262f95fe847805c176d3ba85ede30a2b4c70 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpDual.vhd @@ -0,0 +1,1200 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Dual Channel GTP Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtpDual.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 06/14/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTP and CRC blocks. +-- This module also contains the logic to control the reset of the GTP. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 06/14/2010: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtpDual is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Flash frame state + + -- PLL Reset Control + pll0TxRst : in std_logic; -- Reset transmit PLL logic + pll0RxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pll0RxReady : out std_logic; -- MGT Receive logic is ready + pll0TxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgp0RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp0LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgp0TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp0TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgp0RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp0RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgp0LocLinkReady : out std_logic; -- Local Link is ready + pgp0RemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgp0RxCellError : out std_logic; -- A cell error has occured + pgp0RxLinkDown : out std_logic; -- A link down event has occured + pgp0RxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, Lane 0, VC 0 + vc00FrameTxValid : in std_logic; -- User frame data is valid + vc00FrameTxReady : out std_logic; -- PGP is ready + vc00FrameTxSOF : in std_logic; -- User frame data start of frame + vc00FrameTxEOF : in std_logic; -- User frame data end of frame + vc00FrameTxEOFE : in std_logic; -- User frame data error + vc00FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc00LocBuffAFull : in std_logic; -- Remote buffer almost full + vc00LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 0, VC 1 + vc01FrameTxValid : in std_logic; -- User frame data is valid + vc01FrameTxReady : out std_logic; -- PGP is ready + vc01FrameTxSOF : in std_logic; -- User frame data start of frame + vc01FrameTxEOF : in std_logic; -- User frame data end of frame + vc01FrameTxEOFE : in std_logic; -- User frame data error + vc01FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc01LocBuffAFull : in std_logic; -- Remote buffer almost full + vc01LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 0, VC 2 + vc02FrameTxValid : in std_logic; -- User frame data is valid + vc02FrameTxReady : out std_logic; -- PGP is ready + vc02FrameTxSOF : in std_logic; -- User frame data start of frame + vc02FrameTxEOF : in std_logic; -- User frame data end of frame + vc02FrameTxEOFE : in std_logic; -- User frame data error + vc02FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc02LocBuffAFull : in std_logic; -- Remote buffer almost full + vc02LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 0, VC 3 + vc03FrameTxValid : in std_logic; -- User frame data is valid + vc03FrameTxReady : out std_logic; -- PGP is ready + vc03FrameTxSOF : in std_logic; -- User frame data start of frame + vc03FrameTxEOF : in std_logic; -- User frame data end of frame + vc03FrameTxEOFE : in std_logic; -- User frame data error + vc03FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc03LocBuffAFull : in std_logic; -- Remote buffer almost full + vc03LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All Lane 0 VCs + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, Lane 0, VC 0 + vc00FrameRxValid : out std_logic; -- PGP frame data is valid + vc00RemBuffAFull : out std_logic; -- Remote buffer almost full + vc00RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 0, VC 1 + vc01FrameRxValid : out std_logic; -- PGP frame data is valid + vc01RemBuffAFull : out std_logic; -- Remote buffer almost full + vc01RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 0, VC 2 + vc02FrameRxValid : out std_logic; -- PGP frame data is valid + vc02RemBuffAFull : out std_logic; -- Remote buffer almost full + vc02RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 0, VC 3 + vc03FrameRxValid : out std_logic; -- PGP frame data is valid + vc03RemBuffAFull : out std_logic; -- Remote buffer almost full + vc03RemBuffFull : out std_logic; -- Remote buffer full + + -- PLL Reset Control + pll1TxRst : in std_logic; -- Reset transmit PLL logic + pll1RxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pll1RxReady : out std_logic; -- MGT Receive logic is ready + pll1TxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgp1RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp1LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgp1TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp1TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgp1RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp1RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgp1LocLinkReady : out std_logic; -- Local Link is ready + pgp1RemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgp1RxCellError : out std_logic; -- A cell error has occured + pgp1RxLinkDown : out std_logic; -- A link down event has occured + pgp1RxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, Lane 1, VC 0 + vc10FrameTxValid : in std_logic; -- User frame data is valid + vc10FrameTxReady : out std_logic; -- PGP is ready + vc10FrameTxSOF : in std_logic; -- User frame data start of frame + vc10FrameTxEOF : in std_logic; -- User frame data end of frame + vc10FrameTxEOFE : in std_logic; -- User frame data error + vc10FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc10LocBuffAFull : in std_logic; -- Remote buffer almost full + vc10LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 1, VC 1 + vc11FrameTxValid : in std_logic; -- User frame data is valid + vc11FrameTxReady : out std_logic; -- PGP is ready + vc11FrameTxSOF : in std_logic; -- User frame data start of frame + vc11FrameTxEOF : in std_logic; -- User frame data end of frame + vc11FrameTxEOFE : in std_logic; -- User frame data error + vc11FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc11LocBuffAFull : in std_logic; -- Remote buffer almost full + vc11LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 1, VC 2 + vc12FrameTxValid : in std_logic; -- User frame data is valid + vc12FrameTxReady : out std_logic; -- PGP is ready + vc12FrameTxSOF : in std_logic; -- User frame data start of frame + vc12FrameTxEOF : in std_logic; -- User frame data end of frame + vc12FrameTxEOFE : in std_logic; -- User frame data error + vc12FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc12LocBuffAFull : in std_logic; -- Remote buffer almost full + vc12LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, Lane 1, VC 3 + vc13FrameTxValid : in std_logic; -- User frame data is valid + vc13FrameTxReady : out std_logic; -- PGP is ready + vc13FrameTxSOF : in std_logic; -- User frame data start of frame + vc13FrameTxEOF : in std_logic; -- User frame data end of frame + vc13FrameTxEOFE : in std_logic; -- User frame data error + vc13FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc13LocBuffAFull : in std_logic; -- Remote buffer almost full + vc13LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All Lane 1 VCs + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, Lane 1, VC 0 + vc10FrameRxValid : out std_logic; -- PGP frame data is valid + vc10RemBuffAFull : out std_logic; -- Remote buffer almost full + vc10RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 1, VC 1 + vc11FrameRxValid : out std_logic; -- PGP frame data is valid + vc11RemBuffAFull : out std_logic; -- Remote buffer almost full + vc11RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 1, VC 2 + vc12FrameRxValid : out std_logic; -- PGP frame data is valid + vc12RemBuffAFull : out std_logic; -- Remote buffer almost full + vc12RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, Lane 1, VC 3 + vc13FrameRxValid : out std_logic; -- PGP frame data is valid + vc13RemBuffAFull : out std_logic; -- Remote buffer almost full + vc13RemBuffFull : out std_logic; -- Remote buffer full + + -- GTP loopback control + gtpLoopback : in std_logic_vector(1 downto 0); -- GTP Serial Loopback Control + + -- GTP Signals + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic_vector(1 downto 0); -- GTP Rx Recovered Clock + gtpRxN : in std_logic_vector(1 downto 0); -- GTP Serial Receive Negative + gtpRxP : in std_logic_vector(1 downto 0); -- GTP Serial Receive Positive + gtpTxN : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Negative + gtpTxP : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(127 downto 0) + ); + +end Pgp2GtpDual; + + +-- Define architecture +architecture Pgp2GtpDual of Pgp2GtpDual is + + -- Local Signals + signal crc0TxIn : std_logic_vector(15 downto 0); + signal crc0TxInGtp : std_logic_vector(31 downto 0); + signal crc0TxInit : std_logic; + signal crc0TxRst : std_logic; + signal crc0TxValid : std_logic; + signal crc0TxWidth : std_logic_vector(2 downto 0); + signal crc0TxOut : std_logic_vector(31 downto 0); + signal crc0TxOutGtp : std_logic_vector(31 downto 0); + signal crc0RxIn : std_logic_vector(15 downto 0); + signal crc0RxInGtp : std_logic_vector(31 downto 0); + signal crc0RxInit : std_logic; + signal crc0RxRst : std_logic; + signal crc0RxValid : std_logic; + signal crc0RxWidth : std_logic_vector(2 downto 0); + signal crc0RxOut : std_logic_vector(31 downto 0); + signal crc0RxOutGtp : std_logic_vector(31 downto 0); + signal phy0RxPolarity : std_logic_vector(0 downto 0); + signal phy0RxData : std_logic_vector(15 downto 0); + signal phy0RxDataK : std_logic_vector(1 downto 0); + signal phy0TxData : std_logic_vector(15 downto 0); + signal phy0TxDataK : std_logic_vector(1 downto 0); + signal phy0RxDispErr : std_logic_vector(1 downto 0); + signal phy0RxDecErr : std_logic_vector(1 downto 0); + signal phy0RxReady : std_logic; + signal phy0RxInit : std_logic; + signal phy0TxReady : std_logic; + signal phy0RxReset : std_logic; + signal phy0RxElecIdleRst : std_logic; + signal phy0RxElecIdle : std_logic; + signal phy0RxCdrReset : std_logic; + signal phy0RstDone : std_logic; + signal phy0RxBuffStatus : std_logic_vector(2 downto 0); + signal phy0TxReset : std_logic; + signal phy0TxBuffStatus : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal int0TxRst : std_logic; + signal int0RxRst : std_logic; + signal pgp0RxLinkReady : std_logic; + signal pgp0TxLinkReady : std_logic; + signal int0RxRecClk : std_logic; + signal crc1TxIn : std_logic_vector(15 downto 0); + signal crc1TxInGtp : std_logic_vector(31 downto 0); + signal crc1TxInit : std_logic; + signal crc1TxRst : std_logic; + signal crc1TxValid : std_logic; + signal crc1TxWidth : std_logic_vector(2 downto 0); + signal crc1TxOut : std_logic_vector(31 downto 0); + signal crc1TxOutGtp : std_logic_vector(31 downto 0); + signal crc1RxIn : std_logic_vector(15 downto 0); + signal crc1RxInGtp : std_logic_vector(31 downto 0); + signal crc1RxInit : std_logic; + signal crc1RxRst : std_logic; + signal crc1RxValid : std_logic; + signal crc1RxWidth : std_logic_vector(2 downto 0); + signal crc1RxOut : std_logic_vector(31 downto 0); + signal crc1RxOutGtp : std_logic_vector(31 downto 0); + signal phy1RxPolarity : std_logic_vector(0 downto 0); + signal phy1RxData : std_logic_vector(15 downto 0); + signal phy1RxDataK : std_logic_vector(1 downto 0); + signal phy1TxData : std_logic_vector(15 downto 0); + signal phy1TxDataK : std_logic_vector(1 downto 0); + signal phy1RxDispErr : std_logic_vector(1 downto 0); + signal phy1RxDecErr : std_logic_vector(1 downto 0); + signal phy1RxReady : std_logic; + signal phy1RxInit : std_logic; + signal phy1TxReady : std_logic; + signal phy1RxReset : std_logic; + signal phy1RxElecIdleRst : std_logic; + signal phy1RxElecIdle : std_logic; + signal phy1RxCdrReset : std_logic; + signal phy1RstDone : std_logic; + signal phy1RxBuffStatus : std_logic_vector(2 downto 0); + signal phy1TxReset : std_logic; + signal phy1TxBuffStatus : std_logic_vector(1 downto 0); + signal int1TxRst : std_logic; + signal int1RxRst : std_logic; + signal pgp1RxLinkReady : std_logic; + signal pgp1TxLinkReady : std_logic; + signal int1RxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + ------------------------------------------ + -- PGP Lane 0 + ------------------------------------------ + + -- PGP0 RX Block + U_Pgp2Rx0: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgp0RxLinkReady, + pgpRxCellError => pgp0RxCellError, + pgpRxLinkDown => pgp0RxLinkDown, + pgpRxLinkError => pgp0RxLinkError, + pgpRxOpCodeEn => pgp0RxOpCodeEn, + pgpRxOpCode => pgp0RxOpCode, + pgpRemLinkReady => pgp0RemLinkReady, + pgpRemData => pgp0RemData, + vcFrameRxSOF => vc0FrameRxSOF, + vcFrameRxEOF => vc0FrameRxEOF, + vcFrameRxEOFE => vc0FrameRxEOFE, + vcFrameRxData => vc0FrameRxData, + vc0FrameRxValid => vc00FrameRxValid, + vc0RemBuffAFull => vc00RemBuffAFull, + vc0RemBuffFull => vc00RemBuffFull, + vc1FrameRxValid => vc01FrameRxValid, + vc1RemBuffAFull => vc01RemBuffAFull, + vc1RemBuffFull => vc01RemBuffFull, + vc2FrameRxValid => vc02FrameRxValid, + vc2RemBuffAFull => vc02RemBuffAFull, + vc2RemBuffFull => vc02RemBuffFull, + vc3FrameRxValid => vc03FrameRxValid, + vc3RemBuffAFull => vc03RemBuffAFull, + vc3RemBuffFull => vc03RemBuffFull, + phyRxPolarity => phy0RxPolarity, + phyRxData => phy0RxData, + phyRxDataK => phy0RxDataK, + phyRxDispErr => phy0RxDispErr, + phyRxDecErr => phy0RxDecErr, + phyRxReady => phy0RxReady, + phyRxInit => phy0RxInit, + crcRxIn => crc0RxIn, + crcRxWidth => open, + crcRxInit => crc0RxInit, + crcRxValid => crc0RxValid, + crcRxOut => crc0RxOut, + debug => debug(63 downto 0) + ); + + + -- PGP TX Block + U_Pgp2Tx0: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgp0TxLinkReady, + pgpTxOpCodeEn => pgp0TxOpCodeEn, + pgpTxOpCode => pgp0TxOpCode, + pgpLocLinkReady => pgp0RxLinkReady, + pgpLocData => pgp0LocData, + vc0FrameTxValid => vc00FrameTxValid, + vc0FrameTxReady => vc00FrameTxReady, + vc0FrameTxSOF => vc00FrameTxSOF, + vc0FrameTxEOF => vc00FrameTxEOF, + vc0FrameTxEOFE => vc00FrameTxEOFE, + vc0FrameTxData => vc00FrameTxData, + vc0LocBuffAFull => vc00LocBuffAFull, + vc0LocBuffFull => vc00LocBuffFull, + vc1FrameTxValid => vc01FrameTxValid, + vc1FrameTxReady => vc01FrameTxReady, + vc1FrameTxSOF => vc01FrameTxSOF, + vc1FrameTxEOF => vc01FrameTxEOF, + vc1FrameTxEOFE => vc01FrameTxEOFE, + vc1FrameTxData => vc01FrameTxData, + vc1LocBuffAFull => vc01LocBuffAFull, + vc1LocBuffFull => vc01LocBuffFull, + vc2FrameTxValid => vc02FrameTxValid, + vc2FrameTxReady => vc02FrameTxReady, + vc2FrameTxSOF => vc02FrameTxSOF, + vc2FrameTxEOF => vc02FrameTxEOF, + vc2FrameTxEOFE => vc02FrameTxEOFE, + vc2FrameTxData => vc02FrameTxData, + vc2LocBuffAFull => vc02LocBuffAFull, + vc2LocBuffFull => vc02LocBuffFull, + vc3FrameTxValid => vc03FrameTxValid, + vc3FrameTxReady => vc03FrameTxReady, + vc3FrameTxSOF => vc03FrameTxSOF, + vc3FrameTxEOF => vc03FrameTxEOF, + vc3FrameTxEOFE => vc03FrameTxEOFE, + vc3FrameTxData => vc03FrameTxData, + vc3LocBuffAFull => vc03LocBuffAFull, + vc3LocBuffFull => vc03LocBuffFull, + phyTxData => phy0TxData, + phyTxDataK => phy0TxDataK, + phyTxReady => phy0TxReady, + crcTxIn => crc0TxIn, + crcTxInit => crc0TxInit, + crcTxValid => crc0TxValid, + crcTxOut => crc0TxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crc0TxWidth <= "001"; + crc0RxWidth <= "001"; + crc0RxRst <= int0RxRst or crc0RxInit; + crc0TxRst <= int0TxRst or crc0TxInit; + + -- Pass CRC data in on proper bits + crc0TxInGtp(31 downto 24) <= crc0TxIn(7 downto 0); + crc0TxInGtp(23 downto 16) <= crc0TxIn(15 downto 8); + crc0TxInGtp(15 downto 0) <= (others=>'0'); + crc0RxInGtp(31 downto 24) <= crc0RxIn(7 downto 0); + crc0RxInGtp(23 downto 16) <= crc0RxIn(15 downto 8); + crc0RxInGtp(15 downto 0) <= (others=>'0'); + + -- Pll Resets + int0TxRst <= pll0TxRst or pgpReset; + int0RxRst <= pll0RxRst or pgpReset; + + -- PLL Lock + pll0RxReady <= phy0RxReady; + pll0TxReady <= phy0TxReady; + + -- Link Ready + pgp0LocLinkReady <= pgp0RxLinkReady and pgp0TxLinkReady; + + -- Invert Output CRC + crc0RxOut <= not crc0RxOutGtp; + crc0TxOut <= not crc0TxOutGtp; + + + -- TX CRC BLock + Tx_CRC0: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc0TxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crc0TxValid, + CRCDATAWIDTH => crc0TxWidth, + CRCIN => crc0TxInGtp, + CRCRESET => crc0TxRst + ); + + + -- RX CRC BLock + Rx_CRC0: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc0RxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crc0RxValid, + CRCDATAWIDTH => crc0RxWidth, + CRCIN => crc0RxInGtp, + CRCRESET => crc0RxRst + ); + + + -- RX Reset Control + U_Pgp2GtpRxRst0: Pgp2GtpPackage.Pgp2GtpRxRst + port map ( + gtpRxClk => pgpClk, + gtpRxRst => int0RxRst, + gtpRxReady => phy0RxReady, + gtpRxInit => phy0RxInit, + gtpLockDetect => phyLockDetect, + gtpRxElecIdle => phy0RxElecIdle, + gtpRxBuffStatus => phy0RxBuffStatus, + gtpRstDone => phy0RstDone, + gtpRxElecIdleRst => phy0RxElecIdleRst, + gtpRxReset => phy0RxReset, + gtpRxCdrReset => phy0RxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtpTxRst0: Pgp2GtpPackage.Pgp2GtpTxRst + port map ( + gtpTxClk => pgpClk, + gtpTxRst => int0TxRst, + gtpTxReady => phy0TxReady, + gtpLockDetect => phyLockDetect, + gtpTxBuffStatus => phy0TxBuffStatus, + gtpRstDone => phy0RstDone, + gtpTxReset => phy0TxReset + ); + + + ------------------------------------------ + -- PGP Lane 1 + ------------------------------------------ + + -- PGP1 RX Block + U_Pgp2Rx1: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgp1RxLinkReady, + pgpRxCellError => pgp1RxCellError, + pgpRxLinkDown => pgp1RxLinkDown, + pgpRxLinkError => pgp1RxLinkError, + pgpRxOpCodeEn => pgp1RxOpCodeEn, + pgpRxOpCode => pgp1RxOpCode, + pgpRemLinkReady => pgp1RemLinkReady, + pgpRemData => pgp1RemData, + vcFrameRxSOF => vc1FrameRxSOF, + vcFrameRxEOF => vc1FrameRxEOF, + vcFrameRxEOFE => vc1FrameRxEOFE, + vcFrameRxData => vc1FrameRxData, + vc0FrameRxValid => vc10FrameRxValid, + vc0RemBuffAFull => vc10RemBuffAFull, + vc0RemBuffFull => vc10RemBuffFull, + vc1FrameRxValid => vc11FrameRxValid, + vc1RemBuffAFull => vc11RemBuffAFull, + vc1RemBuffFull => vc11RemBuffFull, + vc2FrameRxValid => vc12FrameRxValid, + vc2RemBuffAFull => vc12RemBuffAFull, + vc2RemBuffFull => vc12RemBuffFull, + vc3FrameRxValid => vc13FrameRxValid, + vc3RemBuffAFull => vc13RemBuffAFull, + vc3RemBuffFull => vc13RemBuffFull, + phyRxPolarity => phy1RxPolarity, + phyRxData => phy1RxData, + phyRxDataK => phy1RxDataK, + phyRxDispErr => phy1RxDispErr, + phyRxDecErr => phy1RxDecErr, + phyRxReady => phy1RxReady, + phyRxInit => phy1RxInit, + crcRxIn => crc1RxIn, + crcRxWidth => open, + crcRxInit => crc1RxInit, + crcRxValid => crc1RxValid, + crcRxOut => crc1RxOut, + debug => debug(127 downto 64) + ); + + + -- PGP TX Block + U_Pgp2Tx1: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgp1TxLinkReady, + pgpTxOpCodeEn => pgp1TxOpCodeEn, + pgpTxOpCode => pgp1TxOpCode, + pgpLocLinkReady => pgp1RxLinkReady, + pgpLocData => pgp1LocData, + vc0FrameTxValid => vc10FrameTxValid, + vc0FrameTxReady => vc10FrameTxReady, + vc0FrameTxSOF => vc10FrameTxSOF, + vc0FrameTxEOF => vc10FrameTxEOF, + vc0FrameTxEOFE => vc10FrameTxEOFE, + vc0FrameTxData => vc10FrameTxData, + vc0LocBuffAFull => vc10LocBuffAFull, + vc0LocBuffFull => vc10LocBuffFull, + vc1FrameTxValid => vc11FrameTxValid, + vc1FrameTxReady => vc11FrameTxReady, + vc1FrameTxSOF => vc11FrameTxSOF, + vc1FrameTxEOF => vc11FrameTxEOF, + vc1FrameTxEOFE => vc11FrameTxEOFE, + vc1FrameTxData => vc11FrameTxData, + vc1LocBuffAFull => vc11LocBuffAFull, + vc1LocBuffFull => vc11LocBuffFull, + vc2FrameTxValid => vc12FrameTxValid, + vc2FrameTxReady => vc12FrameTxReady, + vc2FrameTxSOF => vc12FrameTxSOF, + vc2FrameTxEOF => vc12FrameTxEOF, + vc2FrameTxEOFE => vc12FrameTxEOFE, + vc2FrameTxData => vc12FrameTxData, + vc2LocBuffAFull => vc12LocBuffAFull, + vc2LocBuffFull => vc12LocBuffFull, + vc3FrameTxValid => vc13FrameTxValid, + vc3FrameTxReady => vc13FrameTxReady, + vc3FrameTxSOF => vc13FrameTxSOF, + vc3FrameTxEOF => vc13FrameTxEOF, + vc3FrameTxEOFE => vc13FrameTxEOFE, + vc3FrameTxData => vc13FrameTxData, + vc3LocBuffAFull => vc13LocBuffAFull, + vc3LocBuffFull => vc13LocBuffFull, + phyTxData => phy1TxData, + phyTxDataK => phy1TxDataK, + phyTxReady => phy1TxReady, + crcTxIn => crc1TxIn, + crcTxInit => crc1TxInit, + crcTxValid => crc1TxValid, + crcTxOut => crc1TxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crc1TxWidth <= "001"; + crc1RxWidth <= "001"; + crc1RxRst <= int1RxRst or crc1RxInit; + crc1TxRst <= int1TxRst or crc1TxInit; + + -- Pass CRC data in on proper bits + crc1TxInGtp(31 downto 24) <= crc1TxIn(7 downto 0); + crc1TxInGtp(23 downto 16) <= crc1TxIn(15 downto 8); + crc1TxInGtp(15 downto 0) <= (others=>'0'); + crc1RxInGtp(31 downto 24) <= crc1RxIn(7 downto 0); + crc1RxInGtp(23 downto 16) <= crc1RxIn(15 downto 8); + crc1RxInGtp(15 downto 0) <= (others=>'0'); + + -- Pll Resets + int1TxRst <= pll1TxRst or pgpReset; + int1RxRst <= pll1RxRst or pgpReset; + + -- PLL Lock + pll1RxReady <= phy1RxReady; + pll1TxReady <= phy1TxReady; + + -- Link Ready + pgp1LocLinkReady <= pgp1RxLinkReady and pgp1TxLinkReady; + + -- Invert Output CRC + crc1RxOut <= not crc1RxOutGtp; + crc1TxOut <= not crc1TxOutGtp; + + + -- TX CRC BLock + Tx_CRC1: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc1TxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crc1TxValid, + CRCDATAWIDTH => crc1TxWidth, + CRCIN => crc1TxInGtp, + CRCRESET => crc1TxRst + ); + + + -- RX CRC BLock + Rx_CRC1: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc1RxOutGtp, + CRCCLK => pgpClk, + CRCDATAVALID => crc1RxValid, + CRCDATAWIDTH => crc1RxWidth, + CRCIN => crc1RxInGtp, + CRCRESET => crc1RxRst + ); + + + -- RX Reset Control + U_Pgp2GtpRxRst1: Pgp2GtpPackage.Pgp2GtpRxRst + port map ( + gtpRxClk => pgpClk, + gtpRxRst => int1RxRst, + gtpRxReady => phy1RxReady, + gtpRxInit => phy1RxInit, + gtpLockDetect => phyLockDetect, + gtpRxElecIdle => phy1RxElecIdle, + gtpRxBuffStatus => phy1RxBuffStatus, + gtpRstDone => phy1RstDone, + gtpRxElecIdleRst => phy1RxElecIdleRst, + gtpRxReset => phy1RxReset, + gtpRxCdrReset => phy1RxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtpTxRst1: Pgp2GtpPackage.Pgp2GtpTxRst + port map ( + gtpTxClk => pgpClk, + gtpTxRst => int1TxRst, + gtpTxReady => phy1TxReady, + gtpLockDetect => phyLockDetect, + gtpTxBuffStatus => phy1TxBuffStatus, + gtpRstDone => phy1RstDone, + gtpTxReset => phy1TxReset + ); + + + ------------------------------------------ + -- Shared GTP + ------------------------------------------ + + ----------------------------- GTP_DUAL Instance -------------------------- + U_GtpDual:GTP_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_GTPRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + PLL_TXDIVSEL_COMM_OUT => 1, + TX_SYNC_FILTERB => 1, + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "00000", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "00000", + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + TX_DIFF_BOOST_0 => TRUE, + + TX_DIFF_BOOST_1 => TRUE, + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + + COM_BURST_VAL_1 => "1111", + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "001", + PMA_CDR_SCAN_0 => x"6c07640", + PMA_RX_CFG_0 => x"09f0089", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_MID_0 => FALSE, + RCV_TERM_VTTRX_0 => FALSE, + TERMINATION_IMP_0 => 50, + + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "001", + PMA_CDR_SCAN_1 => x"6c07640", + PMA_RX_CFG_1 => x"09f0089", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_MID_1 => FALSE, + RCV_TERM_VTTRX_1 => FALSE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => TRUE, + + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => TRUE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "0110111100", + CLK_COR_SEQ_1_2_1 => "0100011100", + CLK_COR_SEQ_1_3_1 => "0100011100", + CLK_COR_SEQ_1_4_1 => "0100011100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CHAN_BOND_1_MAX_SKEW_0 => 1, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 0, + CHAN_BOND_MODE_0 => "OFF", + CHAN_BOND_SEQ_1_1_0 => "0000000000", + CHAN_BOND_SEQ_1_2_0 => "0000000000", + CHAN_BOND_SEQ_1_3_0 => "0000000000", + CHAN_BOND_SEQ_1_4_0 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CHAN_BOND_1_MAX_SKEW_1 => 1, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "OFF", + CHAN_BOND_SEQ_1_1_1 => "0000000000", + CHAN_BOND_SEQ_1_2_1 => "0000000000", + CHAN_BOND_SEQ_1_3_1 => "0000000000", + CHAN_BOND_SEQ_1_4_1 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"0060", + TRANS_TIME_NON_P2_0 => x"0025", + TRANS_TIME_TO_P2_0 => x"0100", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"0060", + TRANS_TIME_NON_P2_1 => x"0025", + TRANS_TIME_TO_P2_1 => x"0100" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0(0) => '0', + LOOPBACK0(1) => gtpLoopback(0), + LOOPBACK0(2) => '0', + LOOPBACK1(0) => '0', + LOOPBACK1(1) => gtpLoopback(1), + LOOPBACK1(2) => '0', + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0 => phy0RxDataK, + RXCHARISK1 => phy1RxDataK, + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0 => phy0RxDispErr, + RXDISPERR1 => phy1RxDispErr, + RXNOTINTABLE0 => phy0RxDecErr, + RXNOTINTABLE1 => phy1RxDecErr, + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => (others=>'0'), + RXCHBONDO0 => open, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '0', + RXENCHANSYNC1 => '0', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0 => phy0RxData, + RXDATA1 => phy1RxData, + RXDATAWIDTH0 => '1', + RXDATAWIDTH1 => '1', + RXRECCLK0 => int0RxRecClk, + RXRECCLK1 => int1RxRecClk, + RXRESET0 => phy0RxReset, + RXRESET1 => phy1RxReset, + RXUSRCLK0 => pgpClk2x, + RXUSRCLK1 => pgpClk2x, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => phy0RxCdrReset, + RXCDRRESET1 => phy1RxCdrReset, + RXELECIDLE0 => phy0RxElecIdle, + RXELECIDLE1 => phy1RxElecIdle, + RXELECIDLERESET0 => phy0RxElecIdleRst, + RXELECIDLERESET1 => phy1RxElecIdleRst, + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => gtpRxN(0), + RXN1 => gtpRxN(1), + RXP0 => gtpRxP(0), + RXP1 => gtpRxP(1), + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => phy0RxBuffStatus, + RXBUFSTATUS1 => phy1RxBuffStatus, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => phy0RxPolarity(0), + RXPOLARITY1 => phy1RxPolarity(0), + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtpClkIn, + GTPRESET => pgpReset, + GTPTEST => (others=>'0'), + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => phy0RstDone, + RESETDONE1 => phy1RstDone, + RXENELECIDLERESETB => '1', + TXENPMAPHASEALIGN => '0', + TXPMASETPHASE => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0 => phy0TxDataK, + TXCHARISK1 => phy1TxDataK, + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => open, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => phy0TxBuffStatus, + TXBUFSTATUS1 => phy1TxBuffStatus, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0 => phy0TxData, + TXDATA1 => phy1TxData, + TXDATAWIDTH0 => '1', + TXDATAWIDTH1 => '1', + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => phy0TxReset, + TXRESET1 => phy1TxReset, + TXUSRCLK0 => pgpClk2x, + TXUSRCLK1 => pgpClk2x, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => gtpTxN(0), + TXN1 => gtpTxN(1), + TXP0 => gtpTxP(0), + TXP1 => gtpTxP(1), + TXPREEMPHASIS0 => "011", -- 4.5% + TXPREEMPHASIS1 => "011", + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtpRefClkOut, + I => tmpRefClkOut + ); + gtpRxRecClk(0) <= int0RxRecClk; + gtpRxRecClk(1) <= int1RxRecClk; + +end Pgp2GtpDual; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpPackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpPackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..1e00da7d7aed329b53333e371bd955ebe6207180 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpPackage.vhd @@ -0,0 +1,399 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, GTP Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtpPackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/23/2009 +------------------------------------------------------------------------------- +-- Description: +-- GTP Components package. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/23/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2GtpPackage is + + -- 16-bit wrapper + component Pgp2Gtp16 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Flash frame state + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + gtpLoopback : in std_logic; -- GTP Serial Loopback Control + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic; -- GTP Rx Recovered Clock + gtpRxN : in std_logic; -- GTP Serial Receive Negative + gtpRxP : in std_logic; -- GTP Serial Receive Positive + gtpTxN : out std_logic; -- GTP Serial Transmit Negative + gtpTxP : out std_logic; -- GTP Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- 32-bit wrapper + component Pgp2Gtp32 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Flash frame state + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(31 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + gtpLoopback : in std_logic; -- GTP Serial Loopback Control + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic; -- GTP Rx Recovered Clock + gtpRxN : in std_logic_vector(1 downto 0); -- GTP Serial Receive Negative + gtpRxP : in std_logic_vector(1 downto 0); -- GTP Serial Receive Positive + gtpTxN : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Negative + gtpTxP : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- 16-bit dual wrapper + component Pgp2GtpDual + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpClk2x : in std_logic; -- 2x master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Flash frame state + pll0TxRst : in std_logic; -- Reset transmit PLL logic + pll0RxRst : in std_logic; -- Reset receive PLL logic + pll0RxReady : out std_logic; -- MGT Receive logic is ready + pll0TxReady : out std_logic; -- MGT Transmit logic is ready + pgp0RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp0LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgp0TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp0TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgp0RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp0RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgp0LocLinkReady : out std_logic; -- Local Link is ready + pgp0RemLinkReady : out std_logic; -- Far end side has link + pgp0RxCellError : out std_logic; -- A cell error has occured + pgp0RxLinkDown : out std_logic; -- A link down event has occured + pgp0RxLinkError : out std_logic; -- A link error has occured + vc00FrameTxValid : in std_logic; -- User frame data is valid + vc00FrameTxReady : out std_logic; -- PGP is ready + vc00FrameTxSOF : in std_logic; -- User frame data start of frame + vc00FrameTxEOF : in std_logic; -- User frame data end of frame + vc00FrameTxEOFE : in std_logic; -- User frame data error + vc00FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc00LocBuffAFull : in std_logic; -- Remote buffer almost full + vc00LocBuffFull : in std_logic; -- Remote buffer full + vc01FrameTxValid : in std_logic; -- User frame data is valid + vc01FrameTxReady : out std_logic; -- PGP is ready + vc01FrameTxSOF : in std_logic; -- User frame data start of frame + vc01FrameTxEOF : in std_logic; -- User frame data end of frame + vc01FrameTxEOFE : in std_logic; -- User frame data error + vc01FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc01LocBuffAFull : in std_logic; -- Remote buffer almost full + vc01LocBuffFull : in std_logic; -- Remote buffer full + vc02FrameTxValid : in std_logic; -- User frame data is valid + vc02FrameTxReady : out std_logic; -- PGP is ready + vc02FrameTxSOF : in std_logic; -- User frame data start of frame + vc02FrameTxEOF : in std_logic; -- User frame data end of frame + vc02FrameTxEOFE : in std_logic; -- User frame data error + vc02FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc02LocBuffAFull : in std_logic; -- Remote buffer almost full + vc02LocBuffFull : in std_logic; -- Remote buffer full + vc03FrameTxValid : in std_logic; -- User frame data is valid + vc03FrameTxReady : out std_logic; -- PGP is ready + vc03FrameTxSOF : in std_logic; -- User frame data start of frame + vc03FrameTxEOF : in std_logic; -- User frame data end of frame + vc03FrameTxEOFE : in std_logic; -- User frame data error + vc03FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc03LocBuffAFull : in std_logic; -- Remote buffer almost full + vc03LocBuffFull : in std_logic; -- Remote buffer full + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc00FrameRxValid : out std_logic; -- PGP frame data is valid + vc00RemBuffAFull : out std_logic; -- Remote buffer almost full + vc00RemBuffFull : out std_logic; -- Remote buffer full + vc01FrameRxValid : out std_logic; -- PGP frame data is valid + vc01RemBuffAFull : out std_logic; -- Remote buffer almost full + vc01RemBuffFull : out std_logic; -- Remote buffer full + vc02FrameRxValid : out std_logic; -- PGP frame data is valid + vc02RemBuffAFull : out std_logic; -- Remote buffer almost full + vc02RemBuffFull : out std_logic; -- Remote buffer full + vc03FrameRxValid : out std_logic; -- PGP frame data is valid + vc03RemBuffAFull : out std_logic; -- Remote buffer almost full + vc03RemBuffFull : out std_logic; -- Remote buffer full + pll1TxRst : in std_logic; -- Reset transmit PLL logic + pll1RxRst : in std_logic; -- Reset receive PLL logic + pll1RxReady : out std_logic; -- MGT Receive logic is ready + pll1TxReady : out std_logic; -- MGT Transmit logic is ready + pgp1RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp1LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgp1TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp1TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgp1RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp1RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgp1LocLinkReady : out std_logic; -- Local Link is ready + pgp1RemLinkReady : out std_logic; -- Far end side has link + pgp1RxCellError : out std_logic; -- A cell error has occured + pgp1RxLinkDown : out std_logic; -- A link down event has occured + pgp1RxLinkError : out std_logic; -- A link error has occured + vc10FrameTxValid : in std_logic; -- User frame data is valid + vc10FrameTxReady : out std_logic; -- PGP is ready + vc10FrameTxSOF : in std_logic; -- User frame data start of frame + vc10FrameTxEOF : in std_logic; -- User frame data end of frame + vc10FrameTxEOFE : in std_logic; -- User frame data error + vc10FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc10LocBuffAFull : in std_logic; -- Remote buffer almost full + vc10LocBuffFull : in std_logic; -- Remote buffer full + vc11FrameTxValid : in std_logic; -- User frame data is valid + vc11FrameTxReady : out std_logic; -- PGP is ready + vc11FrameTxSOF : in std_logic; -- User frame data start of frame + vc11FrameTxEOF : in std_logic; -- User frame data end of frame + vc11FrameTxEOFE : in std_logic; -- User frame data error + vc11FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc11LocBuffAFull : in std_logic; -- Remote buffer almost full + vc11LocBuffFull : in std_logic; -- Remote buffer full + vc12FrameTxValid : in std_logic; -- User frame data is valid + vc12FrameTxReady : out std_logic; -- PGP is ready + vc12FrameTxSOF : in std_logic; -- User frame data start of frame + vc12FrameTxEOF : in std_logic; -- User frame data end of frame + vc12FrameTxEOFE : in std_logic; -- User frame data error + vc12FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc12LocBuffAFull : in std_logic; -- Remote buffer almost full + vc12LocBuffFull : in std_logic; -- Remote buffer full + vc13FrameTxValid : in std_logic; -- User frame data is valid + vc13FrameTxReady : out std_logic; -- PGP is ready + vc13FrameTxSOF : in std_logic; -- User frame data start of frame + vc13FrameTxEOF : in std_logic; -- User frame data end of frame + vc13FrameTxEOFE : in std_logic; -- User frame data error + vc13FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc13LocBuffAFull : in std_logic; -- Remote buffer almost full + vc13LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc10FrameRxValid : out std_logic; -- PGP frame data is valid + vc10RemBuffAFull : out std_logic; -- Remote buffer almost full + vc10RemBuffFull : out std_logic; -- Remote buffer full + vc11FrameRxValid : out std_logic; -- PGP frame data is valid + vc11RemBuffAFull : out std_logic; -- Remote buffer almost full + vc11RemBuffFull : out std_logic; -- Remote buffer full + vc12FrameRxValid : out std_logic; -- PGP frame data is valid + vc12RemBuffAFull : out std_logic; -- Remote buffer almost full + vc12RemBuffFull : out std_logic; -- Remote buffer full + vc13FrameRxValid : out std_logic; -- PGP frame data is valid + vc13RemBuffAFull : out std_logic; -- Remote buffer almost full + vc13RemBuffFull : out std_logic; -- Remote buffer full + gtpLoopback : in std_logic_vector(1 downto 0); -- GTP Serial Loopback Control + gtpClkIn : in std_logic; -- GTP Reference Clock In + gtpRefClkOut : out std_logic; -- GTP Reference Clock Output + gtpRxRecClk : out std_logic_vector(1 downto 0); -- GTP Rx Recovered Clock + gtpRxN : in std_logic_vector(1 downto 0); -- GTP Serial Receive Negative + gtpRxP : in std_logic_vector(1 downto 0); -- GTP Serial Receive Positive + gtpTxN : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Negative + gtpTxP : out std_logic_vector(1 downto 0); -- GTP Serial Transmit Positive + debug : out std_logic_vector(127 downto 0) + ); + end component; + + -- PGP Clock Generator + component Pgp2GtpClk + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + pgpRefClk : in std_logic; + ponResetL : in std_logic; + locReset : in std_logic; + pgpClk : out std_logic; + pgpReset : out std_logic; + pgpClk2x : out std_logic; + userClk : out std_logic; + userReset : out std_logic; + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + end component; + + -- RX Reset Control + component Pgp2GtpRxRst + port ( + gtpRxClk : in std_logic; + gtpRxRst : in std_logic; + gtpRxReady : out std_logic; + gtpRxInit : in std_logic; + gtpLockDetect : in std_logic; + gtpRxElecIdle : in std_logic; + gtpRxBuffStatus : in std_logic_vector(2 downto 0); + gtpRstDone : in std_logic; + gtpRxElecIdleRst : out std_logic; + gtpRxReset : out std_logic; + gtpRxCdrReset : out std_logic + ); + end component; + + -- TX Reset Control + component Pgp2GtpTxRst + port ( + gtpTxClk : in std_logic; + gtpTxRst : in std_logic; + gtpTxReady : out std_logic; + gtpLockDetect : in std_logic; + gtpTxBuffStatus : in std_logic_vector(1 downto 0); + gtpRstDone : in std_logic; + gtpTxReset : out std_logic + ); + end component; + + + +end Pgp2GtpPackage; + + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpRxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpRxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..0348001a55bec12633974ed901773f636f884965 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpRxRst.vhd @@ -0,0 +1,205 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTP RX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtpRxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the RX GTP. +------------------------------------------------------------------------------- +-- Copyright (c) 2009 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +-- 01/13/2010: Added received init line to help linking. +-- 04/20/2010: Elec idle will no longer cause general reset. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtpRxRst is + port ( + + -- Clock and reset + gtpRxClk : in std_logic; + gtpRxRst : in std_logic; + + -- RX Side is ready + gtpRxReady : out std_logic; + gtpRxInit : in std_logic; + + -- GTP Status + gtpLockDetect : in std_logic; + gtpRxElecIdle : in std_logic; + gtpRxBuffStatus : in std_logic_vector(2 downto 0); + gtpRstDone : in std_logic; + + -- Reset Control + gtpRxElecIdleRst : out std_logic; + gtpRxReset : out std_logic; + gtpRxCdrReset : out std_logic + ); + +end Pgp2GtpRxRst; + + +-- Define architecture +architecture Pgp2GtpRxRst of Pgp2GtpRxRst is + + -- Local Signals + signal intRxElecIdleRst : std_logic; + signal intRxReset : std_logic; + signal intRxCdrReset : std_logic; + signal rxStateCnt : std_logic_vector(1 downto 0); + signal rxStateCntRst : std_logic; + signal rxClockReady : std_logic; + + -- RX Reset State Machine + constant RX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant RX_WAIT_LOCK : std_logic_vector(2 downto 0) := "001"; + constant RX_RESET : std_logic_vector(2 downto 0) := "010"; + constant RX_WAIT_DONE : std_logic_vector(2 downto 0) := "011"; + constant RX_READY : std_logic_vector(2 downto 0) := "100"; + signal curRxState : std_logic_vector(2 downto 0); + signal nxtRxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- RX State Machine Synchronous Logic + process ( gtpRxClk, gtpRxRst ) begin + if gtpRxRst = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + rxStateCnt <= (others=>'0') after tpd; + gtpRxReady <= '0' after tpd; + gtpRxElecIdleRst <= '1' after tpd; + gtpRxReset <= '1' after tpd; + gtpRxCdrReset <= '1' after tpd; + elsif rising_edge(gtpRxClk) then + + -- Drive PIB Lock + gtpRxReady <= rxClockReady after tpd; + + -- Pass on reset signals + gtpRxElecIdleRst <= intRxElecIdleRst or gtpRxInit after tpd; + gtpRxReset <= intRxReset after tpd; + gtpRxCdrReset <= intRxCdrReset after tpd; + + -- Update state + if gtpRxInit = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + else + curRxState <= nxtRxState after tpd; + end if; + + -- Rx State Counter + if rxStateCntRst = '1' then + rxStateCnt <= (others=>'0') after tpd; + else + rxStateCnt <= rxStateCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Async RX State Logic + process ( curRxState, rxStateCnt, gtpLockDetect, gtpRxBuffStatus, gtpRstDone ) begin + case curRxState is + + -- System Reset State + when RX_SYSTEM_RESET => + rxStateCntRst <= '1'; + intRxReset <= '1'; + intRxCdrReset <= '1'; + rxClockReady <= '0'; + nxtRxState <= RX_WAIT_LOCK; + + -- Wait for PLL lock + when RX_WAIT_LOCK => + rxStateCntRst <= '1'; + intRxReset <= '1'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + + -- Wait for lock + if gtpLockDetect = '1' then + nxtRxState <= RX_RESET; + else + nxtRxState <= curRxState; + end if; + + -- RX Reset State + when RX_RESET => + intRxReset <= '1'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '0'; + + -- Wait for three clocks + if rxStateCnt = 3 then + nxtRxState <= RX_WAIT_DONE; + else + nxtRxState <= curRxState; + end if; + + -- RX Wait Reset Done + when RX_WAIT_DONE => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '1'; + + -- Wait for reset done + if gtpRstDone = '1' then + nxtRxState <= RX_READY; + else + nxtRxState <= curRxState; + end if; + + -- RX Ready + when RX_READY => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '1'; + rxStateCntRst <= '1'; + + -- Look for unlock error + if gtpLockDetect = '0' then + nxtRxState <= RX_WAIT_LOCK; + + -- Look For Buffer Error + elsif gtpRxBuffStatus(2) = '1' then + nxtRxState <= RX_RESET; + + else + nxtRxState <= curRxState; + end if; + + -- Default + when others => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '1'; + nxtRxState <= RX_SYSTEM_RESET; + end case; + end process; + + -- Elec idle reset + intRxElecIdleRst <= gtpRxElecIdle and gtpRstDone; + +end Pgp2GtpRxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpTxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpTxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..cf2eae1f0a764e994c40317dd34030ab6ecd50f3 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtp/Pgp2GtpTxRst.vhd @@ -0,0 +1,179 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTP TX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtpTxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the TX GTP. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtpPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtpTxRst is + port ( + + -- Clock and reset + gtpTxClk : in std_logic; + gtpTxRst : in std_logic; + + -- TX Side is ready + gtpTxReady : out std_logic; + + -- GTP Status + gtpLockDetect : in std_logic; + gtpTxBuffStatus : in std_logic_vector(1 downto 0); + gtpRstDone : in std_logic; + + -- Reset Control + gtpTxReset : out std_logic + ); + +end Pgp2GtpTxRst; + + +-- Define architecture +architecture Pgp2GtpTxRst of Pgp2GtpTxRst is + + -- Local Signals + signal intTxReset : std_logic; + signal txStateCnt : std_logic_vector(1 downto 0); + signal txStateCntRst : std_logic; + signal txClockReady : std_logic; + + -- TX Reset State Machine + constant TX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant TX_WAIT_LOCK : std_logic_vector(2 downto 0) := "001"; + constant TX_RESET : std_logic_vector(2 downto 0) := "010"; + constant TX_WAIT_DONE : std_logic_vector(2 downto 0) := "011"; + constant TX_READY : std_logic_vector(2 downto 0) := "100"; + signal curTxState : std_logic_vector(2 downto 0); + signal nxtTxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- TX State Machine Synchronous Logic + process ( gtpTxClk, gtpTxRst ) begin + if gtpTxRst = '1' then + curTxState <= TX_SYSTEM_RESET after tpd; + txStateCnt <= (others=>'0') after tpd; + gtpTxReset <= '1' after tpd; + gtpTxReady <= '0' after tpd; + elsif rising_edge(gtpTxClk) then + + -- RX Is Ready + gtpTxReady <= txClockReady after tpd; + + -- Pass on reset signals + gtpTxReset <= intTxReset after tpd; + + -- Update state + curTxState <= nxtTxState after tpd; + + -- Tx State Counter + if txStateCntRst = '1' then + txStateCnt <= (others=>'0') after tpd; + else + txStateCnt <= txStateCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Async TX State Logic + process ( curTxState, txStateCnt, gtpLockDetect, gtpTxBuffStatus, gtpRstDone ) begin + case curTxState is + + -- System Reset State + when TX_SYSTEM_RESET => + txStateCntRst <= '1'; + intTxReset <= '1'; + txClockReady <= '0'; + nxtTxState <= TX_WAIT_LOCK; + + -- Wait for PLL lock + when TX_WAIT_LOCK => + txStateCntRst <= '1'; + intTxReset <= '1'; + txClockReady <= '0'; + + -- Wait for three clocks + if gtpLockDetect = '1' then + nxtTxState <= TX_RESET; + else + nxtTxState <= curTxState; + end if; + + -- TX Reset State + when TX_RESET => + intTxReset <= '1'; + txClockReady <= '0'; + txStateCntRst <= '0'; + + -- Wait for three clocks + if txStateCnt = 3 then + nxtTxState <= TX_WAIT_DONE; + else + nxtTxState <= curTxState; + end if; + + -- TX Wait Reset Done + when TX_WAIT_DONE => + intTxReset <= '0'; + txClockReady <= '0'; + txStateCntRst <= '1'; + + -- Wait for three clocks + if gtpRstDone = '1' then + nxtTxState <= TX_READY; + else + nxtTxState <= curTxState; + end if; + + -- TX Ready + when TX_READY => + intTxReset <= '0'; + txClockReady <= '1'; + txStateCntRst <= '1'; + + -- Look for unlock error + if gtpLockDetect = '0' then + nxtTxState <= TX_WAIT_LOCK; + + -- Look For Buffer Error + elsif gtpTxBuffStatus(1) = '1' then + nxtTxState <= TX_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Default + when others => + intTxReset <= '0'; + txClockReady <= '0'; + txStateCntRst <= '1'; + nxtTxState <= TX_SYSTEM_RESET; + end case; + end process; + +end Pgp2GtpTxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16.vhd new file mode 100755 index 0000000000000000000000000000000000000000..7221a46613a3fdc02734ac7bee89fe6a0a876019 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16.vhd @@ -0,0 +1,954 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTX Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Gtx16.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTX and CRC blocks. +-- This module also contains the logic to control the reset of the GTX. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2Gtx16 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Pgp master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame sync flush + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- GTX Status & Control Signals + gtxLoopback : in std_logic; -- GTX Serial Loopback Control + + -- MGT Signals Clock & IO Signals + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic; -- GTX Rx Recovered Clock + gtxRxN : in std_logic; -- GTX Serial Receive Negative + gtxRxP : in std_logic; -- GTX Serial Receive Positive + gtxTxN : out std_logic; -- GTX Serial Transmit Negative + gtxTxP : out std_logic; -- GTX Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Gtx16; + + +-- Define architecture +architecture Pgp2Gtx16 of Pgp2Gtx16 is + + -- Local Signals + signal crcTxIn : std_logic_vector(15 downto 0); + signal crcTxInGtx : std_logic_vector(31 downto 0); + signal crcTxInit : std_logic; + signal crcTxRst : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcTxOutGtx : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(15 downto 0); + signal crcRxInGtx : std_logic_vector(31 downto 0); + signal crcRxInit : std_logic; + signal crcRxRst : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal crcRxOutGtx : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(0 downto 0); + signal phyRxData : std_logic_vector(15 downto 0); + signal phyRxDataK : std_logic_vector(1 downto 0); + signal phyTxData : std_logic_vector(15 downto 0); + signal phyTxDataK : std_logic_vector(1 downto 0); + signal phyRxDispErr : std_logic_vector(1 downto 0); + signal phyRxDecErr : std_logic_vector(1 downto 0); + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal phyRxReset : std_logic; + signal phyRxElecIdle : std_logic; + signal phyRxCdrReset : std_logic; + signal phyRstDone : std_logic; + signal phyRxBuffStatus : std_logic_vector(2 downto 0); + signal phyTxReset : std_logic; + signal phyTxBuffStatus : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal intRxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- PGP RX Block + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP TX Block + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crcTxWidth <= "001"; + crcRxWidth <= "001"; + crcRxRst <= intRxRst or crcRxInit; + crcTxRst <= intTxRst or crcTxInit; + + -- Pass CRC data in on proper bits + crcTxInGtx(31 downto 24) <= crcTxIn(7 downto 0); + crcTxInGtx(23 downto 16) <= crcTxIn(15 downto 8); + crcTxInGtx(15 downto 0) <= (others=>'0'); + crcRxInGtx(31 downto 24) <= crcRxIn(7 downto 0); + crcRxInGtx(23 downto 16) <= crcRxIn(15 downto 8); + crcRxInGtx(15 downto 0) <= (others=>'0'); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + -- Invert Output CRC + crcRxOut <= not crcRxOutGtx; + crcTxOut <= not crcTxOutGtx; + + + -- TX CRC BLock + Tx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcTxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crcTxValid, + CRCDATAWIDTH => crcTxWidth, + CRCIN => crcTxInGtx, + CRCRESET => crcTxRst + ); + + + -- RX CRC BLock + Rx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcRxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crcRxValid, + CRCDATAWIDTH => crcRxWidth, + CRCIN => crcRxInGtx, + CRCRESET => crcRxRst + ); + + + -- RX Reset Control + U_Pgp2GtxRxRst: Pgp2GtxPackage.Pgp2GtxRxRst + port map ( + gtxRxClk => pgpClk, + gtxRxRst => intRxRst, + gtxRxReady => phyRxReady, + gtxRxInit => phyRxInit, + gtxLockDetect => phyLockDetect, + gtxRxElecIdle => phyRxElecIdle, + gtxRxBuffStatus => phyRxBuffStatus, + gtxRstDone => phyRstDone, + gtxRxReset => phyRxReset, + gtxRxCdrReset => phyRxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtxTxRst: Pgp2GtxPackage.Pgp2GtxTxRst + port map ( + gtxTxClk => pgpClk, + gtxTxRst => intTxRst, + gtxTxReady => phyTxReady, + gtxLockDetect => phyLockDetect, + gtxTxBuffStatus => phyTxBuffStatus, + gtxRstDone => phyRstDone, + gtxTxReset => phyTxReset + ); + + + ----------------------------- GTX_DUAL Instance -------------------------- + UGtxDual:GTX_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_RECEIVER_DETECT_PASS_0 => TRUE, + SIM_RECEIVER_DETECT_PASS_1 => TRUE, + SIM_MODE => "FAST", + SIM_GTXRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + CLKRCV_TRST => TRUE, + PLL_COM_CFG => x"21680a", + PLL_CP_CFG => x"00", + PLL_FB_DCCEN => FALSE, + PLL_LKDET_CFG => "101", + PLL_TDCC_CFG => "000", + PMA_COM_CFG => x"000000000000000000", + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "011", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "011", + + --------------------- TX Gearbox Settings ----------------------------- + + GEARBOX_ENDEC_0 => "000", + TXGEARBOX_USE_0 => FALSE, + + GEARBOX_ENDEC_1 => "000", + TXGEARBOX_USE_1 => FALSE, + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + CM_TRIM_0 => "10", + PMA_TX_CFG_0 => x"80082", + TX_DETECT_RX_CFG_0 => x"1832", + TX_IDLE_DELAY_0 => "010", + CM_TRIM_1 => "10", + PMA_TX_CFG_1 => x"80082", + TX_DETECT_RX_CFG_1 => x"1832", + TX_IDLE_DELAY_1 => "010", + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + COM_BURST_VAL_1 => "1111", + + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "111", + PMA_CDR_SCAN_0 => x"640403a", + PMA_RX_CFG_0 => x"0f44088", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_VTTRX_0 => TRUE, + TERMINATION_IMP_0 => 50, + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "111", + PMA_CDR_SCAN_1 => x"640403a", + PMA_RX_CFG_1 => x"0f44088", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_VTTRX_1 => TRUE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + ---------------- RX Decision Feedback Equalizer(DFE) ---------------- + + DFE_CFG_0 => "1001111011", + DFE_CFG_1 => "1001111011", + DFE_CAL_TIME => "00110", + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => FALSE, + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => FALSE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + --------------------- RX Gearbox Settings ----------------------------- + + RXGEARBOX_USE_0 => FALSE, + RXGEARBOX_USE_1 => FALSE, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + PMA_RXSYNC_CFG_0 => x"00", + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + PMA_RXSYNC_CFG_1 => x"00", + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "1101111100", + CLK_COR_SEQ_1_2_1 => "1000111100", + CLK_COR_SEQ_1_3_1 => "1000111100", + CLK_COR_SEQ_1_4_1 => "1000111100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CB2_INH_CC_PERIOD_0 => 8, + CHAN_BOND_KEEP_ALIGN_0 => FALSE, + CHAN_BOND_1_MAX_SKEW_0 => 1, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 0, + CHAN_BOND_MODE_0 => "OFF", + CHAN_BOND_SEQ_1_1_0 => "0000000000", + CHAN_BOND_SEQ_1_2_0 => "0000000000", + CHAN_BOND_SEQ_1_3_0 => "0000000000", + CHAN_BOND_SEQ_1_4_0 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CB2_INH_CC_PERIOD_1 => 8, + CHAN_BOND_KEEP_ALIGN_1 => FALSE, + CHAN_BOND_1_MAX_SKEW_1 => 1, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "OFF", + CHAN_BOND_SEQ_1_1_1 => "0000000000", + CHAN_BOND_SEQ_1_2_1 => "0000000000", + CHAN_BOND_SEQ_1_3_1 => "0000000000", + CHAN_BOND_SEQ_1_4_1 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + -------- RX Attributes to Control Reset after Electrical Idle ------ + + RX_EN_IDLE_HOLD_DFE_0 => TRUE, + RX_EN_IDLE_RESET_BUF_0 => TRUE, + RX_IDLE_HI_CNT_0 => "1000", + RX_IDLE_LO_CNT_0 => "0000", + RX_EN_IDLE_HOLD_DFE_1 => TRUE, + RX_EN_IDLE_RESET_BUF_1 => TRUE, + RX_IDLE_HI_CNT_1 => "1000", + RX_IDLE_LO_CNT_1 => "0000", + CDR_PH_ADJ_TIME => "01010", + RX_EN_IDLE_RESET_FR => TRUE, + RX_EN_IDLE_HOLD_CDR => FALSE, + RX_EN_IDLE_RESET_PH => TRUE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"003C", + TRANS_TIME_NON_P2_0 => x"0019", + TRANS_TIME_TO_P2_0 => x"0064", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"003C", + TRANS_TIME_NON_P2_1 => x"0019", + TRANS_TIME_TO_P2_1 => x"0064" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0(0) => '0', + LOOPBACK0(1) => gtxLoopback, + LOOPBACK0(2) => '0', + LOOPBACK1 => "000", + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + -------------- Receive Ports - 64b66b and 64b67b Gearbox Ports ------------- + RXDATAVALID0 => open, + RXDATAVALID1 => open, + RXGEARBOXSLIP0 => '0', + RXGEARBOXSLIP1 => '0', + RXHEADER0 => open, + RXHEADER1 => open, + RXHEADERVALID0 => open, + RXHEADERVALID1 => open, + RXSTARTOFSEQ0 => open, + RXSTARTOFSEQ1 => open, + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0(1 downto 0) => phyRxDataK, + RXCHARISK0(3 downto 2) => open, + RXCHARISK1 => open, + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0(1 downto 0) => phyRxDispErr, + RXDISPERR0(3 downto 2) => open, + RXDISPERR1 => open, + RXNOTINTABLE0(1 downto 0) => phyRxDecErr, + RXNOTINTABLE0(3 downto 2) => open, + RXNOTINTABLE1 => open, + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => (others=>'0'), + RXCHBONDO0 => open, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '0', + RXENCHANSYNC1 => '0', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0(15 downto 0) => phyRxData, + RXDATA0(31 downto 16) => open, + RXDATA1 => open, + RXDATAWIDTH0 => "01", + RXDATAWIDTH1 => "01", + RXRECCLK0 => intRxRecClk, + RXRECCLK1 => open, + RXRESET0 => phyRxReset, + RXRESET1 => '0', + RXUSRCLK0 => pgpClk, + RXUSRCLK1 => pgpClk, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------------ Receive Ports - RX Decision Feedback Equalizer(DFE) ----------- + DFECLKDLYADJ0 => (others=>'0'), + DFECLKDLYADJ1 => (others=>'0'), + DFECLKDLYADJMONITOR0 => open, + DFECLKDLYADJMONITOR1 => open, + DFEEYEDACMONITOR0 => open, + DFEEYEDACMONITOR1 => open, + DFESENSCAL0 => open, + DFESENSCAL1 => open, + DFETAP10 => (others=>'0'), + DFETAP11 => (others=>'0'), + DFETAP1MONITOR0 => open, + DFETAP1MONITOR1 => open, + DFETAP20 => (others=>'0'), + DFETAP21 => (others=>'0'), + DFETAP2MONITOR0 => open, + DFETAP2MONITOR1 => open, + DFETAP30 => (others=>'0'), + DFETAP31 => (others=>'0'), + DFETAP3MONITOR0 => open, + DFETAP3MONITOR1 => open, + DFETAP40 => (others=>'0'), + DFETAP41 => (others=>'0'), + DFETAP4MONITOR0 => open, + DFETAP4MONITOR1 => open, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => phyRxCdrReset, + RXCDRRESET1 => '0', + RXELECIDLE0 => phyRxElecIdle, + RXELECIDLE1 => open, + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => gtxRxN, + RXN1 => '1', + RXP0 => gtxRxP, + RXP1 => '0', + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => phyRxBuffStatus, + RXBUFSTATUS1 => open, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXENPMAPHASEALIGN0 => '0', + RXENPMAPHASEALIGN1 => '0', + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => phyRxPolarity(0), + RXPOLARITY1 => '0', + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtxClkIn, + GTXRESET => pgpReset, + GTXTEST => "10000000000000", + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => phyRstDone, + RESETDONE1 => open, + -------------- Transmit Ports - 64b66b and 64b67b Gearbox Ports ------------ + TXGEARBOXREADY0 => open, + TXGEARBOXREADY1 => open, + TXHEADER0 => (others=>'0'), + TXHEADER1 => (others=>'0'), + TXSEQUENCE0 => (others=>'0'), + TXSEQUENCE1 => (others=>'0'), + TXSTARTSEQ0 => '0', + TXSTARTSEQ1 => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0(1 downto 0) => phyTxDataK, + TXCHARISK0(3 downto 2) => (others=>'0'), + TXCHARISK1 => (others=>'0'), + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => open, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => phyTxBuffStatus, + TXBUFSTATUS1 => open, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0(15 downto 0) => phyTxData, + TXDATA0(31 downto 16) => (others=>'0'), + TXDATA1 => (others=>'0'), + TXDATAWIDTH0 => "01", + TXDATAWIDTH1 => "01", + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => phyTxReset, + TXRESET1 => '0', + TXUSRCLK0 => pgpClk, + TXUSRCLK1 => pgpClk, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => gtxTxN, + TXN1 => open, + TXP0 => gtxTxP, + TXP1 => open, + TXPREEMPHASIS0 => "0011", -- 4.5% + TXPREEMPHASIS1 => "0011", + -------- Transmit Ports - TX Elastic Buffer and Phase Alignment Ports ------ + TXENPMAPHASEALIGN0 => '0', + TXENPMAPHASEALIGN1 => '0', + TXPMASETPHASE0 => '0', + TXPMASETPHASE1 => '0', + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtxRefClkOut, + I => tmpRefClkOut + ); + gtxRxRecClk <= intRxRecClk; + +end Pgp2Gtx16; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16B.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16B.vhd new file mode 100755 index 0000000000000000000000000000000000000000..e2c3436c32d5b68ff355b2e133c236e4c1a217ec --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2Gtx16B.vhd @@ -0,0 +1,953 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTX Wrapper, Port B +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Gtx16B.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 10/13/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTX and CRC blocks. +-- This module also contains the logic to control the reset of the GTX. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 10/13/2010: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2Gtx16B is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Pgp master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame sync flush + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Local buffer almost full + vc0LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Local buffer almost full + vc1LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Local buffer almost full + vc2LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Local buffer almost full + vc3LocBuffFull : in std_logic; -- Local buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- GTX Status & Control Signals + gtxLoopback : in std_logic; -- GTX Serial Loopback Control + + -- MGT Signals Clock & IO Signals + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic; -- GTX Rx Recovered Clock + gtxRxN : in std_logic; -- GTX Serial Receive Negative + gtxRxP : in std_logic; -- GTX Serial Receive Positive + gtxTxN : out std_logic; -- GTX Serial Transmit Negative + gtxTxP : out std_logic; -- GTX Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Gtx16B; + + +-- Define architecture +architecture Pgp2Gtx16B of Pgp2Gtx16B is + + -- Local Signals + signal crcTxIn : std_logic_vector(15 downto 0); + signal crcTxInGtx : std_logic_vector(31 downto 0); + signal crcTxInit : std_logic; + signal crcTxRst : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcTxOutGtx : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(15 downto 0); + signal crcRxInGtx : std_logic_vector(31 downto 0); + signal crcRxInit : std_logic; + signal crcRxRst : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal crcRxOutGtx : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(0 downto 0); + signal phyRxData : std_logic_vector(15 downto 0); + signal phyRxDataK : std_logic_vector(1 downto 0); + signal phyTxData : std_logic_vector(15 downto 0); + signal phyTxDataK : std_logic_vector(1 downto 0); + signal phyRxDispErr : std_logic_vector(1 downto 0); + signal phyRxDecErr : std_logic_vector(1 downto 0); + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal phyRxReset : std_logic; + signal phyRxElecIdle : std_logic; + signal phyRxCdrReset : std_logic; + signal phyRstDone : std_logic; + signal phyRxBuffStatus : std_logic_vector(2 downto 0); + signal phyTxReset : std_logic; + signal phyTxBuffStatus : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal intRxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- PGP RX Block + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP TX Block + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crcTxWidth <= "001"; + crcRxWidth <= "001"; + crcRxRst <= intRxRst or crcRxInit; + crcTxRst <= intTxRst or crcTxInit; + + -- Pass CRC data in on proper bits + crcTxInGtx(31 downto 24) <= crcTxIn(7 downto 0); + crcTxInGtx(23 downto 16) <= crcTxIn(15 downto 8); + crcTxInGtx(15 downto 0) <= (others=>'0'); + crcRxInGtx(31 downto 24) <= crcRxIn(7 downto 0); + crcRxInGtx(23 downto 16) <= crcRxIn(15 downto 8); + crcRxInGtx(15 downto 0) <= (others=>'0'); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + -- Invert Output CRC + crcRxOut <= not crcRxOutGtx; + crcTxOut <= not crcTxOutGtx; + + + -- TX CRC BLock + Tx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcTxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crcTxValid, + CRCDATAWIDTH => crcTxWidth, + CRCIN => crcTxInGtx, + CRCRESET => crcTxRst + ); + + + -- RX CRC BLock + Rx_CRC: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crcRxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crcRxValid, + CRCDATAWIDTH => crcRxWidth, + CRCIN => crcRxInGtx, + CRCRESET => crcRxRst + ); + + + -- RX Reset Control + U_Pgp2GtxRxRst: Pgp2GtxPackage.Pgp2GtxRxRst + port map ( + gtxRxClk => pgpClk, + gtxRxRst => intRxRst, + gtxRxReady => phyRxReady, + gtxRxInit => phyRxInit, + gtxLockDetect => phyLockDetect, + gtxRxElecIdle => phyRxElecIdle, + gtxRxBuffStatus => phyRxBuffStatus, + gtxRstDone => phyRstDone, + gtxRxReset => phyRxReset, + gtxRxCdrReset => phyRxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtxTxRst: Pgp2GtxPackage.Pgp2GtxTxRst + port map ( + gtxTxClk => pgpClk, + gtxTxRst => intTxRst, + gtxTxReady => phyTxReady, + gtxLockDetect => phyLockDetect, + gtxTxBuffStatus => phyTxBuffStatus, + gtxRstDone => phyRstDone, + gtxTxReset => phyTxReset + ); + + + ----------------------------- GTX_DUAL Instance -------------------------- + UGtxDual:GTX_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_RECEIVER_DETECT_PASS_0 => TRUE, + SIM_RECEIVER_DETECT_PASS_1 => TRUE, + SIM_MODE => "FAST", + SIM_GTXRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + CLKRCV_TRST => TRUE, + PLL_COM_CFG => x"21680a", + PLL_CP_CFG => x"00", + PLL_FB_DCCEN => FALSE, + PLL_LKDET_CFG => "101", + PLL_TDCC_CFG => "000", + PMA_COM_CFG => x"000000000000000000", + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "011", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "011", + + --------------------- TX Gearbox Settings ----------------------------- + + GEARBOX_ENDEC_0 => "000", + TXGEARBOX_USE_0 => FALSE, + + GEARBOX_ENDEC_1 => "000", + TXGEARBOX_USE_1 => FALSE, + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + CM_TRIM_0 => "10", + PMA_TX_CFG_0 => x"80082", + TX_DETECT_RX_CFG_0 => x"1832", + TX_IDLE_DELAY_0 => "010", + CM_TRIM_1 => "10", + PMA_TX_CFG_1 => x"80082", + TX_DETECT_RX_CFG_1 => x"1832", + TX_IDLE_DELAY_1 => "010", + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + COM_BURST_VAL_1 => "1111", + + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "111", + PMA_CDR_SCAN_0 => x"640403a", + PMA_RX_CFG_0 => x"0f44088", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_VTTRX_0 => TRUE, + TERMINATION_IMP_0 => 50, + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "111", + PMA_CDR_SCAN_1 => x"640403a", + PMA_RX_CFG_1 => x"0f44088", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_VTTRX_1 => TRUE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + ---------------- RX Decision Feedback Equalizer(DFE) ---------------- + + DFE_CFG_0 => "1001111011", + DFE_CFG_1 => "1001111011", + DFE_CAL_TIME => "00110", + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => FALSE, + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => FALSE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + --------------------- RX Gearbox Settings ----------------------------- + + RXGEARBOX_USE_0 => FALSE, + RXGEARBOX_USE_1 => FALSE, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + PMA_RXSYNC_CFG_0 => x"00", + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + PMA_RXSYNC_CFG_1 => x"00", + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "0110111100", + CLK_COR_SEQ_1_2_1 => "0100011100", + CLK_COR_SEQ_1_3_1 => "0100011100", + CLK_COR_SEQ_1_4_1 => "0100011100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CB2_INH_CC_PERIOD_0 => 8, + CHAN_BOND_KEEP_ALIGN_0 => FALSE, + CHAN_BOND_1_MAX_SKEW_0 => 1, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 0, + CHAN_BOND_MODE_0 => "OFF", + CHAN_BOND_SEQ_1_1_0 => "0000000000", + CHAN_BOND_SEQ_1_2_0 => "0000000000", + CHAN_BOND_SEQ_1_3_0 => "0000000000", + CHAN_BOND_SEQ_1_4_0 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CB2_INH_CC_PERIOD_1 => 8, + CHAN_BOND_KEEP_ALIGN_1 => FALSE, + CHAN_BOND_1_MAX_SKEW_1 => 1, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "OFF", + CHAN_BOND_SEQ_1_1_1 => "0000000000", + CHAN_BOND_SEQ_1_2_1 => "0000000000", + CHAN_BOND_SEQ_1_3_1 => "0000000000", + CHAN_BOND_SEQ_1_4_1 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + -------- RX Attributes to Control Reset after Electrical Idle ------ + + RX_EN_IDLE_HOLD_DFE_0 => TRUE, + RX_EN_IDLE_RESET_BUF_0 => TRUE, + RX_IDLE_HI_CNT_0 => "1000", + RX_IDLE_LO_CNT_0 => "0000", + RX_EN_IDLE_HOLD_DFE_1 => TRUE, + RX_EN_IDLE_RESET_BUF_1 => TRUE, + RX_IDLE_HI_CNT_1 => "1000", + RX_IDLE_LO_CNT_1 => "0000", + CDR_PH_ADJ_TIME => "01010", + RX_EN_IDLE_RESET_FR => TRUE, + RX_EN_IDLE_HOLD_CDR => FALSE, + RX_EN_IDLE_RESET_PH => TRUE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"003C", + TRANS_TIME_NON_P2_0 => x"0019", + TRANS_TIME_TO_P2_0 => x"0064", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"003C", + TRANS_TIME_NON_P2_1 => x"0019", + TRANS_TIME_TO_P2_1 => x"0064" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0 => "000", + LOOPBACK1(0) => '0', + LOOPBACK1(1) => gtxLoopback, + LOOPBACK1(2) => '0', + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + -------------- Receive Ports - 64b66b and 64b67b Gearbox Ports ------------- + RXDATAVALID0 => open, + RXDATAVALID1 => open, + RXGEARBOXSLIP0 => '0', + RXGEARBOXSLIP1 => '0', + RXHEADER0 => open, + RXHEADER1 => open, + RXHEADERVALID0 => open, + RXHEADERVALID1 => open, + RXSTARTOFSEQ0 => open, + RXSTARTOFSEQ1 => open, + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0 => open, + RXCHARISK1(1 downto 0) => phyRxDataK, + RXCHARISK1(3 downto 2) => open, + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0 => open, + RXDISPERR1(1 downto 0) => phyRxDispErr, + RXDISPERR1(3 downto 2) => open, + RXNOTINTABLE0 => open, + RXNOTINTABLE1(1 downto 0) => phyRxDecErr, + RXNOTINTABLE1(3 downto 2) => open, + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => (others=>'0'), + RXCHBONDO0 => open, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '0', + RXENCHANSYNC1 => '0', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0 => open, + RXDATA1(15 downto 0) => phyRxData, + RXDATA1(31 downto 16) => open, + RXDATAWIDTH0 => "01", + RXDATAWIDTH1 => "01", + RXRECCLK0 => open, + RXRECCLK1 => intRxRecClk, + RXRESET0 => '0', + RXRESET1 => phyRxReset, + RXUSRCLK0 => pgpClk, + RXUSRCLK1 => pgpClk, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------------ Receive Ports - RX Decision Feedback Equalizer(DFE) ----------- + DFECLKDLYADJ0 => (others=>'0'), + DFECLKDLYADJ1 => (others=>'0'), + DFECLKDLYADJMONITOR0 => open, + DFECLKDLYADJMONITOR1 => open, + DFEEYEDACMONITOR0 => open, + DFEEYEDACMONITOR1 => open, + DFESENSCAL0 => open, + DFESENSCAL1 => open, + DFETAP10 => (others=>'0'), + DFETAP11 => (others=>'0'), + DFETAP1MONITOR0 => open, + DFETAP1MONITOR1 => open, + DFETAP20 => (others=>'0'), + DFETAP21 => (others=>'0'), + DFETAP2MONITOR0 => open, + DFETAP2MONITOR1 => open, + DFETAP30 => (others=>'0'), + DFETAP31 => (others=>'0'), + DFETAP3MONITOR0 => open, + DFETAP3MONITOR1 => open, + DFETAP40 => (others=>'0'), + DFETAP41 => (others=>'0'), + DFETAP4MONITOR0 => open, + DFETAP4MONITOR1 => open, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => '0', + RXCDRRESET1 => phyRxCdrReset, + RXELECIDLE0 => open, + RXELECIDLE1 => phyRxElecIdle, + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => '1', + RXN1 => gtxRxN, + RXP0 => '0', + RXP1 => gtxRxP, + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => open, + RXBUFSTATUS1 => phyRxBuffStatus, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXENPMAPHASEALIGN0 => '0', + RXENPMAPHASEALIGN1 => '0', + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => '0', + RXPOLARITY1 => phyRxPolarity(0), + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtxClkIn, + GTXRESET => pgpReset, + GTXTEST => "10000000000000", + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => open, + RESETDONE1 => phyRstDone, + -------------- Transmit Ports - 64b66b and 64b67b Gearbox Ports ------------ + TXGEARBOXREADY0 => open, + TXGEARBOXREADY1 => open, + TXHEADER0 => (others=>'0'), + TXHEADER1 => (others=>'0'), + TXSEQUENCE0 => (others=>'0'), + TXSEQUENCE1 => (others=>'0'), + TXSTARTSEQ0 => '0', + TXSTARTSEQ1 => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0 => (others=>'0'), + TXCHARISK1(1 downto 0) => phyTxDataK, + TXCHARISK1(3 downto 2) => (others=>'0'), + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => open, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => open, + TXBUFSTATUS1 => phyTxBuffStatus, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0 => (others=>'0'), + TXDATA1(15 downto 0) => phyTxData, + TXDATA1(31 downto 16) => (others=>'0'), + TXDATAWIDTH0 => "01", + TXDATAWIDTH1 => "01", + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => '0', + TXRESET1 => phyTxReset, + TXUSRCLK0 => pgpClk, + TXUSRCLK1 => pgpClk, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => open, + TXN1 => gtxTxN, + TXP0 => open, + TXP1 => gtxTxP, + TXPREEMPHASIS0 => "0011", -- 4.5% + TXPREEMPHASIS1 => "0011", + -------- Transmit Ports - TX Elastic Buffer and Phase Alignment Ports ------ + TXENPMAPHASEALIGN0 => '0', + TXENPMAPHASEALIGN1 => '0', + TXPMASETPHASE0 => '0', + TXPMASETPHASE1 => '0', + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtxRefClkOut, + I => tmpRefClkOut + ); + gtxRxRecClk <= intRxRecClk; + +end Pgp2Gtx16B; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxClk.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxClk.vhd new file mode 100755 index 0000000000000000000000000000000000000000..3cdf86942a322c44bf05ff0b0ad7b849ec9a8d9f --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxClk.vhd @@ -0,0 +1,213 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Clock Generation Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtxClk.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- PGP Clock Module. Contains DCM to support PGP clocking for GTX in Virtex5. +-- Used to generate global buffer clocks at the PGP interface rate and the 2X +-- clock required for the internal GTX logic. +-- Will also generate an optional user global clock and reset for external +-- logic use. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +Library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2GtxClk is + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Input. + -- This is provided as an output from the GTX tile. + pgpRefClk : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpReset : out std_logic; + + -- Global Clock & Reset For User Logic + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + +end Pgp2GtxClk; + + +-- Define architecture +architecture Pgp2GtxClk of Pgp2GtxClk is + + -- Local Signals + signal ponReset : std_logic; + signal tmpPgpClk : std_logic; + signal intPgpClk : std_logic; + signal intPgpRst : std_logic; + signal tmpLocClk : std_logic; + signal intUsrClk : std_logic; + signal intUsrRst : std_logic; + signal syncPgpRstIn : std_logic_vector(2 downto 0); + signal pgpRstCnt : std_logic_vector(3 downto 0); + signal syncLocRstIn : std_logic_vector(2 downto 0); + signal locRstCnt : std_logic_vector(3 downto 0); + signal dcmLock : std_logic; + signal resetIn : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output Generated Clock And Reset Signals + pgpClk <= intPgpClk; + pgpReset <= intPgpRst; + userClk <= intUsrClk; + userReset <= intUsrRst; + + -- Invert power on reset + ponReset <= not ponResetL; + + + -- DCM For PGP Clock & User Clock + U_PgpDcm: DCM_ADV + generic map ( + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "HIGH", + CLKIN_DIVIDE_BY_2 => FALSE, + CLK_FEEDBACK => "1X", + CLKOUT_PHASE_SHIFT => "NONE", + STARTUP_WAIT => false, + PHASE_SHIFT => 0, + CLKFX_MULTIPLY => UserFxMult, + CLKFX_DIVIDE => UserFxDiv, + CLKDV_DIVIDE => 2.0, + CLKIN_PERIOD => 6.4, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + FACTORY_JF => X"F0F0", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS" + ) + port map ( + CLKIN => pgpRefClk, CLKFB => intPgpClk, + CLK0 => tmpPgpClk, CLK90 => open, + CLK180 => open, CLK270 => open, + CLK2X => open, CLK2X180 => open, + CLKDV => open, CLKFX => tmpLocClk, + CLKFX180 => open, LOCKED => dcmLock, + PSDONE => open, PSCLK => '0', + PSINCDEC => '0', PSEN => '0', + DCLK => '0', DADDR => (others=>'0'), + DI => (others=>'0'), DO => open, + DRDY => open, DWE => '0', + DEN => '0', RST => ponReset + ); + + + -- Global Buffer For PGP Clock + U_PgpClkBuff: BUFG port map ( + O => intPgpClk, + I => tmpPgpClk + ); + + + -- Global Buffer For User Clock + U_LocClkBuff: BUFG port map ( + O => intUsrClk, + I => tmpLocClk + ); + + + -- Generate reset input + resetIn <= (not dcmLock) or ponReset or locReset; + + -- PGP Clock Synced Reset + process ( pgpClkIn, resetIn ) begin + if resetIn = '1' then + syncPgpRstIn <= (others=>'0') after tpd; + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + elsif rising_edge(pgpClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncPgpRstIn(0) <= '1' after tpd; + syncPgpRstIn(1) <= syncPgpRstIn(0) after tpd; + syncPgpRstIn(2) <= syncPgpRstIn(1) after tpd; + + -- Reset counter on reset + if syncPgpRstIn(2) = '0' then + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + + -- Count Up To Max Value + elsif pgpRstCnt = "1111" then + intPgpRst <= '0' after tpd; + + -- Increment counter + else + intPgpRst <= '1' after tpd; + pgpRstCnt <= pgpRstCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Local User Clock Synced Reset + process ( userClkIn, resetIn ) begin + if resetIn = '1' then + syncLocRstIn <= (others=>'0') after tpd; + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + elsif rising_edge(userClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncLocRstIn(0) <= '1' after tpd; + syncLocRstIn(1) <= syncLocRstIn(0) after tpd; + syncLocRstIn(2) <= syncLocRstIn(1) after tpd; + + -- Reset counter on reset + if syncLocRstIn(2) = '0' then + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + + -- Count Up To Max Value + elsif locRstCnt = "1111" then + intUsrRst <= '0' after tpd; + + -- Increment counter + else + intUsrRst <= '1' after tpd; + locRstCnt <= locRstCnt + 1 after tpd; + end if; + end if; + end process; + +end Pgp2GtxClk; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxDual.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxDual.vhd new file mode 100755 index 0000000000000000000000000000000000000000..f7dd22d8855168980e3a8e34f647beeb1ffdf872 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxDual.vhd @@ -0,0 +1,1294 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Dual Channel GTX Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtxDual.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/24/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, GTX and CRC blocks. +-- This module also contains the logic to control the reset of the GTX. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 09/24/2010: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtxDual is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- Pgp master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state flash + + -- PLL Reset Control + pll0TxRst : in std_logic; -- Reset transmit PLL logic + pll0RxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pll0RxReady : out std_logic; -- MGT Receive logic is ready + pll0TxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgp0RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp0LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgp0TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp0TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgp0RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp0RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgp0LocLinkReady : out std_logic; -- Local Link is ready + pgp0RemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgp0RxCellError : out std_logic; -- A cell error has occured + pgp0RxLinkDown : out std_logic; -- A link down event has occured + pgp0RxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc00FrameTxValid : in std_logic; -- User frame data is valid + vc00FrameTxReady : out std_logic; -- PGP is ready + vc00FrameTxSOF : in std_logic; -- User frame data start of frame + vc00FrameTxEOF : in std_logic; -- User frame data end of frame + vc00FrameTxEOFE : in std_logic; -- User frame data error + vc00FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc00LocBuffAFull : in std_logic; -- Local buffer almost full + vc00LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 1 + vc01FrameTxValid : in std_logic; -- User frame data is valid + vc01FrameTxReady : out std_logic; -- PGP is ready + vc01FrameTxSOF : in std_logic; -- User frame data start of frame + vc01FrameTxEOF : in std_logic; -- User frame data end of frame + vc01FrameTxEOFE : in std_logic; -- User frame data error + vc01FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc01LocBuffAFull : in std_logic; -- Local buffer almost full + vc01LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 2 + vc02FrameTxValid : in std_logic; -- User frame data is valid + vc02FrameTxReady : out std_logic; -- PGP is ready + vc02FrameTxSOF : in std_logic; -- User frame data start of frame + vc02FrameTxEOF : in std_logic; -- User frame data end of frame + vc02FrameTxEOFE : in std_logic; -- User frame data error + vc02FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc02LocBuffAFull : in std_logic; -- Local buffer almost full + vc02LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 3 + vc03FrameTxValid : in std_logic; -- User frame data is valid + vc03FrameTxReady : out std_logic; -- PGP is ready + vc03FrameTxSOF : in std_logic; -- User frame data start of frame + vc03FrameTxEOF : in std_logic; -- User frame data end of frame + vc03FrameTxEOFE : in std_logic; -- User frame data error + vc03FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc03LocBuffAFull : in std_logic; -- Local buffer almost full + vc03LocBuffFull : in std_logic; -- Local buffer full + + -- Common Frame Receive Interface For All VCs + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc00FrameRxValid : out std_logic; -- PGP frame data is valid + vc00RemBuffAFull : out std_logic; -- Remote buffer almost full + vc00RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc01FrameRxValid : out std_logic; -- PGP frame data is valid + vc01RemBuffAFull : out std_logic; -- Remote buffer almost full + vc01RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc02FrameRxValid : out std_logic; -- PGP frame data is valid + vc02RemBuffAFull : out std_logic; -- Remote buffer almost full + vc02RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc03FrameRxValid : out std_logic; -- PGP frame data is valid + vc03RemBuffAFull : out std_logic; -- Remote buffer almost full + vc03RemBuffFull : out std_logic; -- Remote buffer full + + -- PLL Reset Control + pll1TxRst : in std_logic; -- Reset transmit PLL logic + pll1RxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pll1RxReady : out std_logic; -- MGT Receive logic is ready + pll1TxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgp1RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp1LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgp1TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp1TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgp1RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp1RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgp1LocLinkReady : out std_logic; -- Local Link is ready + pgp1RemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgp1RxCellError : out std_logic; -- A cell error has occured + pgp1RxLinkDown : out std_logic; -- A link down event has occured + pgp1RxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc10FrameTxValid : in std_logic; -- User frame data is valid + vc10FrameTxReady : out std_logic; -- PGP is ready + vc10FrameTxSOF : in std_logic; -- User frame data start of frame + vc10FrameTxEOF : in std_logic; -- User frame data end of frame + vc10FrameTxEOFE : in std_logic; -- User frame data error + vc10FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc10LocBuffAFull : in std_logic; -- Local buffer almost full + vc10LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 1 + vc11FrameTxValid : in std_logic; -- User frame data is valid + vc11FrameTxReady : out std_logic; -- PGP is ready + vc11FrameTxSOF : in std_logic; -- User frame data start of frame + vc11FrameTxEOF : in std_logic; -- User frame data end of frame + vc11FrameTxEOFE : in std_logic; -- User frame data error + vc11FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc11LocBuffAFull : in std_logic; -- Local buffer almost full + vc11LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 2 + vc12FrameTxValid : in std_logic; -- User frame data is valid + vc12FrameTxReady : out std_logic; -- PGP is ready + vc12FrameTxSOF : in std_logic; -- User frame data start of frame + vc12FrameTxEOF : in std_logic; -- User frame data end of frame + vc12FrameTxEOFE : in std_logic; -- User frame data error + vc12FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc12LocBuffAFull : in std_logic; -- Local buffer almost full + vc12LocBuffFull : in std_logic; -- Local buffer full + + -- Frame Transmit Interface, VC 3 + vc13FrameTxValid : in std_logic; -- User frame data is valid + vc13FrameTxReady : out std_logic; -- PGP is ready + vc13FrameTxSOF : in std_logic; -- User frame data start of frame + vc13FrameTxEOF : in std_logic; -- User frame data end of frame + vc13FrameTxEOFE : in std_logic; -- User frame data error + vc13FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc13LocBuffAFull : in std_logic; -- Local buffer almost full + vc13LocBuffFull : in std_logic; -- Local buffer full + + -- Common Frame Receive Interface For All VCs + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc10FrameRxValid : out std_logic; -- PGP frame data is valid + vc10RemBuffAFull : out std_logic; -- Remote buffer almost full + vc10RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc11FrameRxValid : out std_logic; -- PGP frame data is valid + vc11RemBuffAFull : out std_logic; -- Remote buffer almost full + vc11RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc12FrameRxValid : out std_logic; -- PGP frame data is valid + vc12RemBuffAFull : out std_logic; -- Remote buffer almost full + vc12RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc13FrameRxValid : out std_logic; -- PGP frame data is valid + vc13RemBuffAFull : out std_logic; -- Remote buffer almost full + vc13RemBuffFull : out std_logic; -- Remote buffer full + + -- GTX Status & Control Signals + gtxLoopback : in std_logic_vector(1 downto 0); -- GTX Serial Loopback Control + + -- MGT Signals Clock & IO Signals + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic_vector(1 downto 0); -- GTX Rx Recovered Clock + gtxRxN : in std_logic_vector(1 downto 0); -- GTX Serial Receive Negative + gtxRxP : in std_logic_vector(1 downto 0); -- GTX Serial Receive Positive + gtxTxN : out std_logic_vector(1 downto 0); -- GTX Serial Transmit Negative + gtxTxP : out std_logic_vector(1 downto 0); -- GTX Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(127 downto 0) + ); + +end Pgp2GtxDual; + + +-- Define architecture +architecture Pgp2GtxDual of Pgp2GtxDual is + + -- Local Signals + signal crc0TxIn : std_logic_vector(15 downto 0); + signal crc0TxInGtx : std_logic_vector(31 downto 0); + signal crc0TxInit : std_logic; + signal crc0TxRst : std_logic; + signal crc0TxValid : std_logic; + signal crc0TxWidth : std_logic_vector(2 downto 0); + signal crc0TxOut : std_logic_vector(31 downto 0); + signal crc0TxOutGtx : std_logic_vector(31 downto 0); + signal crc0RxIn : std_logic_vector(15 downto 0); + signal crc0RxInGtx : std_logic_vector(31 downto 0); + signal crc0RxInit : std_logic; + signal crc0RxRst : std_logic; + signal crc0RxValid : std_logic; + signal crc0RxWidth : std_logic_vector(2 downto 0); + signal crc0RxOut : std_logic_vector(31 downto 0); + signal crc0RxOutGtx : std_logic_vector(31 downto 0); + signal phy0RxPolarity : std_logic_vector(0 downto 0); + signal phy0RxData : std_logic_vector(15 downto 0); + signal phy0RxDataK : std_logic_vector(1 downto 0); + signal phy0TxData : std_logic_vector(15 downto 0); + signal phy0TxDataK : std_logic_vector(1 downto 0); + signal phy0RxDispErr : std_logic_vector(1 downto 0); + signal phy0RxDecErr : std_logic_vector(1 downto 0); + signal phy0RxReady : std_logic; + signal phy0RxInit : std_logic; + signal phy0TxReady : std_logic; + signal phy0RxReset : std_logic; + signal phy0RxElecIdle : std_logic; + signal phy0RxCdrReset : std_logic; + signal phy0RstDone : std_logic; + signal phy0RxBuffStatus : std_logic_vector(2 downto 0); + signal phy0TxReset : std_logic; + signal phy0TxBuffStatus : std_logic_vector(1 downto 0); + signal phyLockDetect : std_logic; + signal int0TxRst : std_logic; + signal int0RxRst : std_logic; + signal pgp0RxLinkReady : std_logic; + signal pgp0TxLinkReady : std_logic; + signal crc1TxIn : std_logic_vector(15 downto 0); + signal crc1TxInGtx : std_logic_vector(31 downto 0); + signal crc1TxInit : std_logic; + signal crc1TxRst : std_logic; + signal crc1TxValid : std_logic; + signal crc1TxWidth : std_logic_vector(2 downto 0); + signal crc1TxOut : std_logic_vector(31 downto 0); + signal crc1TxOutGtx : std_logic_vector(31 downto 0); + signal crc1RxIn : std_logic_vector(15 downto 0); + signal crc1RxInGtx : std_logic_vector(31 downto 0); + signal crc1RxInit : std_logic; + signal crc1RxRst : std_logic; + signal crc1RxValid : std_logic; + signal crc1RxWidth : std_logic_vector(2 downto 0); + signal crc1RxOut : std_logic_vector(31 downto 0); + signal crc1RxOutGtx : std_logic_vector(31 downto 0); + signal phy1RxPolarity : std_logic_vector(0 downto 0); + signal phy1RxData : std_logic_vector(15 downto 0); + signal phy1RxDataK : std_logic_vector(1 downto 0); + signal phy1TxData : std_logic_vector(15 downto 0); + signal phy1TxDataK : std_logic_vector(1 downto 0); + signal phy1RxDispErr : std_logic_vector(1 downto 0); + signal phy1RxDecErr : std_logic_vector(1 downto 0); + signal phy1RxReady : std_logic; + signal phy1RxInit : std_logic; + signal phy1TxReady : std_logic; + signal phy1RxReset : std_logic; + signal phy1RxElecIdle : std_logic; + signal phy1RxCdrReset : std_logic; + signal phy1RstDone : std_logic; + signal phy1RxBuffStatus : std_logic_vector(2 downto 0); + signal phy1TxReset : std_logic; + signal phy1TxBuffStatus : std_logic_vector(1 downto 0); + signal int1TxRst : std_logic; + signal int1RxRst : std_logic; + signal pgp1RxLinkReady : std_logic; + signal pgp1TxLinkReady : std_logic; + signal intRxRecClk : std_logic; + signal tmpRefClkOut : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + ------------------------------------------ + -- PGP Lane 0 + ------------------------------------------ + + -- PGP RX Block + U_Pgp2Rx0: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgp0RxLinkReady, + pgpRxCellError => pgp0RxCellError, + pgpRxLinkDown => pgp0RxLinkDown, + pgpRxLinkError => pgp0RxLinkError, + pgpRxOpCodeEn => pgp0RxOpCodeEn, + pgpRxOpCode => pgp0RxOpCode, + pgpRemLinkReady => pgp0RemLinkReady, + pgpRemData => pgp0RemData, + vcFrameRxSOF => vc0FrameRxSOF, + vcFrameRxEOF => vc0FrameRxEOF, + vcFrameRxEOFE => vc0FrameRxEOFE, + vcFrameRxData => vc0FrameRxData, + vc0FrameRxValid => vc00FrameRxValid, + vc0RemBuffAFull => vc00RemBuffAFull, + vc0RemBuffFull => vc00RemBuffFull, + vc1FrameRxValid => vc01FrameRxValid, + vc1RemBuffAFull => vc01RemBuffAFull, + vc1RemBuffFull => vc01RemBuffFull, + vc2FrameRxValid => vc02FrameRxValid, + vc2RemBuffAFull => vc02RemBuffAFull, + vc2RemBuffFull => vc02RemBuffFull, + vc3FrameRxValid => vc03FrameRxValid, + vc3RemBuffAFull => vc03RemBuffAFull, + vc3RemBuffFull => vc03RemBuffFull, + phyRxPolarity => phy0RxPolarity, + phyRxData => phy0RxData, + phyRxDataK => phy0RxDataK, + phyRxDispErr => phy0RxDispErr, + phyRxDecErr => phy0RxDecErr, + phyRxReady => phy0RxReady, + phyRxInit => phy0RxInit, + crcRxIn => crc0RxIn, + crcRxWidth => open, + crcRxInit => crc0RxInit, + crcRxValid => crc0RxValid, + crcRxOut => crc0RxOut, + debug => debug(63 downto 0) + ); + + + -- PGP TX Block + U_Pgp2Tx0: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgp0TxLinkReady, + pgpTxOpCodeEn => pgp0TxOpCodeEn, + pgpTxOpCode => pgp0TxOpCode, + pgpLocLinkReady => pgp0RxLinkReady, + pgpLocData => pgp0LocData, + vc0FrameTxValid => vc00FrameTxValid, + vc0FrameTxReady => vc00FrameTxReady, + vc0FrameTxSOF => vc00FrameTxSOF, + vc0FrameTxEOF => vc00FrameTxEOF, + vc0FrameTxEOFE => vc00FrameTxEOFE, + vc0FrameTxData => vc00FrameTxData, + vc0LocBuffAFull => vc00LocBuffAFull, + vc0LocBuffFull => vc00LocBuffFull, + vc1FrameTxValid => vc01FrameTxValid, + vc1FrameTxReady => vc01FrameTxReady, + vc1FrameTxSOF => vc01FrameTxSOF, + vc1FrameTxEOF => vc01FrameTxEOF, + vc1FrameTxEOFE => vc01FrameTxEOFE, + vc1FrameTxData => vc01FrameTxData, + vc1LocBuffAFull => vc01LocBuffAFull, + vc1LocBuffFull => vc01LocBuffFull, + vc2FrameTxValid => vc02FrameTxValid, + vc2FrameTxReady => vc02FrameTxReady, + vc2FrameTxSOF => vc02FrameTxSOF, + vc2FrameTxEOF => vc02FrameTxEOF, + vc2FrameTxEOFE => vc02FrameTxEOFE, + vc2FrameTxData => vc02FrameTxData, + vc2LocBuffAFull => vc02LocBuffAFull, + vc2LocBuffFull => vc02LocBuffFull, + vc3FrameTxValid => vc03FrameTxValid, + vc3FrameTxReady => vc03FrameTxReady, + vc3FrameTxSOF => vc03FrameTxSOF, + vc3FrameTxEOF => vc03FrameTxEOF, + vc3FrameTxEOFE => vc03FrameTxEOFE, + vc3FrameTxData => vc03FrameTxData, + vc3LocBuffAFull => vc03LocBuffAFull, + vc3LocBuffFull => vc03LocBuffFull, + phyTxData => phy0TxData, + phyTxDataK => phy0TxDataK, + phyTxReady => phy0TxReady, + crcTxIn => crc0TxIn, + crcTxInit => crc0TxInit, + crcTxValid => crc0TxValid, + crcTxOut => crc0TxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crc0TxWidth <= "001"; + crc0RxWidth <= "001"; + crc0RxRst <= int0RxRst or crc0RxInit; + crc0TxRst <= int0TxRst or crc0TxInit; + + -- Pass CRC data in on proper bits + crc0TxInGtx(31 downto 24) <= crc0TxIn(7 downto 0); + crc0TxInGtx(23 downto 16) <= crc0TxIn(15 downto 8); + crc0TxInGtx(15 downto 0) <= (others=>'0'); + crc0RxInGtx(31 downto 24) <= crc0RxIn(7 downto 0); + crc0RxInGtx(23 downto 16) <= crc0RxIn(15 downto 8); + crc0RxInGtx(15 downto 0) <= (others=>'0'); + + -- Pll Resets + int0TxRst <= pll0TxRst or pgpReset; + int0RxRst <= pll0RxRst or pgpReset; + + -- PLL Lock + pll0RxReady <= phy0RxReady; + pll0TxReady <= phy0TxReady; + + -- Link Ready + pgp0LocLinkReady <= pgp0RxLinkReady and pgp0TxLinkReady; + + -- Invert Output CRC + crc0RxOut <= not crc0RxOutGtx; + crc0TxOut <= not crc0TxOutGtx; + + + -- TX CRC BLock + Tx_CRC0: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc0TxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crc0TxValid, + CRCDATAWIDTH => crc0TxWidth, + CRCIN => crc0TxInGtx, + CRCRESET => crc0TxRst + ); + + + -- RX CRC BLock + Rx_CRC0: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc0RxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crc0RxValid, + CRCDATAWIDTH => crc0RxWidth, + CRCIN => crc0RxInGtx, + CRCRESET => crc0RxRst + ); + + + -- RX Reset Control + U_Pgp2GtxRxRst0: Pgp2GtxPackage.Pgp2GtxRxRst + port map ( + gtxRxClk => pgpClk, + gtxRxRst => int0RxRst, + gtxRxReady => phy0RxReady, + gtxRxInit => phy0RxInit, + gtxLockDetect => phyLockDetect, + gtxRxElecIdle => phy0RxElecIdle, + gtxRxBuffStatus => phy0RxBuffStatus, + gtxRstDone => phy0RstDone, + gtxRxReset => phy0RxReset, + gtxRxCdrReset => phy0RxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtxTxRst0: Pgp2GtxPackage.Pgp2GtxTxRst + port map ( + gtxTxClk => pgpClk, + gtxTxRst => int0TxRst, + gtxTxReady => phy0TxReady, + gtxLockDetect => phyLockDetect, + gtxTxBuffStatus => phy0TxBuffStatus, + gtxRstDone => phy0RstDone, + gtxTxReset => phy0TxReset + ); + + + ------------------------------------------ + -- PGP Lane 1 + ------------------------------------------ + + -- PGP RX Block + U_Pgp2Rx1: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgp1RxLinkReady, + pgpRxCellError => pgp1RxCellError, + pgpRxLinkDown => pgp1RxLinkDown, + pgpRxLinkError => pgp1RxLinkError, + pgpRxOpCodeEn => pgp1RxOpCodeEn, + pgpRxOpCode => pgp1RxOpCode, + pgpRemLinkReady => pgp1RemLinkReady, + pgpRemData => pgp1RemData, + vcFrameRxSOF => vc1FrameRxSOF, + vcFrameRxEOF => vc1FrameRxEOF, + vcFrameRxEOFE => vc1FrameRxEOFE, + vcFrameRxData => vc1FrameRxData, + vc0FrameRxValid => vc10FrameRxValid, + vc0RemBuffAFull => vc10RemBuffAFull, + vc0RemBuffFull => vc10RemBuffFull, + vc1FrameRxValid => vc11FrameRxValid, + vc1RemBuffAFull => vc11RemBuffAFull, + vc1RemBuffFull => vc11RemBuffFull, + vc2FrameRxValid => vc12FrameRxValid, + vc2RemBuffAFull => vc12RemBuffAFull, + vc2RemBuffFull => vc12RemBuffFull, + vc3FrameRxValid => vc13FrameRxValid, + vc3RemBuffAFull => vc13RemBuffAFull, + vc3RemBuffFull => vc13RemBuffFull, + phyRxPolarity => phy1RxPolarity, + phyRxData => phy1RxData, + phyRxDataK => phy1RxDataK, + phyRxDispErr => phy1RxDispErr, + phyRxDecErr => phy1RxDecErr, + phyRxReady => phy1RxReady, + phyRxInit => phy1RxInit, + crcRxIn => crc1RxIn, + crcRxWidth => open, + crcRxInit => crc1RxInit, + crcRxValid => crc1RxValid, + crcRxOut => crc1RxOut, + debug => debug(127 downto 64) + ); + + + -- PGP TX Block + U_Pgp2Tx1: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgp1TxLinkReady, + pgpTxOpCodeEn => pgp1TxOpCodeEn, + pgpTxOpCode => pgp1TxOpCode, + pgpLocLinkReady => pgp1RxLinkReady, + pgpLocData => pgp1LocData, + vc0FrameTxValid => vc10FrameTxValid, + vc0FrameTxReady => vc10FrameTxReady, + vc0FrameTxSOF => vc10FrameTxSOF, + vc0FrameTxEOF => vc10FrameTxEOF, + vc0FrameTxEOFE => vc10FrameTxEOFE, + vc0FrameTxData => vc10FrameTxData, + vc0LocBuffAFull => vc10LocBuffAFull, + vc0LocBuffFull => vc10LocBuffFull, + vc1FrameTxValid => vc11FrameTxValid, + vc1FrameTxReady => vc11FrameTxReady, + vc1FrameTxSOF => vc11FrameTxSOF, + vc1FrameTxEOF => vc11FrameTxEOF, + vc1FrameTxEOFE => vc11FrameTxEOFE, + vc1FrameTxData => vc11FrameTxData, + vc1LocBuffAFull => vc11LocBuffAFull, + vc1LocBuffFull => vc11LocBuffFull, + vc2FrameTxValid => vc12FrameTxValid, + vc2FrameTxReady => vc12FrameTxReady, + vc2FrameTxSOF => vc12FrameTxSOF, + vc2FrameTxEOF => vc12FrameTxEOF, + vc2FrameTxEOFE => vc12FrameTxEOFE, + vc2FrameTxData => vc12FrameTxData, + vc2LocBuffAFull => vc12LocBuffAFull, + vc2LocBuffFull => vc12LocBuffFull, + vc3FrameTxValid => vc13FrameTxValid, + vc3FrameTxReady => vc13FrameTxReady, + vc3FrameTxSOF => vc13FrameTxSOF, + vc3FrameTxEOF => vc13FrameTxEOF, + vc3FrameTxEOFE => vc13FrameTxEOFE, + vc3FrameTxData => vc13FrameTxData, + vc3LocBuffAFull => vc13LocBuffAFull, + vc3LocBuffFull => vc13LocBuffFull, + phyTxData => phy1TxData, + phyTxDataK => phy1TxDataK, + phyTxReady => phy1TxReady, + crcTxIn => crc1TxIn, + crcTxInit => crc1TxInit, + crcTxValid => crc1TxValid, + crcTxOut => crc1TxOut, + debug => open + ); + + + -- Adapt CRC data width flag + crc1TxWidth <= "001"; + crc1RxWidth <= "001"; + crc1RxRst <= int1RxRst or crc1RxInit; + crc1TxRst <= int1TxRst or crc1TxInit; + + -- Pass CRC data in on proper bits + crc1TxInGtx(31 downto 24) <= crc1TxIn(7 downto 0); + crc1TxInGtx(23 downto 16) <= crc1TxIn(15 downto 8); + crc1TxInGtx(15 downto 0) <= (others=>'0'); + crc1RxInGtx(31 downto 24) <= crc1RxIn(7 downto 0); + crc1RxInGtx(23 downto 16) <= crc1RxIn(15 downto 8); + crc1RxInGtx(15 downto 0) <= (others=>'0'); + + -- Pll Resets + int1TxRst <= pll1TxRst or pgpReset; + int1RxRst <= pll1RxRst or pgpReset; + + -- PLL Lock + pll1RxReady <= phy1RxReady; + pll1TxReady <= phy1TxReady; + + -- Link Ready + pgp1LocLinkReady <= pgp1RxLinkReady and pgp1TxLinkReady; + + -- Invert Output CRC + crc1RxOut <= not crc1RxOutGtx; + crc1TxOut <= not crc1TxOutGtx; + + + -- TX CRC BLock + Tx_CRC1: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc1TxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crc1TxValid, + CRCDATAWIDTH => crc1TxWidth, + CRCIN => crc1TxInGtx, + CRCRESET => crc1TxRst + ); + + + -- RX CRC BLock + Rx_CRC1: CRC32 + generic map( + CRC_INIT => x"FFFFFFFF" + ) port map( + CRCOUT => crc1RxOutGtx, + CRCCLK => pgpClk, + CRCDATAVALID => crc1RxValid, + CRCDATAWIDTH => crc1RxWidth, + CRCIN => crc1RxInGtx, + CRCRESET => crc1RxRst + ); + + + -- RX Reset Control + U_Pgp2GtxRxRst1: Pgp2GtxPackage.Pgp2GtxRxRst + port map ( + gtxRxClk => pgpClk, + gtxRxRst => int1RxRst, + gtxRxReady => phy1RxReady, + gtxRxInit => phy1RxInit, + gtxLockDetect => phyLockDetect, + gtxRxElecIdle => phy1RxElecIdle, + gtxRxBuffStatus => phy1RxBuffStatus, + gtxRstDone => phy1RstDone, + gtxRxReset => phy1RxReset, + gtxRxCdrReset => phy1RxCdrReset + ); + + + -- TX Reset Control + U_Pgp2GtxTxRst1: Pgp2GtxPackage.Pgp2GtxTxRst + port map ( + gtxTxClk => pgpClk, + gtxTxRst => int1TxRst, + gtxTxReady => phy1TxReady, + gtxLockDetect => phyLockDetect, + gtxTxBuffStatus => phy1TxBuffStatus, + gtxRstDone => phy1RstDone, + gtxTxReset => phy1TxReset + ); + + + ----------------------------- GTX_DUAL Instance -------------------------- + UGtxDual:GTX_DUAL + generic map ( + + --_______________________ Simulation-Only Attributes ___________________ + + SIM_RECEIVER_DETECT_PASS_0 => TRUE, + SIM_RECEIVER_DETECT_PASS_1 => TRUE, + SIM_MODE => "FAST", + SIM_GTXRESET_SPEEDUP => 1, + SIM_PLL_PERDIV2 => x"140", + + --___________________________ Shared Attributes ________________________ + + -------------------------- Tile and PLL Attributes --------------------- + + CLK25_DIVIDER => 10, + CLKINDC_B => TRUE, + OOB_CLK_DIVIDER => 6, + OVERSAMPLE_MODE => FALSE, + PLL_DIVSEL_FB => 2, + PLL_DIVSEL_REF => 1, + CLKRCV_TRST => TRUE, + PLL_COM_CFG => x"21680a", + PLL_CP_CFG => x"00", + PLL_FB_DCCEN => FALSE, + PLL_LKDET_CFG => "101", + PLL_TDCC_CFG => "000", + PMA_COM_CFG => x"000000000000000000", + + --____________________ Transmit Interface Attributes ___________________ + + ------------------- TX Buffering and Phase Alignment ------------------- + + TX_BUFFER_USE_0 => TRUE, + TX_XCLK_SEL_0 => "TXOUT", + TXRX_INVERT_0 => "011", + + TX_BUFFER_USE_1 => TRUE, + TX_XCLK_SEL_1 => "TXOUT", + TXRX_INVERT_1 => "011", + + --------------------- TX Gearbox Settings ----------------------------- + + GEARBOX_ENDEC_0 => "000", + TXGEARBOX_USE_0 => FALSE, + + GEARBOX_ENDEC_1 => "000", + TXGEARBOX_USE_1 => FALSE, + + --------------------- TX Serial Line Rate settings --------------------- + + PLL_TXDIVSEL_OUT_0 => 1, + PLL_TXDIVSEL_OUT_1 => 1, + + --------------------- TX Driver and OOB signalling -------------------- + + CM_TRIM_0 => "10", + PMA_TX_CFG_0 => x"80082", + TX_DETECT_RX_CFG_0 => x"1832", + TX_IDLE_DELAY_0 => "010", + CM_TRIM_1 => "10", + PMA_TX_CFG_1 => x"80082", + TX_DETECT_RX_CFG_1 => x"1832", + TX_IDLE_DELAY_1 => "010", + + ------------------ TX Pipe Control for PCI Express/SATA --------------- + + COM_BURST_VAL_0 => "1111", + COM_BURST_VAL_1 => "1111", + + --_______________________ Receive Interface Attributes ________________ + + ------------ RX Driver,OOB signalling,Coupling and Eq,CDR ------------- + + AC_CAP_DIS_0 => TRUE, + OOBDETECT_THRESHOLD_0 => "111", + PMA_CDR_SCAN_0 => x"640403a", + PMA_RX_CFG_0 => x"0f44088", + RCV_TERM_GND_0 => FALSE, + RCV_TERM_VTTRX_0 => TRUE, + TERMINATION_IMP_0 => 50, + AC_CAP_DIS_1 => TRUE, + OOBDETECT_THRESHOLD_1 => "111", + PMA_CDR_SCAN_1 => x"640403a", + PMA_RX_CFG_1 => x"0f44088", + RCV_TERM_GND_1 => FALSE, + RCV_TERM_VTTRX_1 => TRUE, + TERMINATION_IMP_1 => 50, + TERMINATION_CTRL => "10100", + TERMINATION_OVRD => FALSE, + + ---------------- RX Decision Feedback Equalizer(DFE) ---------------- + + DFE_CFG_0 => "1001111011", + DFE_CFG_1 => "1001111011", + DFE_CAL_TIME => "00110", + + --------------------- RX Serial Line Rate Attributes ------------------ + + PLL_RXDIVSEL_OUT_0 => 1, + PLL_SATA_0 => FALSE, + PLL_RXDIVSEL_OUT_1 => 1, + PLL_SATA_1 => FALSE, + + ----------------------- PRBS Detection Attributes --------------------- + + PRBS_ERR_THRESHOLD_0 => x"00000001", + PRBS_ERR_THRESHOLD_1 => x"00000001", + + ---------------- Comma Detection and Alignment Attributes ------------- + + ALIGN_COMMA_WORD_0 => 2, + COMMA_10B_ENABLE_0 => "1111111111", + COMMA_DOUBLE_0 => FALSE, + DEC_MCOMMA_DETECT_0 => TRUE, + DEC_PCOMMA_DETECT_0 => TRUE, + DEC_VALID_COMMA_ONLY_0 => FALSE, + MCOMMA_10B_VALUE_0 => "1010000011", + MCOMMA_DETECT_0 => TRUE, + PCOMMA_10B_VALUE_0 => "0101111100", + PCOMMA_DETECT_0 => TRUE, + RX_SLIDE_MODE_0 => "PCS", + + ALIGN_COMMA_WORD_1 => 2, + COMMA_10B_ENABLE_1 => "1111111111", + COMMA_DOUBLE_1 => FALSE, + DEC_MCOMMA_DETECT_1 => TRUE, + DEC_PCOMMA_DETECT_1 => TRUE, + DEC_VALID_COMMA_ONLY_1 => FALSE, + MCOMMA_10B_VALUE_1 => "1010000011", + MCOMMA_DETECT_1 => TRUE, + PCOMMA_10B_VALUE_1 => "0101111100", + PCOMMA_DETECT_1 => TRUE, + RX_SLIDE_MODE_1 => "PCS", + + ------------------ RX Loss-of-sync State Machine Attributes ----------- + + RX_LOSS_OF_SYNC_FSM_0 => FALSE, + RX_LOS_INVALID_INCR_0 => 8, + RX_LOS_THRESHOLD_0 => 128, + RX_LOSS_OF_SYNC_FSM_1 => FALSE, + RX_LOS_INVALID_INCR_1 => 8, + RX_LOS_THRESHOLD_1 => 128, + + --------------------- RX Gearbox Settings ----------------------------- + + RXGEARBOX_USE_0 => FALSE, + RXGEARBOX_USE_1 => FALSE, + + -------------- RX Elastic Buffer and Phase alignment Attributes ------- + + PMA_RXSYNC_CFG_0 => x"00", + RX_BUFFER_USE_0 => TRUE, + RX_XCLK_SEL_0 => "RXREC", + PMA_RXSYNC_CFG_1 => x"00", + RX_BUFFER_USE_1 => TRUE, + RX_XCLK_SEL_1 => "RXREC", + + ------------------------ Clock Correction Attributes ------------------ + + CLK_CORRECT_USE_0 => TRUE, + CLK_COR_ADJ_LEN_0 => 4, + CLK_COR_DET_LEN_0 => 4, + CLK_COR_INSERT_IDLE_FLAG_0 => FALSE, + CLK_COR_KEEP_IDLE_0 => FALSE, + CLK_COR_MAX_LAT_0 => 48, + CLK_COR_MIN_LAT_0 => 36, + CLK_COR_PRECEDENCE_0 => TRUE, + CLK_COR_REPEAT_WAIT_0 => 0, + CLK_COR_SEQ_1_1_0 => "0110111100", + CLK_COR_SEQ_1_2_0 => "0100011100", + CLK_COR_SEQ_1_3_0 => "0100011100", + CLK_COR_SEQ_1_4_0 => "0100011100", + CLK_COR_SEQ_1_ENABLE_0 => "1111", + CLK_COR_SEQ_2_1_0 => "0000000000", + CLK_COR_SEQ_2_2_0 => "0000000000", + CLK_COR_SEQ_2_3_0 => "0000000000", + CLK_COR_SEQ_2_4_0 => "0000000000", + CLK_COR_SEQ_2_ENABLE_0 => "0000", + CLK_COR_SEQ_2_USE_0 => FALSE, + RX_DECODE_SEQ_MATCH_0 => TRUE, + + CLK_CORRECT_USE_1 => TRUE, + CLK_COR_ADJ_LEN_1 => 4, + CLK_COR_DET_LEN_1 => 4, + CLK_COR_INSERT_IDLE_FLAG_1 => FALSE, + CLK_COR_KEEP_IDLE_1 => FALSE, + CLK_COR_MAX_LAT_1 => 48, + CLK_COR_MIN_LAT_1 => 36, + CLK_COR_PRECEDENCE_1 => TRUE, + CLK_COR_REPEAT_WAIT_1 => 0, + CLK_COR_SEQ_1_1_1 => "0110111100", + CLK_COR_SEQ_1_2_1 => "0100011100", + CLK_COR_SEQ_1_3_1 => "0100011100", + CLK_COR_SEQ_1_4_1 => "0100011100", + CLK_COR_SEQ_1_ENABLE_1 => "1111", + CLK_COR_SEQ_2_1_1 => "0000000000", + CLK_COR_SEQ_2_2_1 => "0000000000", + CLK_COR_SEQ_2_3_1 => "0000000000", + CLK_COR_SEQ_2_4_1 => "0000000000", + CLK_COR_SEQ_2_ENABLE_1 => "0000", + CLK_COR_SEQ_2_USE_1 => FALSE, + RX_DECODE_SEQ_MATCH_1 => TRUE, + + ------------------------ Channel Bonding Attributes ------------------- + + CB2_INH_CC_PERIOD_0 => 8, + CHAN_BOND_KEEP_ALIGN_0 => FALSE, + CHAN_BOND_1_MAX_SKEW_0 => 1, + CHAN_BOND_2_MAX_SKEW_0 => 1, + CHAN_BOND_LEVEL_0 => 0, + CHAN_BOND_MODE_0 => "OFF", + CHAN_BOND_SEQ_1_1_0 => "0000000000", + CHAN_BOND_SEQ_1_2_0 => "0000000000", + CHAN_BOND_SEQ_1_3_0 => "0000000000", + CHAN_BOND_SEQ_1_4_0 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_1_0 => "0000000000", + CHAN_BOND_SEQ_2_2_0 => "0000000000", + CHAN_BOND_SEQ_2_3_0 => "0000000000", + CHAN_BOND_SEQ_2_4_0 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_0 => "0000", + CHAN_BOND_SEQ_2_USE_0 => FALSE, + CHAN_BOND_SEQ_LEN_0 => 1, + PCI_EXPRESS_MODE_0 => FALSE, + + CB2_INH_CC_PERIOD_1 => 8, + CHAN_BOND_KEEP_ALIGN_1 => FALSE, + CHAN_BOND_1_MAX_SKEW_1 => 1, + CHAN_BOND_2_MAX_SKEW_1 => 1, + CHAN_BOND_LEVEL_1 => 0, + CHAN_BOND_MODE_1 => "OFF", + CHAN_BOND_SEQ_1_1_1 => "0000000000", + CHAN_BOND_SEQ_1_2_1 => "0000000000", + CHAN_BOND_SEQ_1_3_1 => "0000000000", + CHAN_BOND_SEQ_1_4_1 => "0000000000", + CHAN_BOND_SEQ_1_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_1_1 => "0000000000", + CHAN_BOND_SEQ_2_2_1 => "0000000000", + CHAN_BOND_SEQ_2_3_1 => "0000000000", + CHAN_BOND_SEQ_2_4_1 => "0000000000", + CHAN_BOND_SEQ_2_ENABLE_1 => "0000", + CHAN_BOND_SEQ_2_USE_1 => FALSE, + CHAN_BOND_SEQ_LEN_1 => 1, + PCI_EXPRESS_MODE_1 => FALSE, + + -------- RX Attributes to Control Reset after Electrical Idle ------ + + RX_EN_IDLE_HOLD_DFE_0 => TRUE, + RX_EN_IDLE_RESET_BUF_0 => TRUE, + RX_IDLE_HI_CNT_0 => "1000", + RX_IDLE_LO_CNT_0 => "0000", + RX_EN_IDLE_HOLD_DFE_1 => TRUE, + RX_EN_IDLE_RESET_BUF_1 => TRUE, + RX_IDLE_HI_CNT_1 => "1000", + RX_IDLE_LO_CNT_1 => "0000", + CDR_PH_ADJ_TIME => "01010", + RX_EN_IDLE_RESET_FR => TRUE, + RX_EN_IDLE_HOLD_CDR => FALSE, + RX_EN_IDLE_RESET_PH => TRUE, + + ------------------ RX Attributes for PCI Express/SATA --------------- + + RX_STATUS_FMT_0 => "PCIE", + SATA_BURST_VAL_0 => "100", + SATA_IDLE_VAL_0 => "100", + SATA_MAX_BURST_0 => 7, + SATA_MAX_INIT_0 => 22, + SATA_MAX_WAKE_0 => 7, + SATA_MIN_BURST_0 => 4, + SATA_MIN_INIT_0 => 12, + SATA_MIN_WAKE_0 => 4, + TRANS_TIME_FROM_P2_0 => x"003C", + TRANS_TIME_NON_P2_0 => x"0019", + TRANS_TIME_TO_P2_0 => x"0064", + + RX_STATUS_FMT_1 => "PCIE", + SATA_BURST_VAL_1 => "100", + SATA_IDLE_VAL_1 => "100", + SATA_MAX_BURST_1 => 7, + SATA_MAX_INIT_1 => 22, + SATA_MAX_WAKE_1 => 7, + SATA_MIN_BURST_1 => 4, + SATA_MIN_INIT_1 => 12, + SATA_MIN_WAKE_1 => 4, + TRANS_TIME_FROM_P2_1 => x"003C", + TRANS_TIME_NON_P2_1 => x"0019", + TRANS_TIME_TO_P2_1 => x"0064" + + ) port map ( + + ------------------------ Loopback and Powerdown Ports ---------------------- + LOOPBACK0(0) => '0', + LOOPBACK0(1) => gtxLoopback(0), + LOOPBACK0(2) => '0', + LOOPBACK1(0) => '0', + LOOPBACK1(1) => gtxLoopback(1), + LOOPBACK1(2) => '0', + RXPOWERDOWN0 => (others=>'0'), + RXPOWERDOWN1 => (others=>'0'), + TXPOWERDOWN0 => (others=>'0'), + TXPOWERDOWN1 => (others=>'0'), + -------------- Receive Ports - 64b66b and 64b67b Gearbox Ports ------------- + RXDATAVALID0 => open, + RXDATAVALID1 => open, + RXGEARBOXSLIP0 => '0', + RXGEARBOXSLIP1 => '0', + RXHEADER0 => open, + RXHEADER1 => open, + RXHEADERVALID0 => open, + RXHEADERVALID1 => open, + RXSTARTOFSEQ0 => open, + RXSTARTOFSEQ1 => open, + ----------------------- Receive Ports - 8b10b Decoder ---------------------- + RXCHARISCOMMA0 => open, + RXCHARISCOMMA1 => open, + RXCHARISK0(1 downto 0) => phy0RxDataK, + RXCHARISK0(3 downto 2) => open, + RXCHARISK1(1 downto 0) => phy1RxDataK, + RXCHARISK1(3 downto 2) => open, + RXDEC8B10BUSE0 => '1', + RXDEC8B10BUSE1 => '1', + RXDISPERR0(1 downto 0) => phy0RxDispErr, + RXDISPERR0(3 downto 2) => open, + RXDISPERR1(1 downto 0) => phy1RxDispErr, + RXDISPERR1(3 downto 2) => open, + RXNOTINTABLE0(1 downto 0) => phy0RxDecErr, + RXNOTINTABLE0(3 downto 2) => open, + RXNOTINTABLE1(1 downto 0) => phy1RxDecErr, + RXNOTINTABLE1(3 downto 2) => open, + RXRUNDISP0 => open, + RXRUNDISP1 => open, + ------------------- Receive Ports - Channel Bonding Ports ------------------ + RXCHANBONDSEQ0 => open, + RXCHANBONDSEQ1 => open, + RXCHBONDI0 => (others=>'0'), + RXCHBONDI1 => (others=>'0'), + RXCHBONDO0 => open, + RXCHBONDO1 => open, + RXENCHANSYNC0 => '0', + RXENCHANSYNC1 => '0', + ------------------- Receive Ports - Clock Correction Ports ----------------- + RXCLKCORCNT0 => open, + RXCLKCORCNT1 => open, + --------------- Receive Ports - Comma Detection and Alignment -------------- + RXBYTEISALIGNED0 => open, + RXBYTEISALIGNED1 => open, + RXBYTEREALIGN0 => open, + RXBYTEREALIGN1 => open, + RXCOMMADET0 => open, + RXCOMMADET1 => open, + RXCOMMADETUSE0 => '1', + RXCOMMADETUSE1 => '1', + RXENMCOMMAALIGN0 => '1', + RXENMCOMMAALIGN1 => '1', + RXENPCOMMAALIGN0 => '1', + RXENPCOMMAALIGN1 => '1', + RXSLIDE0 => '0', + RXSLIDE1 => '0', + ----------------------- Receive Ports - PRBS Detection --------------------- + PRBSCNTRESET0 => '0', + PRBSCNTRESET1 => '0', + RXENPRBSTST0 => (others=>'0'), + RXENPRBSTST1 => (others=>'0'), + RXPRBSERR0 => open, + RXPRBSERR1 => open, + ------------------- Receive Ports - RX Data Path interface ----------------- + RXDATA0(15 downto 0) => phy0RxData, + RXDATA0(31 downto 16) => open, + RXDATA1(15 downto 0) => phy1RxData, + RXDATA1(31 downto 16) => open, + RXDATAWIDTH0 => "01", + RXDATAWIDTH1 => "01", + RXRECCLK0 => int0RxRecClk, + RXRECCLK1 => int1RxRecClk, + RXRESET0 => phy0RxReset, + RXRESET1 => phy1RxReset, + RXUSRCLK0 => pgpClk, + RXUSRCLK1 => pgpClk, + RXUSRCLK20 => pgpClk, + RXUSRCLK21 => pgpClk, + ------------ Receive Ports - RX Decision Feedback Equalizer(DFE) ----------- + DFECLKDLYADJ0 => (others=>'0'), + DFECLKDLYADJ1 => (others=>'0'), + DFECLKDLYADJMONITOR0 => open, + DFECLKDLYADJMONITOR1 => open, + DFEEYEDACMONITOR0 => open, + DFEEYEDACMONITOR1 => open, + DFESENSCAL0 => open, + DFESENSCAL1 => open, + DFETAP10 => (others=>'0'), + DFETAP11 => (others=>'0'), + DFETAP1MONITOR0 => open, + DFETAP1MONITOR1 => open, + DFETAP20 => (others=>'0'), + DFETAP21 => (others=>'0'), + DFETAP2MONITOR0 => open, + DFETAP2MONITOR1 => open, + DFETAP30 => (others=>'0'), + DFETAP31 => (others=>'0'), + DFETAP3MONITOR0 => open, + DFETAP3MONITOR1 => open, + DFETAP40 => (others=>'0'), + DFETAP41 => (others=>'0'), + DFETAP4MONITOR0 => open, + DFETAP4MONITOR1 => open, + ------- Receive Ports - RX Driver,OOB signalling,Coupling and Eq.,CDR ------ + RXCDRRESET0 => phy0RxCdrReset, + RXCDRRESET1 => phy1RxCdrReset, + RXELECIDLE0 => phy0RxElecIdle, + RXELECIDLE1 => phy1RxElecIdle, + RXENEQB0 => '0', + RXENEQB1 => '0', + RXEQMIX0 => (others=>'0'), + RXEQMIX1 => (others=>'0'), + RXEQPOLE0 => (others=>'0'), + RXEQPOLE1 => (others=>'0'), + RXN0 => gtxRxN(0), + RXN1 => gtxRxN(1), + RXP0 => gtxRxP(0), + RXP1 => gtxRxP(1), + -------- Receive Ports - RX Elastic Buffer and Phase Alignment Ports ------- + RXBUFRESET0 => '0', + RXBUFRESET1 => '0', + RXBUFSTATUS0 => phy0RxBuffStatus, + RXBUFSTATUS1 => phy1RxBuffStatus, + RXCHANISALIGNED0 => open, + RXCHANISALIGNED1 => open, + RXCHANREALIGN0 => open, + RXCHANREALIGN1 => open, + RXENPMAPHASEALIGN0 => '0', + RXENPMAPHASEALIGN1 => '0', + RXPMASETPHASE0 => '0', + RXPMASETPHASE1 => '0', + RXSTATUS0 => open, + RXSTATUS1 => open, + --------------- Receive Ports - RX Loss-of-sync State Machine -------------- + RXLOSSOFSYNC0 => open, + RXLOSSOFSYNC1 => open, + ---------------------- Receive Ports - RX Oversampling --------------------- + RXENSAMPLEALIGN0 => '0', + RXENSAMPLEALIGN1 => '0', + RXOVERSAMPLEERR0 => open, + RXOVERSAMPLEERR1 => open, + -------------- Receive Ports - RX Pipe Control for PCI Express ------------- + PHYSTATUS0 => open, + PHYSTATUS1 => open, + RXVALID0 => open, + RXVALID1 => open, + ----------------- Receive Ports - RX Polarity Control Ports ---------------- + RXPOLARITY0 => phyRxPolarity(0), + RXPOLARITY1 => phyRxPolarity(1), + ------------- Shared Ports - Dynamic Reconfiguration Port (DRP) ------------ + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + --------------------- Shared Ports - Tile and PLL Ports -------------------- + CLKIN => gtxClkIn, + GTXRESET => pgpReset, + GTXTEST => "10000000000000", + INTDATAWIDTH => '1', + PLLLKDET => phyLockDetect, + PLLLKDETEN => '1', + PLLPOWERDOWN => '0', + REFCLKOUT => tmpRefClkOut, + REFCLKPWRDNB => '1', + RESETDONE0 => phy0RstDone, + RESETDONE1 => phy1RstDone, + -------------- Transmit Ports - 64b66b and 64b67b Gearbox Ports ------------ + TXGEARBOXREADY0 => open, + TXGEARBOXREADY1 => open, + TXHEADER0 => (others=>'0'), + TXHEADER1 => (others=>'0'), + TXSEQUENCE0 => (others=>'0'), + TXSEQUENCE1 => (others=>'0'), + TXSTARTSEQ0 => '0', + TXSTARTSEQ1 => '0', + ---------------- Transmit Ports - 8b10b Encoder Control Ports -------------- + TXBYPASS8B10B0 => (others=>'0'), + TXBYPASS8B10B1 => (others=>'0'), + TXCHARDISPMODE0 => (others=>'0'), + TXCHARDISPMODE1 => (others=>'0'), + TXCHARDISPVAL0 => (others=>'0'), + TXCHARDISPVAL1 => (others=>'0'), + TXCHARISK0(1 downto 0) => phy0TxDataK, + TXCHARISK0(3 downto 2) => (others=>'0'), + TXCHARISK1(1 downto 0) => phy1TxDataK, + TXCHARISK1(3 downto 2) => (others=>'0'), + TXENC8B10BUSE0 => '1', + TXENC8B10BUSE1 => '1', + TXKERR0 => open, + TXKERR1 => open, + TXRUNDISP0 => open, + TXRUNDISP1 => open, + ------------- Transmit Ports - TX Buffering and Phase Alignment ------------ + TXBUFSTATUS0 => phy0TxBuffStatus, + TXBUFSTATUS1 => phy1TxBuffStatus, + ------------------ Transmit Ports - TX Data Path interface ----------------- + TXDATA0(15 downto 0) => phy0TxData, + TXDATA0(31 downto 16) => (others=>'0'), + TXDATA1(15 downto 0) => phy1TxData, + TXDATA1(31 downto 16) => (others=>'0'), + TXDATAWIDTH0 => "01", + TXDATAWIDTH1 => "01", + TXOUTCLK0 => open, + TXOUTCLK1 => open, + TXRESET0 => phy0TxReset, + TXRESET1 => phy1TxReset, + TXUSRCLK0 => pgpClk, + TXUSRCLK1 => pgpClk, + TXUSRCLK20 => pgpClk, + TXUSRCLK21 => pgpClk, + --------------- Transmit Ports - TX Driver and OOB signalling -------------- + TXBUFDIFFCTRL0 => "100", -- 800mV + TXBUFDIFFCTRL1 => "100", + TXDIFFCTRL0 => "100", + TXDIFFCTRL1 => "100", + TXINHIBIT0 => '0', + TXINHIBIT1 => '0', + TXN0 => gtxTxN(0), + TXN1 => gtxTxN(1), + TXP0 => gtxTxP(0), + TXP1 => gtxTxP(1), + TXPREEMPHASIS0 => "0011", -- 4.5% + TXPREEMPHASIS1 => "0011", + -------- Transmit Ports - TX Elastic Buffer and Phase Alignment Ports ------ + TXENPMAPHASEALIGN0 => '0', + TXENPMAPHASEALIGN1 => '0', + TXPMASETPHASE0 => '0', + TXPMASETPHASE1 => '0', + --------------------- Transmit Ports - TX PRBS Generator ------------------- + TXENPRBSTST0 => (others=>'0'), + TXENPRBSTST1 => (others=>'0'), + -------------------- Transmit Ports - TX Polarity Control ------------------ + TXPOLARITY0 => '0', + TXPOLARITY1 => '0', + ----------------- Transmit Ports - TX Ports for PCI Express ---------------- + TXDETECTRX0 => '0', + TXDETECTRX1 => '0', + TXELECIDLE0 => '0', + TXELECIDLE1 => '0', + --------------------- Transmit Ports - TX Ports for SATA ------------------- + TXCOMSTART0 => '0', + TXCOMSTART1 => '0', + TXCOMTYPE0 => '0', + TXCOMTYPE1 => '0' + ); + + -- Global Buffer For Ref Clock Output + U_RefClkBuff: BUFG port map ( + O => gtxRefClkOut, + I => tmpRefClkOut + ); + gtxRxRecClk(0) <= int0RxRecClk; + gtxRxRecClk(1) <= int1RxRecClk; + +end Pgp2GtxDual; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxPackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxPackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..32a7ce7e86008fc71e09cad24bb314473bd9181a --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxPackage.vhd @@ -0,0 +1,391 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, GTX Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtxPackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/23/2009 +------------------------------------------------------------------------------- +-- Description: +-- GTX Components package. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/23/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2GtxPackage is + + -- 16-bit wrapper + component Pgp2Gtx16 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state flush + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + gtxLoopback : in std_logic; -- GTX Serial Loopback Control + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic; -- GTX Rx Recovered Clock + gtxRxN : in std_logic; -- GTX Serial Receive Negative + gtxRxP : in std_logic; -- GTX Serial Receive Positive + gtxTxN : out std_logic; -- GTX Serial Transmit Negative + gtxTxP : out std_logic; -- GTX Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- 16-bit wrapper, port b + component Pgp2Gtx16B + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state flush + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + gtxLoopback : in std_logic; -- GTX Serial Loopback Control + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic; -- GTX Rx Recovered Clock + gtxRxN : in std_logic; -- GTX Serial Receive Negative + gtxRxP : in std_logic; -- GTX Serial Receive Positive + gtxTxN : out std_logic; -- GTX Serial Transmit Negative + gtxTxP : out std_logic; -- GTX Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- Dual Channel Wrapper + component Pgp2GtxDual + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1 -- Interleave Frames + ); + port ( + pgpClk : in std_logic; -- Pgp master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state flush + pll0TxRst : in std_logic; -- Reset transmit PLL logic + pll0RxRst : in std_logic; -- Reset receive PLL logic + pll0RxReady : out std_logic; -- MGT Receive logic is ready + pll0TxReady : out std_logic; -- MGT Transmit logic is ready + pgp0RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp0LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgp0TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp0TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgp0RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp0RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgp0LocLinkReady : out std_logic; -- Local Link is ready + pgp0RemLinkReady : out std_logic; -- Far end side has link + pgp0RxCellError : out std_logic; -- A cell error has occured + pgp0RxLinkDown : out std_logic; -- A link down event has occured + pgp0RxLinkError : out std_logic; -- A link error has occured + vc00FrameTxValid : in std_logic; -- User frame data is valid + vc00FrameTxReady : out std_logic; -- PGP is ready + vc00FrameTxSOF : in std_logic; -- User frame data start of frame + vc00FrameTxEOF : in std_logic; -- User frame data end of frame + vc00FrameTxEOFE : in std_logic; -- User frame data error + vc00FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc00LocBuffAFull : in std_logic; -- Local buffer almost full + vc00LocBuffFull : in std_logic; -- Local buffer full + vc01FrameTxValid : in std_logic; -- User frame data is valid + vc01FrameTxReady : out std_logic; -- PGP is ready + vc01FrameTxSOF : in std_logic; -- User frame data start of frame + vc01FrameTxEOF : in std_logic; -- User frame data end of frame + vc01FrameTxEOFE : in std_logic; -- User frame data error + vc01FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc01LocBuffAFull : in std_logic; -- Local buffer almost full + vc01LocBuffFull : in std_logic; -- Local buffer full + vc02FrameTxValid : in std_logic; -- User frame data is valid + vc02FrameTxReady : out std_logic; -- PGP is ready + vc02FrameTxSOF : in std_logic; -- User frame data start of frame + vc02FrameTxEOF : in std_logic; -- User frame data end of frame + vc02FrameTxEOFE : in std_logic; -- User frame data error + vc02FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc02LocBuffAFull : in std_logic; -- Local buffer almost full + vc02LocBuffFull : in std_logic; -- Local buffer full + vc03FrameTxValid : in std_logic; -- User frame data is valid + vc03FrameTxReady : out std_logic; -- PGP is ready + vc03FrameTxSOF : in std_logic; -- User frame data start of frame + vc03FrameTxEOF : in std_logic; -- User frame data end of frame + vc03FrameTxEOFE : in std_logic; -- User frame data error + vc03FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc03LocBuffAFull : in std_logic; -- Local buffer almost full + vc03LocBuffFull : in std_logic; -- Local buffer full + vc0FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc0FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc0FrameRxEOFE : out std_logic; -- PGP frame data error + vc0FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc00FrameRxValid : out std_logic; -- PGP frame data is valid + vc00RemBuffAFull : out std_logic; -- Remote buffer almost full + vc00RemBuffFull : out std_logic; -- Remote buffer full + vc01FrameRxValid : out std_logic; -- PGP frame data is valid + vc01RemBuffAFull : out std_logic; -- Remote buffer almost full + vc01RemBuffFull : out std_logic; -- Remote buffer full + vc02FrameRxValid : out std_logic; -- PGP frame data is valid + vc02RemBuffAFull : out std_logic; -- Remote buffer almost full + vc02RemBuffFull : out std_logic; -- Remote buffer full + vc03FrameRxValid : out std_logic; -- PGP frame data is valid + vc03RemBuffAFull : out std_logic; -- Remote buffer almost full + vc03RemBuffFull : out std_logic; -- Remote buffer full + pll1TxRst : in std_logic; -- Reset transmit PLL logic + pll1RxRst : in std_logic; -- Reset receive PLL logic + pll1RxReady : out std_logic; -- MGT Receive logic is ready + pll1TxReady : out std_logic; -- MGT Transmit logic is ready + pgp1RemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgp1LocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgp1TxOpCodeEn : in std_logic; -- Opcode receive enable + pgp1TxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgp1RxOpCodeEn : out std_logic; -- Opcode receive enable + pgp1RxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgp1LocLinkReady : out std_logic; -- Local Link is ready + pgp1RemLinkReady : out std_logic; -- Far end side has link + pgp1RxCellError : out std_logic; -- A cell error has occured + pgp1RxLinkDown : out std_logic; -- A link down event has occured + pgp1RxLinkError : out std_logic; -- A link error has occured + vc10FrameTxValid : in std_logic; -- User frame data is valid + vc10FrameTxReady : out std_logic; -- PGP is ready + vc10FrameTxSOF : in std_logic; -- User frame data start of frame + vc10FrameTxEOF : in std_logic; -- User frame data end of frame + vc10FrameTxEOFE : in std_logic; -- User frame data error + vc10FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc10LocBuffAFull : in std_logic; -- Local buffer almost full + vc10LocBuffFull : in std_logic; -- Local buffer full + vc11FrameTxValid : in std_logic; -- User frame data is valid + vc11FrameTxReady : out std_logic; -- PGP is ready + vc11FrameTxSOF : in std_logic; -- User frame data start of frame + vc11FrameTxEOF : in std_logic; -- User frame data end of frame + vc11FrameTxEOFE : in std_logic; -- User frame data error + vc11FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc11LocBuffAFull : in std_logic; -- Local buffer almost full + vc11LocBuffFull : in std_logic; -- Local buffer full + vc12FrameTxValid : in std_logic; -- User frame data is valid + vc12FrameTxReady : out std_logic; -- PGP is ready + vc12FrameTxSOF : in std_logic; -- User frame data start of frame + vc12FrameTxEOF : in std_logic; -- User frame data end of frame + vc12FrameTxEOFE : in std_logic; -- User frame data error + vc12FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc12LocBuffAFull : in std_logic; -- Local buffer almost full + vc12LocBuffFull : in std_logic; -- Local buffer full + vc13FrameTxValid : in std_logic; -- User frame data is valid + vc13FrameTxReady : out std_logic; -- PGP is ready + vc13FrameTxSOF : in std_logic; -- User frame data start of frame + vc13FrameTxEOF : in std_logic; -- User frame data end of frame + vc13FrameTxEOFE : in std_logic; -- User frame data error + vc13FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc13LocBuffAFull : in std_logic; -- Local buffer almost full + vc13LocBuffFull : in std_logic; -- Local buffer full + vc1FrameRxSOF : out std_logic; -- PGP frame data start of frame + vc1FrameRxEOF : out std_logic; -- PGP frame data end of frame + vc1FrameRxEOFE : out std_logic; -- PGP frame data error + vc1FrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc10FrameRxValid : out std_logic; -- PGP frame data is valid + vc10RemBuffAFull : out std_logic; -- Remote buffer almost full + vc10RemBuffFull : out std_logic; -- Remote buffer full + vc11FrameRxValid : out std_logic; -- PGP frame data is valid + vc11RemBuffAFull : out std_logic; -- Remote buffer almost full + vc11RemBuffFull : out std_logic; -- Remote buffer full + vc12FrameRxValid : out std_logic; -- PGP frame data is valid + vc12RemBuffAFull : out std_logic; -- Remote buffer almost full + vc12RemBuffFull : out std_logic; -- Remote buffer full + vc13FrameRxValid : out std_logic; -- PGP frame data is valid + vc13RemBuffAFull : out std_logic; -- Remote buffer almost full + vc13RemBuffFull : out std_logic; -- Remote buffer full + gtxLoopback : in std_logic_vector(1 downto 0); -- GTX Serial Loopback Control + gtxClkIn : in std_logic; -- GTX Reference Clock In + gtxRefClkOut : out std_logic; -- GTX Reference Clock Output + gtxRxRecClk : out std_logic_vector(1 downto 0); -- GTX Rx Recovered Clock + gtxRxN : in std_logic_vector(1 downto 0); -- GTX Serial Receive Negative + gtxRxP : in std_logic_vector(1 downto 0); -- GTX Serial Receive Positive + gtxTxN : out std_logic_vector(1 downto 0); -- GTX Serial Transmit Negative + gtxTxP : out std_logic_vector(1 downto 0); -- GTX Serial Transmit Positive + debug : out std_logic_vector(127 downto 0) + ); + end component; + + -- PGP Clock Generator + component Pgp2GtxClk + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + pgpRefClk : in std_logic; + ponResetL : in std_logic; + locReset : in std_logic; + pgpClk : out std_logic; + pgpReset : out std_logic; + userClk : out std_logic; + userReset : out std_logic; + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + end component; + + -- RX Reset Control + component Pgp2GtxRxRst + port ( + gtxRxClk : in std_logic; + gtxRxRst : in std_logic; + gtxRxReady : out std_logic; + gtxRxInit : in std_logic; + gtxLockDetect : in std_logic; + gtxRxBuffStatus : in std_logic_vector(2 downto 0); + gtxRxElecIdle : in std_logic; + gtxRstDone : in std_logic; + gtxRxReset : out std_logic; + gtxRxCdrReset : out std_logic + ); + end component; + + -- TX Reset Control + component Pgp2GtxTxRst + port ( + gtxTxClk : in std_logic; + gtxTxRst : in std_logic; + gtxTxReady : out std_logic; + gtxLockDetect : in std_logic; + gtxTxBuffStatus : in std_logic_vector(1 downto 0); + gtxRstDone : in std_logic; + gtxTxReset : out std_logic + ); + end component; + +end Pgp2GtxPackage; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxRxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxRxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..b80943fb5a8dbfd48f378592c33991e5ac0ef9ea --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxRxRst.vhd @@ -0,0 +1,198 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTX RX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtxRxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the RX GTX. +------------------------------------------------------------------------------- +-- Copyright (c) 2009 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +-- 01/13/2010: Added received init line to help linking. +-- 04/20/2010: Elec idle will no longer cause general reset. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtxRxRst is + port ( + + -- Clock and reset + gtxRxClk : in std_logic; + gtxRxRst : in std_logic; + + -- RX Side is ready + gtxRxReady : out std_logic; + gtxRxInit : in std_logic; + + -- GTX Status + gtxLockDetect : in std_logic; + gtxRxBuffStatus : in std_logic_vector(2 downto 0); + gtxRxElecIdle : in std_logic; + gtxRstDone : in std_logic; + + -- Reset Control + gtxRxReset : out std_logic; + gtxRxCdrReset : out std_logic + ); + +end Pgp2GtxRxRst; + + +-- Define architecture +architecture Pgp2GtxRxRst of Pgp2GtxRxRst is + + -- Local Signals + signal intRxReset : std_logic; + signal intRxCdrReset : std_logic; + signal rxStateCnt : std_logic_vector(1 downto 0); + signal rxStateCntRst : std_logic; + signal rxClockReady : std_logic; + + -- RX Reset State Machine + constant RX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant RX_WAIT_LOCK : std_logic_vector(2 downto 0) := "001"; + constant RX_RESET : std_logic_vector(2 downto 0) := "010"; + constant RX_WAIT_DONE : std_logic_vector(2 downto 0) := "011"; + constant RX_READY : std_logic_vector(2 downto 0) := "100"; + signal curRxState : std_logic_vector(2 downto 0); + signal nxtRxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- RX State Machine Synchronous Logic + process ( gtxRxClk, gtxRxRst ) begin + if gtxRxRst = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + rxStateCnt <= (others=>'0') after tpd; + gtxRxReady <= '0' after tpd; + gtxRxReset <= '1' after tpd; + gtxRxCdrReset <= '1' after tpd; + elsif rising_edge(gtxRxClk) then + + -- Drive PIB Lock + gtxRxReady <= rxClockReady after tpd; + + -- Pass on reset signals + gtxRxReset <= intRxReset after tpd; + gtxRxCdrReset <= intRxCdrReset after tpd; + + -- Update state + if gtxRxInit = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + else + curRxState <= nxtRxState after tpd; + end if; + + -- Rx State Counter + if rxStateCntRst = '1' then + rxStateCnt <= (others=>'0') after tpd; + else + rxStateCnt <= rxStateCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Async RX State Logic + process ( curRxState, rxStateCnt, gtxLockDetect, gtxRxBuffStatus, gtxRstDone ) begin + case curRxState is + + -- System Reset State + when RX_SYSTEM_RESET => + rxStateCntRst <= '1'; + intRxReset <= '1'; + intRxCdrReset <= '1'; + rxClockReady <= '0'; + nxtRxState <= RX_WAIT_LOCK; + + -- Wait for PLL lock + when RX_WAIT_LOCK => + rxStateCntRst <= '1'; + intRxReset <= '1'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + + -- Wait for three clocks + if gtxLockDetect = '1' then + nxtRxState <= RX_RESET; + else + nxtRxState <= curRxState; + end if; + + -- RX Reset State + when RX_RESET => + intRxReset <= '1'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '0'; + + -- Wait for three clocks + if rxStateCnt = 3 then + nxtRxState <= RX_WAIT_DONE; + else + nxtRxState <= curRxState; + end if; + + -- RX Wait Reset Done + when RX_WAIT_DONE => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '1'; + + -- Wait for three clocks + if gtxRstDone = '1' then + nxtRxState <= RX_READY; + else + nxtRxState <= curRxState; + end if; + + -- RX Ready + when RX_READY => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '1'; + rxStateCntRst <= '1'; + + -- Look for unlock error + if gtxLockDetect = '0' then + nxtRxState <= RX_WAIT_LOCK; + + -- Look For Buffer Error + elsif gtxRxBuffStatus(2) = '1' then + nxtRxState <= RX_RESET; + + else + nxtRxState <= curRxState; + end if; + + -- Default + when others => + intRxReset <= '0'; + intRxCdrReset <= '0'; + rxClockReady <= '0'; + rxStateCntRst <= '1'; + nxtRxState <= RX_SYSTEM_RESET; + end case; + end process; + +end Pgp2GtxRxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxTxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxTxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..d11adca58e246bcf6689ebe25275ab13f8aba1e9 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/gtx/Pgp2GtxTxRst.vhd @@ -0,0 +1,179 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, GTX TX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2GtxTxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/18/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the TX GTX. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/18/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2GtxPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + + +entity Pgp2GtxTxRst is + port ( + + -- Clock and reset + gtxTxClk : in std_logic; + gtxTxRst : in std_logic; + + -- TX Side is ready + gtxTxReady : out std_logic; + + -- GTX Status + gtxLockDetect : in std_logic; + gtxTxBuffStatus : in std_logic_vector(1 downto 0); + gtxRstDone : in std_logic; + + -- Reset Control + gtxTxReset : out std_logic + ); + +end Pgp2GtxTxRst; + + +-- Define architecture +architecture Pgp2GtxTxRst of Pgp2GtxTxRst is + + -- Local Signals + signal intTxReset : std_logic; + signal txStateCnt : std_logic_vector(1 downto 0); + signal txStateCntRst : std_logic; + signal txClockReady : std_logic; + + -- TX Reset State Machine + constant TX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant TX_WAIT_LOCK : std_logic_vector(2 downto 0) := "001"; + constant TX_RESET : std_logic_vector(2 downto 0) := "010"; + constant TX_WAIT_DONE : std_logic_vector(2 downto 0) := "011"; + constant TX_READY : std_logic_vector(2 downto 0) := "100"; + signal curTxState : std_logic_vector(2 downto 0); + signal nxtTxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + + -- TX State Machine Synchronous Logic + process ( gtxTxClk, gtxTxRst ) begin + if gtxTxRst = '1' then + curTxState <= TX_SYSTEM_RESET after tpd; + txStateCnt <= (others=>'0') after tpd; + gtxTxReset <= '1' after tpd; + gtxTxReady <= '0' after tpd; + elsif rising_edge(gtxTxClk) then + + -- RX Is Ready + gtxTxReady <= txClockReady after tpd; + + -- Pass on reset signals + gtxTxReset <= intTxReset after tpd; + + -- Update state + curTxState <= nxtTxState after tpd; + + -- Tx State Counter + if txStateCntRst = '1' then + txStateCnt <= (others=>'0') after tpd; + else + txStateCnt <= txStateCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Async TX State Logic + process ( curTxState, txStateCnt, gtxLockDetect, gtxTxBuffStatus, gtxRstDone ) begin + case curTxState is + + -- System Reset State + when TX_SYSTEM_RESET => + txStateCntRst <= '1'; + intTxReset <= '1'; + txClockReady <= '0'; + nxtTxState <= TX_WAIT_LOCK; + + -- Wait for PLL lock + when TX_WAIT_LOCK => + txStateCntRst <= '1'; + intTxReset <= '1'; + txClockReady <= '0'; + + -- Wait for three clocks + if gtxLockDetect = '1' then + nxtTxState <= TX_RESET; + else + nxtTxState <= curTxState; + end if; + + -- TX Reset State + when TX_RESET => + intTxReset <= '1'; + txClockReady <= '0'; + txStateCntRst <= '0'; + + -- Wait for three clocks + if txStateCnt = 3 then + nxtTxState <= TX_WAIT_DONE; + else + nxtTxState <= curTxState; + end if; + + -- TX Wait Reset Done + when TX_WAIT_DONE => + intTxReset <= '0'; + txClockReady <= '0'; + txStateCntRst <= '1'; + + -- Wait for three clocks + if gtxRstDone = '1' then + nxtTxState <= TX_READY; + else + nxtTxState <= curTxState; + end if; + + -- TX Ready + when TX_READY => + intTxReset <= '0'; + txClockReady <= '1'; + txStateCntRst <= '1'; + + -- Look for unlock error + if gtxLockDetect = '0' then + nxtTxState <= TX_WAIT_LOCK; + + -- Look For Buffer Error + elsif gtxTxBuffStatus(1) = '1' then + nxtTxState <= TX_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Default + when others => + intTxReset <= '0'; + txClockReady <= '0'; + txStateCntRst <= '1'; + nxtTxState <= TX_SYSTEM_RESET; + end case; + end process; + +end Pgp2GtxTxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt16.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt16.vhd new file mode 100755 index 0000000000000000000000000000000000000000..79091f4f8c1d48873e9b356080df1b7087591184 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt16.vhd @@ -0,0 +1,782 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, MGT Wrapper +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Mgt16.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/27/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, MGT and CRC blocks. +-- This module supports a standard PGP implementation where a single MGT +-- supports a bi-directional link. Both links operated at the same speed. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/27/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2Mgt16 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + MgtMode : string := "A"; -- Default Location + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- Frame state sync + pgpFlush : in std_logic; -- Frame state sync + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- MGT loopback control + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + + -- MGT Signals, Drive Ref Clock Which Matches RefClkSel Generic Above + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic; -- MGT Serial Receive Negative + mgtRxP : in std_logic; -- MGT Serial Receive Positive + mgtTxN : out std_logic; -- MGT Serial Transmit Negative + mgtTxP : out std_logic; -- MGT Serial Transmit Positive + + -- MGT Signals For Simulation, + -- Drive mgtCombusIn to 0's, Leave mgtCombusOut open for real use + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0); + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Mgt16; + + +-- Define architecture +architecture Pgp2Mgt16 of Pgp2Mgt16 is + + -- Local Signals + signal crcTxIn : std_logic_vector(15 downto 0); + signal crcTxInMgt : std_logic_vector(63 downto 0); + signal crcTxInit : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(15 downto 0); + signal crcRxInMgt : std_logic_vector(63 downto 0); + signal crcRxInit : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(0 downto 0); + signal phyRxData : std_logic_vector(15 downto 0); + signal phyRxDataK : std_logic_vector(1 downto 0); + signal phyTxData : std_logic_vector(15 downto 0); + signal phyTxDataK : std_logic_vector(1 downto 0); + signal mgtRxPmaReset : std_logic; + signal mgtTxPmaReset : std_logic; + signal mgtRxReset : std_logic; + signal mgtTxReset : std_logic; + signal mgtRxBuffError : std_logic; + signal mgtTxBuffError : std_logic; + signal phyRxDispErr : std_logic_vector(1 downto 0); + signal phyRxDecErr : std_logic_vector(1 downto 0); + signal mgtRxLock : std_logic; + signal mgtTxLock : std_logic; + signal crcRxReset : std_logic; + signal crcTxReset : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Adapt CRC data width flag + crcTxWidth <= "001"; + crcRxWidth <= "001"; + crcRxReset <= mgtRxReset; + crcTxReset <= mgtTxReset; + + -- Pass CRC data in on proper bits + crcTxInMgt(63 downto 56) <= crcTxIn(7 downto 0); + crcTxInMgt(55 downto 48) <= crcTxIn(15 downto 8); + crcTxInMgt(47 downto 0) <= (others=>'0'); + crcRxInMgt(63 downto 56) <= crcRxIn(7 downto 0); + crcRxInMgt(55 downto 48) <= crcRxIn(15 downto 8); + crcRxInMgt(47 downto 0) <= (others=>'0'); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + + -- PGP Receive Core + U_Pgp2Rx: Pgp2Rx + generic map ( + RxLaneCnt => 1, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP Transmit Core + U_Pgp2Tx: Pgp2Tx + generic map ( + TxLaneCnt => 1, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- MGT Receive Reset + U_Pgp2MgtRxRst: Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => phyRxReady, + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock, + mgtRxPmaReset => mgtRxPmaReset, + mgtRxReset => mgtRxReset, + mgtRxBuffError => mgtRxBuffError + ); + + + -- MGT Transmit Reset + U_Pgp2MgtTxRst: Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => phyTxReady, + mgtTxLock => mgtTxLock, + mgtTxPmaReset => mgtTxPmaReset, + mgtTxReset => mgtTxReset, + mgtTxBuffError => mgtTxBuffError + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGT : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "NONE", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00000000000", + CHAN_BOND_SEQ_1_2 => "00000000000", + CHAN_BOND_SEQ_1_3 => "00000000000", + CHAN_BOND_SEQ_1_4 => "00000000000", + CHAN_BOND_SEQ_1_MASK => "1110", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 1, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => MgtMode, + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => crcRxValid, + RXCRCDATAWIDTH => crcRxWidth, + RXCRCIN => crcRxInMgt, + RXCRCINIT => crcRxInit, + RXCRCINTCLK => pgpClk, + RXCRCOUT => crcRxOut, + RXCRCPD => '0', + RXCRCRESET => crcRxReset, + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => crcTxValid, + TXCRCDATAWIDTH => crcTxWidth, + TXCRCIN => crcTxInMgt, + TXCRCINIT => crcTxInit, + TXCRCINTCLK => pgpClk, + TXCRCOUT => crcTxOut, + TXCRCPD => '0', + TXCRCRESET => crcTxReset, + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN, + RX1P => mgtRxP, + TX1N => mgtTxN, + TX1P => mgtTxP, + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock, + TXLOCK => mgtTxLock, + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset, + RXRESET => mgtRxReset, + TXPMARESET => mgtTxPmaReset, + TXRESET => mgtTxReset, + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError, + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError, + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(0), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => (others=>'0'), + CHBONDO => open, + ENCHANSYNC => '0', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => "000000", + TXBYPASS8B10B(1 downto 0) => "00", + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => x"00", + TXCHARDISPVAL(7 downto 0) => x"00", + TXCHARISK(7 downto 2) => "000000", + TXCHARISK(1 downto 0) => phyTxDataK, + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK, + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr, + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr, + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData, + TXDATA(63 downto 16) => x"000000000000", + TXDATA(15 downto 0) => phyTxData, + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => mgtRxRecClk, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusIn, + COMBUSOUT => mgtCombusOut + ); + +end Pgp2Mgt16; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt32.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt32.vhd new file mode 100755 index 0000000000000000000000000000000000000000..b5737e7a5c5f563fe141ec92ce9fc0ad05296e66 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt32.vhd @@ -0,0 +1,1227 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, MGT Wrapper, 32-bit +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Mgt3232.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/21/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, MGT and CRC blocks. 32-bit version. +-- This module supports a standard PGP implementation where a single MGT +-- supports a bi-directional link. Both links operated at the same speed. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/21/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2Mgt32 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- Frame state sync + pgpFlush : in std_logic; -- Frame state sync + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(31 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- MGT loopback control + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + + -- MGT Signals, Drive Ref Clock Which Matches RefClkSel Generic Above + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic_vector(1 downto 0); -- MGT Serial Receive Negative + mgtRxP : in std_logic_vector(1 downto 0); -- MGT Serial Receive Positive + mgtTxN : out std_logic_vector(1 downto 0); -- MGT Serial Transmit Negative + mgtTxP : out std_logic_vector(1 downto 0); -- MGT Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Mgt32; + + +-- Define architecture +architecture Pgp2Mgt32 of Pgp2Mgt32 is + + -- Local Signals + signal crcTxIn : std_logic_vector(31 downto 0); + signal crcTxInMgt : std_logic_vector(63 downto 0); + signal crcTxInit : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(31 downto 0); + signal crcRxInMgt : std_logic_vector(63 downto 0); + signal crcRxInit : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxOut : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(1 downto 0); + signal phyRxData : std_logic_vector(31 downto 0); + signal phyRxDataK : std_logic_vector(3 downto 0); + signal phyTxData : std_logic_vector(31 downto 0); + signal phyTxDataK : std_logic_vector(3 downto 0); + signal mgtRxPmaReset : std_logic_vector(1 downto 0); + signal mgtTxPmaReset : std_logic_vector(1 downto 0); + signal mgtRxReset : std_logic_vector(1 downto 0); + signal mgtTxReset : std_logic_vector(1 downto 0); + signal mgtRxBuffError : std_logic_vector(1 downto 0); + signal mgtTxBuffError : std_logic_vector(1 downto 0); + signal phyRxDispErr : std_logic_vector(3 downto 0); + signal phyRxDecErr : std_logic_vector(3 downto 0); + signal mgtRxLock : std_logic_vector(1 downto 0); + signal mgtTxLock : std_logic_vector(1 downto 0); + signal crcRxReset : std_logic; + signal crcTxReset : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal intRxReady : std_logic_vector(1 downto 0); + signal intTxReady : std_logic_vector(1 downto 0); + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal mgtCombusOutA : std_logic_vector(15 downto 0); + signal mgtCombusInA : std_logic_vector(15 downto 0); + signal mgtChanBond : std_logic_vector(4 downto 0); + signal mgtStatusA : std_logic_vector(5 downto 0); + signal mgtStatusB : std_logic_vector(5 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Adapt CRC data width flag + crcTxWidth <= "011"; + crcRxWidth <= "011"; + crcRxReset <= mgtRxReset(0); + crcTxReset <= mgtTxReset(0); + + -- Pass CRC data in on proper bits + crcTxInMgt(63 downto 56) <= crcTxIn(7 downto 0); + crcTxInMgt(55 downto 48) <= crcTxIn(15 downto 8); + crcTxInMgt(47 downto 40) <= crcTxIn(23 downto 16); + crcTxInMgt(39 downto 32) <= crcTxIn(31 downto 24); + crcTxInMgt(31 downto 0) <= (others=>'0'); + crcRxInMgt(63 downto 56) <= crcRxIn(7 downto 0); + crcRxInMgt(55 downto 48) <= crcRxIn(15 downto 8); + crcRxInMgt(47 downto 40) <= crcRxIn(23 downto 16); + crcRxInMgt(39 downto 32) <= crcRxIn(31 downto 24); + crcRxInMgt(31 downto 0) <= (others=>'0'); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + phyRxReady <= '1' when intRxReady = "11" else '0'; + phyTxReady <= '1' when intTxReady = "11" else '0'; + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + + -- PGP Receive Core + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 2, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => open, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP Transmit Core + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 2, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- MGTA Receive Reset + U_Pgp2MgtRxRstA: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(0), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(0), + mgtRxPmaReset => mgtRxPmaReset(0), + mgtRxReset => mgtRxReset(0), + mgtRxBuffError => mgtRxBuffError(0) + ); + + + -- MGTB Receive Reset + U_Pgp2MgtRxRstB: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(1), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(1), + mgtRxPmaReset => mgtRxPmaReset(1), + mgtRxReset => mgtRxReset(1), + mgtRxBuffError => mgtRxBuffError(1) + ); + + + -- MGTA Transmit Reset + U_Pgp2MgtTxRstA: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(0), + mgtTxLock => mgtTxLock(0), + mgtTxPmaReset => mgtTxPmaReset(0), + mgtTxReset => mgtTxReset(0), + mgtTxBuffError => mgtTxBuffError(0) + ); + + + -- MGTB Transmit Reset + U_Pgp2MgtTxRstB: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(1), + mgtTxLock => mgtTxLock(1), + mgtTxPmaReset => mgtTxPmaReset(1), + mgtTxReset => mgtTxReset(1), + mgtTxBuffError => mgtTxBuffError(1) + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTA : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "MASTER", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "A", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => crcRxValid, + RXCRCDATAWIDTH => crcRxWidth, + RXCRCIN => crcRxInMgt, + RXCRCINIT => crcRxInit, + RXCRCINTCLK => pgpClk, + RXCRCOUT => crcRxOut, + RXCRCPD => '0', + RXCRCRESET => crcRxReset, + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => crcTxValid, + TXCRCDATAWIDTH => crcTxWidth, + TXCRCIN => crcTxInMgt, + TXCRCINIT => crcTxInit, + TXCRCINTCLK => pgpClk, + TXCRCOUT => crcTxOut, + TXCRCPD => '0', + TXCRCRESET => crcTxReset, + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(0), + RX1P => mgtRxP(0), + TX1N => mgtTxN(0), + TX1P => mgtTxP(0), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(0), + TXLOCK => mgtTxLock(0), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(0), + RXRESET => mgtRxReset(0), + TXPMARESET => mgtTxPmaReset(0), + TXRESET => mgtTxReset(0), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(0), + RXCLKSTABLE => '1', + RXSTATUS => mgtStatusA, + TXBUFERR => mgtTxBuffError(0), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(0), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => (others=>'0'), + CHBONDO => mgtChanBond, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(1 downto 0), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(1 downto 0), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(1 downto 0), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(1 downto 0), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(15 downto 0), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(15 downto 0), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => mgtRxRecClk, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusInA, + COMBUSOUT => mgtCombusOutA + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTB : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "SLAVE_1_HOP", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "B", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => '0', + RXCRCDATAWIDTH => (others=>'0'), + RXCRCIN => (others=>'0'), + RXCRCINIT => '0', + RXCRCINTCLK => pgpClk, + RXCRCOUT => open, + RXCRCPD => '0', + RXCRCRESET => '0', + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => '0', + TXCRCDATAWIDTH => (others=>'0'), + TXCRCIN => (others=>'0'), + TXCRCINIT => '0', + TXCRCINTCLK => pgpClk, + TXCRCOUT => open, + TXCRCPD => '0', + TXCRCRESET => '0', + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(1), + RX1P => mgtRxP(1), + TX1N => mgtTxN(1), + TX1P => mgtTxP(1), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(1), + TXLOCK => mgtTxLock(1), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(1), + RXRESET => mgtRxReset(1), + TXPMARESET => mgtTxPmaReset(1), + TXRESET => mgtTxReset(1), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(1), + RXCLKSTABLE => '1', + RXSTATUS => mgtStatusB, + TXBUFERR => mgtTxBuffError(1), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(1), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => mgtChanBond, + CHBONDO => open, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(3 downto 2), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(3 downto 2), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(3 downto 2), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(3 downto 2), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(31 downto 16), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(31 downto 16), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => open, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusOutA, + COMBUSOUT => mgtCombusInA + ); + +end Pgp2Mgt32; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt64.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt64.vhd new file mode 100755 index 0000000000000000000000000000000000000000..7611e3a0d0cddd5e549b87b1486d9ebeed4b38cd --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2Mgt64.vhd @@ -0,0 +1,2114 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, MGT Wrapper, 64-bit +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Mgt64.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 08/21/2009 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file containing the PGP, MGT and CRC blocks. 64-bit version. +-- This module supports a standard PGP implementation where a single MGT +-- supports a bi-directional link. Both links operated at the same speed. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 08/21/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +use work.Pgp2CorePackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2Mgt64 is + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + + -- System clock, reset & control + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + + -- Frame state flush + pgpFlush : in std_logic; -- Frame state sync + + -- PLL Reset Control + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + + -- PLL Lock Status + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + + -- Sideband data + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + + -- Opcode Transmit Interface + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + + -- Opcode Receive Interface + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + + -- Link status + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + + -- Error Flags, one pulse per event + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + + -- Frame Transmit Interface, VC 0 + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 1 + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 2 + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + + -- Frame Transmit Interface, VC 3 + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + + -- Common Frame Receive Interface For All VCs + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(63 downto 0); -- PGP frame data + + -- Frame Receive Interface, VC 0 + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 1 + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 2 + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + + -- Frame Receive Interface, VC 3 + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + + -- MGT loopback control + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + + -- MGT Signals, Drive Ref Clock Which Matches RefClkSel Generic Above + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic_vector(3 downto 0); -- MGT Serial Receive Negative + mgtRxP : in std_logic_vector(3 downto 0); -- MGT Serial Receive Positive + mgtTxN : out std_logic_vector(3 downto 0); -- MGT Serial Transmit Negative + mgtTxP : out std_logic_vector(3 downto 0); -- MGT Serial Transmit Positive + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); + +end Pgp2Mgt64; + + +-- Define architecture +architecture Pgp2Mgt64 of Pgp2Mgt64 is + + -- Local Signals + signal crcTxIn : std_logic_vector(63 downto 0); + signal crcTxInMgt : std_logic_vector(63 downto 0); + signal crcTxInit : std_logic; + signal crcTxValid : std_logic; + signal crcTxWidth : std_logic_vector(2 downto 0); + signal crcTxOut : std_logic_vector(31 downto 0); + signal crcRxIn : std_logic_vector(63 downto 0); + signal crcRxInMgt : std_logic_vector(63 downto 0); + signal crcRxInit : std_logic; + signal crcRxValid : std_logic; + signal crcRxWidth : std_logic_vector(2 downto 0); + signal crcRxWidthIn : std_logic; + signal crcRxOut : std_logic_vector(31 downto 0); + signal phyRxPolarity : std_logic_vector(3 downto 0); + signal phyRxData : std_logic_vector(63 downto 0); + signal phyRxDataK : std_logic_vector(7 downto 0); + signal phyTxData : std_logic_vector(63 downto 0); + signal phyTxDataK : std_logic_vector(7 downto 0); + signal mgtRxPmaReset : std_logic_vector(3 downto 0); + signal mgtTxPmaReset : std_logic_vector(3 downto 0); + signal mgtRxReset : std_logic_vector(3 downto 0); + signal mgtTxReset : std_logic_vector(3 downto 0); + signal mgtRxBuffError : std_logic_vector(3 downto 0); + signal mgtTxBuffError : std_logic_vector(3 downto 0); + signal phyRxDispErr : std_logic_vector(7 downto 0); + signal phyRxDecErr : std_logic_vector(7 downto 0); + signal mgtRxLock : std_logic_vector(3 downto 0); + signal mgtTxLock : std_logic_vector(3 downto 0); + signal crcRxReset : std_logic; + signal crcTxReset : std_logic; + signal intTxRst : std_logic; + signal intRxRst : std_logic; + signal phyRxReady : std_logic; + signal phyRxInit : std_logic; + signal phyTxReady : std_logic; + signal intRxReady : std_logic_vector(3 downto 0); + signal intTxReady : std_logic_vector(3 downto 0); + signal pgpRxLinkReady : std_logic; + signal pgpTxLinkReady : std_logic; + signal mgtCombusOutA : std_logic_vector(15 downto 0); + signal mgtCombusInA : std_logic_vector(15 downto 0); + signal mgtCombusOutC : std_logic_vector(15 downto 0); + signal mgtCombusInC : std_logic_vector(15 downto 0); + signal mgtChanBond : std_logic_vector(4 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Adapt CRC data width flag + crcTxWidth <= "111"; + crcRxWidth <= crcRxWidthIn & "11"; + crcRxReset <= mgtRxReset(0); + crcTxReset <= mgtTxReset(0); + + -- Pass CRC data in on proper bits + crcTxInMgt(63 downto 56) <= crcTxIn(7 downto 0); + crcTxInMgt(55 downto 48) <= crcTxIn(15 downto 8); + crcTxInMgt(47 downto 40) <= crcTxIn(23 downto 16); + crcTxInMgt(39 downto 32) <= crcTxIn(31 downto 24); + crcTxInMgt(31 downto 24) <= crcTxIn(39 downto 32); + crcTxInMgt(23 downto 16) <= crcTxIn(47 downto 40); + crcTxInMgt(15 downto 8) <= crcTxIn(55 downto 48); + crcTxInMgt(7 downto 0) <= crcTxIn(63 downto 56); + + crcRxInMgt(63 downto 56) <= crcRxIn(7 downto 0); + crcRxInMgt(55 downto 48) <= crcRxIn(15 downto 8); + crcRxInMgt(47 downto 40) <= crcRxIn(23 downto 16); + crcRxInMgt(39 downto 32) <= crcRxIn(31 downto 24); + crcRxInMgt(31 downto 24) <= crcRxIn(39 downto 32); + crcRxInMgt(23 downto 16) <= crcRxIn(47 downto 40); + crcRxInMgt(15 downto 8) <= crcRxIn(55 downto 48); + crcRxInMgt(7 downto 0) <= crcRxIn(63 downto 56); + + -- Pll Resets + intTxRst <= pllTxRst or pgpReset; + intRxRst <= pllRxRst or pgpReset; + + -- PLL Lock + phyRxReady <= '1' when intRxReady = "1111" else '0'; + phyTxReady <= '1' when intTxReady = "1111" else '0'; + pllRxReady <= phyRxReady; + pllTxReady <= phyTxReady; + + -- Link Ready + pgpLocLinkReady <= pgpRxLinkReady and pgpTxLinkReady; + + + -- PGP Receive Core + U_Pgp2Rx: Pgp2CorePackage.Pgp2Rx + generic map ( + RxLaneCnt => 4, + EnShortCells => EnShortCells + ) port map ( + pgpRxClk => pgpClk, + pgpRxReset => pgpReset, + pgpRxFlush => pgpFlush, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkReady => pgpRxLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + pgpRxOpCodeEn => pgpRxOpCodeEn, + pgpRxOpCode => pgpRxOpCode, + pgpRemLinkReady => pgpRemLinkReady, + pgpRemData => pgpRemData, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxData => vcFrameRxData, + vc0FrameRxValid => vc0FrameRxValid, + vc0RemBuffAFull => vc0RemBuffAFull, + vc0RemBuffFull => vc0RemBuffFull, + vc1FrameRxValid => vc1FrameRxValid, + vc1RemBuffAFull => vc1RemBuffAFull, + vc1RemBuffFull => vc1RemBuffFull, + vc2FrameRxValid => vc2FrameRxValid, + vc2RemBuffAFull => vc2RemBuffAFull, + vc2RemBuffFull => vc2RemBuffFull, + vc3FrameRxValid => vc3FrameRxValid, + vc3RemBuffAFull => vc3RemBuffAFull, + vc3RemBuffFull => vc3RemBuffFull, + phyRxPolarity => phyRxPolarity, + phyRxData => phyRxData, + phyRxDataK => phyRxDataK, + phyRxDispErr => phyRxDispErr, + phyRxDecErr => phyRxDecErr, + phyRxReady => phyRxReady, + phyRxInit => phyRxInit, + crcRxIn => crcRxIn, + crcRxWidth => crcRxWidthIn, + crcRxInit => crcRxInit, + crcRxValid => crcRxValid, + crcRxOut => crcRxOut, + debug => debug + ); + + + -- PGP Transmit Core + U_Pgp2Tx: Pgp2CorePackage.Pgp2Tx + generic map ( + TxLaneCnt => 4, + VcInterleave => VcInterleave + ) port map ( + pgpTxClk => pgpClk, + pgpTxReset => pgpReset, + pgpTxFlush => pgpFlush, + pgpTxLinkReady => pgpTxLinkReady, + pgpTxOpCodeEn => pgpTxOpCodeEn, + pgpTxOpCode => pgpTxOpCode, + pgpLocLinkReady => pgpRxLinkReady, + pgpLocData => pgpLocData, + vc0FrameTxValid => vc0FrameTxValid, + vc0FrameTxReady => vc0FrameTxReady, + vc0FrameTxSOF => vc0FrameTxSOF, + vc0FrameTxEOF => vc0FrameTxEOF, + vc0FrameTxEOFE => vc0FrameTxEOFE, + vc0FrameTxData => vc0FrameTxData, + vc0LocBuffAFull => vc0LocBuffAFull, + vc0LocBuffFull => vc0LocBuffFull, + vc1FrameTxValid => vc1FrameTxValid, + vc1FrameTxReady => vc1FrameTxReady, + vc1FrameTxSOF => vc1FrameTxSOF, + vc1FrameTxEOF => vc1FrameTxEOF, + vc1FrameTxEOFE => vc1FrameTxEOFE, + vc1FrameTxData => vc1FrameTxData, + vc1LocBuffAFull => vc1LocBuffAFull, + vc1LocBuffFull => vc1LocBuffFull, + vc2FrameTxValid => vc2FrameTxValid, + vc2FrameTxReady => vc2FrameTxReady, + vc2FrameTxSOF => vc2FrameTxSOF, + vc2FrameTxEOF => vc2FrameTxEOF, + vc2FrameTxEOFE => vc2FrameTxEOFE, + vc2FrameTxData => vc2FrameTxData, + vc2LocBuffAFull => vc2LocBuffAFull, + vc2LocBuffFull => vc2LocBuffFull, + vc3FrameTxValid => vc3FrameTxValid, + vc3FrameTxReady => vc3FrameTxReady, + vc3FrameTxSOF => vc3FrameTxSOF, + vc3FrameTxEOF => vc3FrameTxEOF, + vc3FrameTxEOFE => vc3FrameTxEOFE, + vc3FrameTxData => vc3FrameTxData, + vc3LocBuffAFull => vc3LocBuffAFull, + vc3LocBuffFull => vc3LocBuffFull, + phyTxData => phyTxData, + phyTxDataK => phyTxDataK, + phyTxReady => phyTxReady, + crcTxIn => crcTxIn, + crcTxInit => crcTxInit, + crcTxValid => crcTxValid, + crcTxOut => crcTxOut, + debug => open + ); + + + -- MGTA Receive Reset + U_Pgp2MgtRxRstA: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(0), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(0), + mgtRxPmaReset => mgtRxPmaReset(0), + mgtRxReset => mgtRxReset(0), + mgtRxBuffError => mgtRxBuffError(0) + ); + + + -- MGTB Receive Reset + U_Pgp2MgtRxRstB: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(1), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(1), + mgtRxPmaReset => mgtRxPmaReset(1), + mgtRxReset => mgtRxReset(1), + mgtRxBuffError => mgtRxBuffError(1) + ); + + + -- MGTC Receive Reset + U_Pgp2MgtRxRstC: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(2), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(2), + mgtRxPmaReset => mgtRxPmaReset(2), + mgtRxReset => mgtRxReset(2), + mgtRxBuffError => mgtRxBuffError(2) + ); + + + -- MGTD Receive Reset + U_Pgp2MgtRxRstD: Pgp2MgtPackage.Pgp2MgtRxRst port map ( + mgtRxClk => pgpClk, + mgtRxRst => intRxRst, + mgtRxReady => intRxReady(3), + mgtRxInit => phyRxInit, + mgtRxLock => mgtRxLock(3), + mgtRxPmaReset => mgtRxPmaReset(3), + mgtRxReset => mgtRxReset(3), + mgtRxBuffError => mgtRxBuffError(3) + ); + + + -- MGTA Transmit Reset + U_Pgp2MgtTxRstA: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(0), + mgtTxLock => mgtTxLock(0), + mgtTxPmaReset => mgtTxPmaReset(0), + mgtTxReset => mgtTxReset(0), + mgtTxBuffError => mgtTxBuffError(0) + ); + + + -- MGTB Transmit Reset + U_Pgp2MgtTxRstB: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(1), + mgtTxLock => mgtTxLock(1), + mgtTxPmaReset => mgtTxPmaReset(1), + mgtTxReset => mgtTxReset(1), + mgtTxBuffError => mgtTxBuffError(1) + ); + + + -- MGTC Transmit Reset + U_Pgp2MgtTxRstC: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(2), + mgtTxLock => mgtTxLock(2), + mgtTxPmaReset => mgtTxPmaReset(2), + mgtTxReset => mgtTxReset(2), + mgtTxBuffError => mgtTxBuffError(2) + ); + + + -- MGTD Transmit Reset + U_Pgp2MgtTxRstD: Pgp2MgtPackage.Pgp2MgtTxRst port map ( + mgtTxClk => pgpClk, + mgtTxRst => intTxRst, + mgtTxReady => intTxReady(3), + mgtTxLock => mgtTxLock(3), + mgtTxPmaReset => mgtTxPmaReset(3), + mgtTxReset => mgtTxReset(3), + mgtTxBuffError => mgtTxBuffError(3) + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTA : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "MASTER", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "A", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => crcRxValid, + RXCRCDATAWIDTH => crcRxWidth, + RXCRCIN => crcRxInMgt, + RXCRCINIT => crcRxInit, + RXCRCINTCLK => pgpClk, + RXCRCOUT => crcRxOut, + RXCRCPD => '0', + RXCRCRESET => crcRxReset, + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => crcTxValid, + TXCRCDATAWIDTH => crcTxWidth, + TXCRCIN => crcTxInMgt, + TXCRCINIT => crcTxInit, + TXCRCINTCLK => pgpClk, + TXCRCOUT => crcTxOut, + TXCRCPD => '0', + TXCRCRESET => crcTxReset, + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(0), + RX1P => mgtRxP(0), + TX1N => mgtTxN(0), + TX1P => mgtTxP(0), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(0), + TXLOCK => mgtTxLock(0), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(0), + RXRESET => mgtRxReset(0), + TXPMARESET => mgtTxPmaReset(0), + TXRESET => mgtTxReset(0), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(0), + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError(0), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(0), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => (others=>'0'), + CHBONDO => mgtChanBond, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(1 downto 0), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(1 downto 0), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(1 downto 0), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(1 downto 0), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(15 downto 0), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(15 downto 0), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => mgtRxRecClk, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusInA, + COMBUSOUT => mgtCombusOutA + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTB : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "SLAVE_1_HOP", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "B", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => '0', + RXCRCDATAWIDTH => (others=>'0'), + RXCRCIN => (others=>'0'), + RXCRCINIT => '0', + RXCRCINTCLK => pgpClk, + RXCRCOUT => open, + RXCRCPD => '0', + RXCRCRESET => '0', + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => '0', + TXCRCDATAWIDTH => (others=>'0'), + TXCRCIN => (others=>'0'), + TXCRCINIT => '0', + TXCRCINTCLK => pgpClk, + TXCRCOUT => open, + TXCRCPD => '0', + TXCRCRESET => '0', + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(1), + RX1P => mgtRxP(1), + TX1N => mgtTxN(1), + TX1P => mgtTxP(1), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(1), + TXLOCK => mgtTxLock(1), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(1), + RXRESET => mgtRxReset(1), + TXPMARESET => mgtTxPmaReset(1), + TXRESET => mgtTxReset(1), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(1), + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError(1), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(1), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => mgtChanBond, + CHBONDO => open, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(3 downto 2), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(3 downto 2), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(3 downto 2), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(3 downto 2), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(31 downto 16), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(31 downto 16), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => open, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusOutA, + COMBUSOUT => mgtCombusInA + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTC : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "SLAVE_1_HOP", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "A", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => '0', + RXCRCDATAWIDTH => (others=>'0'), + RXCRCIN => (others=>'0'), + RXCRCINIT => '0', + RXCRCINTCLK => pgpClk, + RXCRCOUT => open, + RXCRCPD => '0', + RXCRCRESET => '0', + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => '0', + TXCRCDATAWIDTH => (others=>'0'), + TXCRCIN => (others=>'0'), + TXCRCINIT => '0', + TXCRCINTCLK => pgpClk, + TXCRCOUT => open, + TXCRCPD => '0', + TXCRCRESET => '0', + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(2), + RX1P => mgtRxP(2), + TX1N => mgtTxN(2), + TX1P => mgtTxP(2), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(2), + TXLOCK => mgtTxLock(2), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(2), + RXRESET => mgtRxReset(2), + TXPMARESET => mgtTxPmaReset(2), + TXRESET => mgtTxReset(2), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(2), + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError(2), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(2), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => mgtChanBond, + CHBONDO => open, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(5 downto 4), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(5 downto 4), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(5 downto 4), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(5 downto 4), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(47 downto 32), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(47 downto 32), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => open, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusInC, + COMBUSOUT => mgtCombusOutC + ); + + + --------------------------- GT11 Instantiations --------------------------- + U_MGTD : GT11 + generic map + ( + + ---------- RocketIO MGT 64B66B Block Sync State Machine Attributes --------- + + SH_CNT_MAX => 64, + SH_INVALID_CNT_MAX => 16, + + ----------------------- RocketIO MGT Alignment Atrributes ------------------ + + ALIGN_COMMA_WORD => 2, + COMMA_10B_MASK => x"3ff", + COMMA32 => FALSE, + DEC_MCOMMA_DETECT => FALSE, + DEC_PCOMMA_DETECT => FALSE, + DEC_VALID_COMMA_ONLY => FALSE, + MCOMMA_32B_VALUE => x"00000283", + MCOMMA_DETECT => TRUE, + PCOMMA_32B_VALUE => x"0000017c", + PCOMMA_DETECT => TRUE, + PCS_BIT_SLIP => FALSE, + + ---- RocketIO MGT Atrributes Common to Clk Correction & Channel Bonding ---- + + CCCB_ARBITRATOR_DISABLE => FALSE, + CLK_COR_8B10B_DE => TRUE, + + ------------------- RocketIO MGT Channel Bonding Atrributes ---------------- + + CHAN_BOND_LIMIT => 16, + CHAN_BOND_MODE => "SLAVE_1_HOP", + CHAN_BOND_ONE_SHOT => FALSE, + CHAN_BOND_SEQ_1_1 => "00110111100", + CHAN_BOND_SEQ_1_2 => "00111011100", + CHAN_BOND_SEQ_1_3 => "00111011100", + CHAN_BOND_SEQ_1_4 => "00111011100", + CHAN_BOND_SEQ_1_MASK => "0000", + CHAN_BOND_SEQ_2_1 => "00000000000", + CHAN_BOND_SEQ_2_2 => "00000000000", + CHAN_BOND_SEQ_2_3 => "00000000000", + CHAN_BOND_SEQ_2_4 => "00000000000", + CHAN_BOND_SEQ_2_MASK => "1111", + CHAN_BOND_SEQ_2_USE => FALSE, + CHAN_BOND_SEQ_LEN => 4, + + ------------------ RocketIO MGT Clock Correction Atrributes ---------------- + + CLK_COR_MAX_LAT => 48, + CLK_COR_MIN_LAT => 36, + CLK_COR_SEQ_1_1 => "00110111100", + CLK_COR_SEQ_1_2 => "00100011100", + CLK_COR_SEQ_1_3 => "00100011100", + CLK_COR_SEQ_1_4 => "00100011100", + CLK_COR_SEQ_1_MASK => "0000", + CLK_COR_SEQ_2_1 => "00000000000", + CLK_COR_SEQ_2_2 => "00000000000", + CLK_COR_SEQ_2_3 => "00000000000", + CLK_COR_SEQ_2_4 => "00000000000", + CLK_COR_SEQ_2_MASK => "1111", + CLK_COR_SEQ_2_USE => FALSE, + CLK_COR_SEQ_DROP => FALSE, + CLK_COR_SEQ_LEN => 4, + CLK_CORRECT_USE => TRUE, + + ---------------------- RocketIO MGT Clocking Atrributes -------------------- + + RX_CLOCK_DIVIDER => "01", + RXASYNCDIVIDE => "01", + RXCLK0_FORCE_PMACLK => TRUE, + RXCLKMODE => "000011", + RXOUTDIV2SEL => 2, + RXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + RXPMACLKSEL => RefClkSel, + RXRECCLK1_USE_SYNC => FALSE, + RXUSRDIVISOR => 1, + TX_CLOCK_DIVIDER => "01", + TXABPMACLKSEL => RefClkSel, + TXASYNCDIVIDE => "01", + TXCLK0_FORCE_PMACLK => TRUE, + TXCLKMODE => "0100", + TXOUTCLK1_USE_SYNC => FALSE, + TXOUTDIV2SEL => 2, + TXPHASESEL => FALSE, + TXPLLNDIVSEL => 20, -- 8=1.25, 16=2.5, 20=3.125 + + -------------------------- RocketIO MGT CRC Atrributes --------------------- + + RXCRCCLOCKDOUBLE => FALSE, + RXCRCENABLE => TRUE, + RXCRCINITVAL => x"FFFFFFFF", + RXCRCINVERTGEN => TRUE, + RXCRCSAMECLOCK => TRUE, + TXCRCCLOCKDOUBLE => FALSE, + TXCRCENABLE => TRUE, + TXCRCINITVAL => x"FFFFFFFF", + TXCRCINVERTGEN => TRUE, + TXCRCSAMECLOCK => TRUE, + + --------------------- RocketIO MGT Data Path Atrributes -------------------- + + RXDATA_SEL => "00", + TXDATA_SEL => "00", + + ---------------- RocketIO MGT Digital Receiver Attributes ------------------ + + DIGRX_FWDCLK => "01", + DIGRX_SYNC_MODE => FALSE, + ENABLE_DCDR => FALSE, + RXBY_32 => FALSE, + RXDIGRESET => FALSE, + RXDIGRX => FALSE, + SAMPLE_8X => FALSE, + + ----------------- Rocket IO MGT Miscellaneous Attributes ------------------ + + GT11_MODE => "B", + OPPOSITE_SELECT => FALSE, + PMA_BIT_SLIP => FALSE, + REPEATER => FALSE, + RX_BUFFER_USE => TRUE, + RXCDRLOS => "000000", + RXDCCOUPLE => TRUE, + RXFDCAL_CLOCK_DIVIDE => "NONE", + TX_BUFFER_USE => TRUE, + TXFDCAL_CLOCK_DIVIDE => "NONE", + TXSLEWRATE => FALSE, + + ----------------- Rocket IO MGT Preemphasis and Equalization -------------- + + RXAFEEQ => "000000000", + RXEQ => x"4000FF0303030101", + TXDAT_PRDRV_DAC => "111", + TXDAT_TAP_DAC => "11011", -- = TXPOST_TAP_DAC * 4 + TXHIGHSIGNALEN => TRUE, + TXPOST_PRDRV_DAC => "111", + TXPOST_TAP_DAC => "00010", + TXPOST_TAP_PD => FALSE, + TXPRE_PRDRV_DAC => "111", + TXPRE_TAP_DAC => "00001", -- = TXPOST_TAP_DAC / 2 + TXPRE_TAP_PD => TRUE, + + ----------------------- Restricted RocketIO MGT Attributes ------------------- + + ---Note : THE FOLLOWING ATTRIBUTES ARE RESTRICTED. PLEASE DO NOT EDIT. + + ----------------------------- Restricted: Biasing ------------------------- + + BANDGAPSEL => FALSE, + BIASRESSEL => FALSE, + IREFBIASMODE => "11", + PMAIREFTRIM => "0111", + PMAVREFTRIM => "0111", + TXAREFBIASSEL => TRUE, + TXTERMTRIM => "1100", + VREFBIASMODE => "11", + + ---------------- Restricted: Frequency Detector and Calibration ----------- + + CYCLE_LIMIT_SEL => "00", + FDET_HYS_CAL => "010", + FDET_HYS_SEL => "100", + FDET_LCK_CAL => "101", + FDET_LCK_SEL => "001", + LOOPCAL_WAIT => "00", + RXCYCLE_LIMIT_SEL => "00", + RXFDET_HYS_CAL => "010", + RXFDET_HYS_SEL => "100", + RXFDET_LCK_CAL => "101", + RXFDET_LCK_SEL => "001", + RXLOOPCAL_WAIT => "00", + RXSLOWDOWN_CAL => "00", + SLOWDOWN_CAL => "00", + + --------------------------- Restricted: PLL Settings --------------------- + + PMACLKENABLE => TRUE, + PMACOREPWRENABLE => TRUE, + PMAVBGCTRL => "00000", + RXACTST => FALSE, + RXAFETST => FALSE, + RXCMADJ => "01", + RXCPSEL => TRUE, + RXCPTST => FALSE, + RXCTRL1 => x"200", + RXFECONTROL1 => "00", + RXFECONTROL2 => "000", + RXFETUNE => "01", + RXLKADJ => "00000", + RXLOOPFILT => "1111", + RXPDDTST => TRUE, + RXRCPADJ => "011", + RXRIBADJ => "11", + RXVCO_CTRL_ENABLE => TRUE, + RXVCODAC_INIT => "0000101001", + TXCPSEL => TRUE, + TXCTRL1 => x"200", + TXLOOPFILT => "1101", + VCO_CTRL_ENABLE => TRUE, + VCODAC_INIT => "0000101001", + + --------------------------- Restricted: Powerdowns ------------------------ + + POWER_ENABLE => TRUE, + RXAFEPD => FALSE, + RXAPD => FALSE, + RXLKAPD => FALSE, + RXPD => FALSE, + RXRCPPD => FALSE, + RXRPDPD => FALSE, + RXRSDPD => FALSE, + TXAPD => FALSE, + TXDIGPD => FALSE, + TXLVLSHFTPD => FALSE, + TXPD => FALSE, + + --------------------------- Recent Adds In Latest Software, Unknown ------- + + IN_DELAY => 0 ps, + DCDR_FILTER => "010", + RXAREGCTRL => "00000", + RXCLMODE => "00", + RXLB => FALSE, + RXMODE => "000000", + RXTUNE => X"0000", + TXCLMODE => "00", + TXTUNE => X"0000" + ) + port map + ( + ------------------------------- CRC Ports ------------------------------ + + RXCRCCLK => pgpClk, + RXCRCDATAVALID => '0', + RXCRCDATAWIDTH => (others=>'0'), + RXCRCIN => (others=>'0'), + RXCRCINIT => '0', + RXCRCINTCLK => pgpClk, + RXCRCOUT => open, + RXCRCPD => '0', + RXCRCRESET => '0', + + TXCRCCLK => pgpClk, + TXCRCDATAVALID => '0', + TXCRCDATAWIDTH => (others=>'0'), + TXCRCIN => (others=>'0'), + TXCRCINIT => '0', + TXCRCINTCLK => pgpClk, + TXCRCOUT => open, + TXCRCPD => '0', + TXCRCRESET => '0', + + ---------------------------- Calibration Ports ------------------------ + + RXCALFAIL => open, + RXCYCLELIMIT => open, + TXCALFAIL => open, + TXCYCLELIMIT => open, + + ------------------------------ Serial Ports ---------------------------- + + RX1N => mgtRxN(3), + RX1P => mgtRxP(3), + TX1N => mgtTxN(3), + TX1P => mgtTxP(3), + + ------------------------------- PLL Lock ------------------------------- + + RXLOCK => mgtRxLock(3), + TXLOCK => mgtTxLock(3), + + -------------------------------- Resets ------------------------------- + + RXPMARESET => mgtRxPmaReset(3), + RXRESET => mgtRxReset(3), + TXPMARESET => mgtTxPmaReset(3), + TXRESET => mgtTxReset(3), + + ---------------------------- Synchronization --------------------------- + + RXSYNC => '0', + TXSYNC => '0', + + ---------------------------- Out of Band Signalling ------------------- + + RXSIGDET => open, + TXENOOB => '0', + + -------------------------------- Status -------------------------------- + + RXBUFERR => mgtRxBuffError(3), + RXCLKSTABLE => '1', + RXSTATUS => open, + TXBUFERR => mgtTxBuffError(3), + TXCLKSTABLE => '1', + + ---------------------------- Polarity Control Ports -------------------- + + RXPOLARITY => phyRxPolarity(3), + TXINHIBIT => '0', + TXPOLARITY => '0', + + ------------------------------- Channel Bonding Ports ------------------ + + CHBONDI => mgtChanBond, + CHBONDO => open, + ENCHANSYNC => '1', + + ---------------------------- 64B66B Blocks Use Ports ------------------- + + RXBLOCKSYNC64B66BUSE => '0', + RXDEC64B66BUSE => '0', + RXDESCRAM64B66BUSE => '0', + RXIGNOREBTF => '0', + TXENC64B66BUSE => '0', + TXGEARBOX64B66BUSE => '0', + TXSCRAM64B66BUSE => '0', + + ---------------------------- 8B10B Blocks Use Ports -------------------- + + RXDEC8B10BUSE => '1', + TXBYPASS8B10B(7 downto 2) => (others=>'0'), + TXBYPASS8B10B(1 downto 0) => (others=>'0'), + TXENC8B10BUSE => '1', + + ------------------------------ Transmit Control Ports ------------------ + + TXCHARDISPMODE(7 downto 0) => (others=>'0'), + TXCHARDISPVAL(7 downto 0) => (others=>'0'), + TXCHARISK(7 downto 2) => (others=>'0'), + TXCHARISK(1 downto 0) => phyTxDataK(3 downto 2), + TXKERR(7 downto 0) => open, + TXRUNDISP(7 downto 0) => open, + + ------------------------------ Receive Control Ports ------------------- + + RXCHARISCOMMA => open, + RXCHARISK(7 downto 2) => open, + RXCHARISK(1 downto 0) => phyRxDataK(7 downto 6), + RXDISPERR(7 downto 2) => open, + RXDISPERR(1 downto 0) => phyRxDispErr(7 downto 6), + RXNOTINTABLE(7 downto 2) => open, + RXNOTINTABLE(1 downto 0) => phyRxDecErr(7 downto 6), + RXRUNDISP(7 downto 0) => open, + + ------------------------------- Serdes Alignment ----------------------- + + ENMCOMMAALIGN => '1', + ENPCOMMAALIGN => '1', + RXCOMMADET => open, + RXCOMMADETUSE => '1', + RXLOSSOFSYNC => open, + RXREALIGN => open, + RXSLIDE => '0', + + ----------- Data Width Settings - Internal and fabric interface -------- + + RXDATAWIDTH => "01", + RXINTDATAWIDTH => "11", + TXDATAWIDTH => "01", + TXINTDATAWIDTH => "11", + + ------------------------------- Data Ports ----------------------------- + + RXDATA(63 downto 16) => open, + RXDATA(15 downto 0) => phyRxData(63 downto 48), + TXDATA(63 downto 16) => (others=>'0'), + TXDATA(15 downto 0) => phyTxData(63 downto 48), + + ------------------------------- User Clocks ----------------------------- + + RXMCLK => open, + RXPCSHCLKOUT => open, + RXRECCLK1 => open, + RXRECCLK2 => open, + RXUSRCLK => '0', + RXUSRCLK2 => pgpClk, + TXOUTCLK1 => open, + TXOUTCLK2 => open, + TXPCSHCLKOUT => open, + TXUSRCLK => '0', + TXUSRCLK2 => pgpClk, + + ---------------------------- Reference Clocks -------------------------- + + GREFCLK => '0', + REFCLK1 => mgtRefClk1, + REFCLK2 => mgtRefClk2, + + ---------------------------- Powerdown and Loopback Ports -------------- + + LOOPBACK(1) => mgtLoopback, + LOOPBACK(0) => mgtLoopback, + POWERDOWN => '0', + + ------------------- Dynamic Reconfiguration Port (DRP) ------------------ + + DADDR => (others=>'0'), + DCLK => '0', + DEN => '0', + DI => (others=>'0'), + DO => open, + DRDY => open, + DWE => '0', + + --------------------- MGT Tile Communication Ports ------------------ + + COMBUSIN => mgtCombusOutC, + COMBUSOUT => mgtCombusInC + ); + + +end Pgp2Mgt64; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtClk.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtClk.vhd new file mode 100755 index 0000000000000000000000000000000000000000..2a81c73652895b5faa4fe5a617826025c5ea1b1b --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtClk.vhd @@ -0,0 +1,207 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Clock Generation Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2MgtClk.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/28/2009 +------------------------------------------------------------------------------- +-- Description: +-- PGP Clock Module. Contains DCM to support PGP. +-- Used to generate global buffer clock for PGP core at the same frequency +-- as the input reference clock. Will also generate an optional 125Mhz +-- global clock and reset for external logic use. +-- RefClk should be generated from external GT11CLK Module. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/28/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2MgtClk is + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Input + refClkIn : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpReset : out std_logic; + + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + +end Pgp2MgtClk; + + +-- Define architecture +architecture Pgp2MgtClk of Pgp2MgtClk is + + -- Local Signals + signal ponReset : std_logic; + signal tmpPgpClk : std_logic; + signal intPgpClk : std_logic; + signal intPgpRst : std_logic; + signal tmpLocClk : std_logic; + signal intUsrClk : std_logic; + signal intUsrRst : std_logic; + signal syncPgpRstIn : std_logic_vector(2 downto 0); + signal pgpRstCnt : std_logic_vector(3 downto 0); + signal syncLocRstIn : std_logic_vector(2 downto 0); + signal locRstCnt : std_logic_vector(3 downto 0); + signal dcmLock : std_logic; + signal resetIn : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output Generated Clock And Reset Signals + pgpClk <= intPgpClk; + pgpReset <= intPgpRst; + userClk <= intUsrClk; + userReset <= intUsrRst; + + -- Invert power on reset + ponReset <= not ponResetL; + + + -- DCM For PGP Clock & User Clock + U_PgpDcm: DCM + generic map ( + DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "HIGH", + DUTY_CYCLE_CORRECTION => FALSE, CLKIN_DIVIDE_BY_2 => FALSE, + CLK_FEEDBACK => "1X", CLKOUT_PHASE_SHIFT => "NONE", + STARTUP_WAIT => false, PHASE_SHIFT => 0, + CLKFX_MULTIPLY => UserFxMult, CLKFX_DIVIDE => UserFxDiv, + CLKDV_DIVIDE => 4.0, CLKIN_PERIOD => 6.4, + DSS_MODE => "NONE", FACTORY_JF => X"C080", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS" + ) + port map ( + CLKIN => refClkIn, CLKFB => intPgpClk, + CLK0 => tmpPgpClk, CLK90 => open, + CLK180 => open, CLK270 => open, + CLK2X => open, CLK2X180 => open, + CLKDV => tmpLocClk, CLKFX => open, + CLKFX180 => open, LOCKED => dcmLock, + PSDONE => open, STATUS => open, + DSSEN => '0', PSCLK => '0', + PSEN => '0', PSINCDEC => '0', + RST => ponReset + ); + + + -- Global Buffer For PGP Clock + U_PgpClkBuff: BUFGMUX port map ( + O => intPgpClk, + I0 => tmpPgpClk, + I1 => '0', + S => '0' + ); + + + -- Global Buffer For 125Mhz Clock + U_LocClkBuff: BUFGMUX port map ( + O => intUsrClk, + I0 => tmpLocClk, + I1 => '0', + S => '0' + ); + + + -- Generate reset input + resetIn <= (not dcmLock) or ponReset or locReset; + + -- PGP Clock Synced Reset + process ( pgpClkIn, resetIn ) begin + if resetIn = '1' then + syncPgpRstIn <= (others=>'0') after tpd; + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + elsif rising_edge(pgpClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncPgpRstIn(0) <= '1' after tpd; + syncPgpRstIn(1) <= syncPgpRstIn(0) after tpd; + syncPgpRstIn(2) <= syncPgpRstIn(1) after tpd; + + -- Reset counter on reset + if syncPgpRstIn(2) = '0' then + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + + -- Count Up To Max Value + elsif pgpRstCnt = "1111" then + intPgpRst <= '0' after tpd; + + -- Increment counter + else + intPgpRst <= '1' after tpd; + pgpRstCnt <= pgpRstCnt + 1 after tpd; + end if; + end if; + end process; + + -- Local User Clock Synced Reset + process ( userClkIn, resetIn ) begin + if resetIn = '1' then + syncLocRstIn <= (others=>'0') after tpd; + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + elsif rising_edge(userClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncLocRstIn(0) <= '1' after tpd; + syncLocRstIn(1) <= syncLocRstIn(0) after tpd; + syncLocRstIn(2) <= syncLocRstIn(1) after tpd; + + -- Reset counter on reset + if syncLocRstIn(2) = '0' then + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + + -- Count Up To Max Value + elsif locRstCnt = "1111" then + intUsrRst <= '0' after tpd; + + -- Increment counter + else + intUsrRst <= '1' after tpd; + locRstCnt <= locRstCnt + 1 after tpd; + end if; + end if; + end process; + +end Pgp2MgtClk; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtPackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtPackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..eb5584d27e9675fc2421516d1cc65350c29fc843 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtPackage.vhd @@ -0,0 +1,333 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, MGT Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2MgtPackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/23/2009 +------------------------------------------------------------------------------- +-- Description: +-- MGT Components package. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/23/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2MgtPackage is + + -- 16-bit wrapper + component Pgp2Mgt16 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + MgtMode : string := "A"; -- Default Location + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state reset + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(15 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(15 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic; -- MGT Serial Receive Negative + mgtRxP : in std_logic; -- MGT Serial Receive Positive + mgtTxN : out std_logic; -- MGT Serial Transmit Negative + mgtTxP : out std_logic; -- MGT Serial Transmit Positive + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0); + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- 32-bit wrapper + component Pgp2Mgt32 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state reset + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(31 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(31 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic_vector(1 downto 0); -- MGT Serial Receive Negative + mgtRxP : in std_logic_vector(1 downto 0); -- MGT Serial Receive Positive + mgtTxN : out std_logic_vector(1 downto 0); -- MGT Serial Transmit Negative + mgtTxP : out std_logic_vector(1 downto 0); -- MGT Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- 64-bit wrapper + component Pgp2Mgt64 + generic ( + EnShortCells : integer := 1; -- Enable short non-EOF cells + VcInterleave : integer := 1; -- Interleave Frames + RefClkSel : string := "REFCLK1" -- Reference Clock To Use "REFCLK1" or "REFCLK2" + ); + port ( + pgpClk : in std_logic; -- 156.25Mhz master clock + pgpReset : in std_logic; -- Synchronous reset input + pgpFlush : in std_logic; -- Frame state reset + pllTxRst : in std_logic; -- Reset transmit PLL logic + pllRxRst : in std_logic; -- Reset receive PLL logic + pllRxReady : out std_logic; -- MGT Receive logic is ready + pllTxReady : out std_logic; -- MGT Transmit logic is ready + pgpRemData : out std_logic_vector(7 downto 0); -- Far end side User Data + pgpLocData : in std_logic_vector(7 downto 0); -- Far end side User Data + pgpTxOpCodeEn : in std_logic; -- Opcode receive enable + pgpTxOpCode : in std_logic_vector(7 downto 0); -- Opcode receive value + pgpRxOpCodeEn : out std_logic; -- Opcode receive enable + pgpRxOpCode : out std_logic_vector(7 downto 0); -- Opcode receive value + pgpLocLinkReady : out std_logic; -- Local Link is ready + pgpRemLinkReady : out std_logic; -- Far end side has link + pgpRxCellError : out std_logic; -- A cell error has occured + pgpRxLinkDown : out std_logic; -- A link down event has occured + pgpRxLinkError : out std_logic; -- A link error has occured + vc0FrameTxValid : in std_logic; -- User frame data is valid + vc0FrameTxReady : out std_logic; -- PGP is ready + vc0FrameTxSOF : in std_logic; -- User frame data start of frame + vc0FrameTxEOF : in std_logic; -- User frame data end of frame + vc0FrameTxEOFE : in std_logic; -- User frame data error + vc0FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc0LocBuffAFull : in std_logic; -- Remote buffer almost full + vc0LocBuffFull : in std_logic; -- Remote buffer full + vc1FrameTxValid : in std_logic; -- User frame data is valid + vc1FrameTxReady : out std_logic; -- PGP is ready + vc1FrameTxSOF : in std_logic; -- User frame data start of frame + vc1FrameTxEOF : in std_logic; -- User frame data end of frame + vc1FrameTxEOFE : in std_logic; -- User frame data error + vc1FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc1LocBuffAFull : in std_logic; -- Remote buffer almost full + vc1LocBuffFull : in std_logic; -- Remote buffer full + vc2FrameTxValid : in std_logic; -- User frame data is valid + vc2FrameTxReady : out std_logic; -- PGP is ready + vc2FrameTxSOF : in std_logic; -- User frame data start of frame + vc2FrameTxEOF : in std_logic; -- User frame data end of frame + vc2FrameTxEOFE : in std_logic; -- User frame data error + vc2FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc2LocBuffAFull : in std_logic; -- Remote buffer almost full + vc2LocBuffFull : in std_logic; -- Remote buffer full + vc3FrameTxValid : in std_logic; -- User frame data is valid + vc3FrameTxReady : out std_logic; -- PGP is ready + vc3FrameTxSOF : in std_logic; -- User frame data start of frame + vc3FrameTxEOF : in std_logic; -- User frame data end of frame + vc3FrameTxEOFE : in std_logic; -- User frame data error + vc3FrameTxData : in std_logic_vector(63 downto 0); -- User frame data + vc3LocBuffAFull : in std_logic; -- Remote buffer almost full + vc3LocBuffFull : in std_logic; -- Remote buffer full + vcFrameRxSOF : out std_logic; -- PGP frame data start of frame + vcFrameRxEOF : out std_logic; -- PGP frame data end of frame + vcFrameRxEOFE : out std_logic; -- PGP frame data error + vcFrameRxData : out std_logic_vector(63 downto 0); -- PGP frame data + vc0FrameRxValid : out std_logic; -- PGP frame data is valid + vc0RemBuffAFull : out std_logic; -- Remote buffer almost full + vc0RemBuffFull : out std_logic; -- Remote buffer full + vc1FrameRxValid : out std_logic; -- PGP frame data is valid + vc1RemBuffAFull : out std_logic; -- Remote buffer almost full + vc1RemBuffFull : out std_logic; -- Remote buffer full + vc2FrameRxValid : out std_logic; -- PGP frame data is valid + vc2RemBuffAFull : out std_logic; -- Remote buffer almost full + vc2RemBuffFull : out std_logic; -- Remote buffer full + vc3FrameRxValid : out std_logic; -- PGP frame data is valid + vc3RemBuffAFull : out std_logic; -- Remote buffer almost full + vc3RemBuffFull : out std_logic; -- Remote buffer full + mgtLoopback : in std_logic; -- MGT Serial Loopback Control + mgtRefClk1 : in std_logic; -- MGT Reference Clock In 1 + mgtRefClk2 : in std_logic; -- MGT Reference Clock In 2 + mgtRxRecClk : out std_logic; -- MGT Rx Recovered Clock + mgtRxN : in std_logic_vector(3 downto 0); -- MGT Serial Receive Negative + mgtRxP : in std_logic_vector(3 downto 0); -- MGT Serial Receive Positive + mgtTxN : out std_logic_vector(3 downto 0); -- MGT Serial Transmit Negative + mgtTxP : out std_logic_vector(3 downto 0); -- MGT Serial Transmit Positive + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- PGP Clock Generator + component Pgp2MgtClk + generic ( + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + refClkIn : in std_logic; + ponResetL : in std_logic; + locReset : in std_logic; + pgpClk : out std_logic; + pgpReset : out std_logic; + userClk : out std_logic; + userReset : out std_logic; + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + end component; + + -- RX Reset Control + component Pgp2MgtRxRst + port ( + mgtRxClk : in std_logic; + mgtRxRst : in std_logic; + mgtRxReady : out std_logic; + mgtRxInit : in std_logic; + mgtRxLock : in std_logic; + mgtRxPmaReset : out std_logic; + mgtRxReset : out std_logic; + mgtRxBuffError : in std_logic + ); + end component; + + -- TX Reset Control + component Pgp2MgtTxRst + port ( + mgtTxClk : in std_logic; + mgtTxRst : in std_logic; + mgtTxReady : out std_logic; + mgtTxLock : in std_logic; + mgtTxPmaReset : out std_logic; + mgtTxReset : out std_logic; + mgtTxBuffError : in std_logic + ); + end component; + +end Pgp2MgtPackage; + + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtRxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtRxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..1cf0308f1fef0d8be2ed9d4996f568eafc1c2d13 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtRxRst.vhd @@ -0,0 +1,291 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, MGT RX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2MgtRxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/27/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the RX MGT. +------------------------------------------------------------------------------- +-- Copyright (c) 2009 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/27/2009: created. +-- 01/13/2010: Added received init line to help linking. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2MgtRxRst is + port ( + + -- Clock and reset, must not be derived from MGT receive PLL + mgtRxClk : in std_logic; + mgtRxRst : in std_logic; + + -- RX Side is ready + mgtRxReady : out std_logic; + mgtRxInit : in std_logic; + + -- Lock status + mgtRxLock : in std_logic; + + -- PCS & PMA Reset + mgtRxPmaReset : out std_logic; + mgtRxReset : out std_logic; + + -- Buffer error + mgtRxBuffError : in std_logic + ); + +end Pgp2MgtRxRst; + + +-- Define architecture +architecture Pgp2MgtRxRst of Pgp2MgtRxRst is + + -- Local Signals + signal rxPcsResetCnt : std_logic_vector(3 downto 0); + signal rxPcsResetCntRst : std_logic; + signal rxPcsResetCntEn : std_logic; + signal rxStateCnt : std_logic_vector(13 downto 0); + signal rxStateCntRst : std_logic; + signal intRxPmaReset : std_logic; + signal intRxReset : std_logic; + signal rxClockReady : std_logic; + + -- RX Reset State Machine + constant RX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant RX_PMA_RESET : std_logic_vector(2 downto 0) := "001"; + constant RX_WAIT_LOCK : std_logic_vector(2 downto 0) := "010"; + constant RX_PCS_RESET : std_logic_vector(2 downto 0) := "011"; + constant RX_WAIT_PCS : std_logic_vector(2 downto 0) := "100"; + constant RX_ALMOST_READY : std_logic_vector(2 downto 0) := "101"; + constant RX_READY : std_logic_vector(2 downto 0) := "110"; + signal curRxState : std_logic_vector(2 downto 0); + signal nxtRxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- State Machine Synchronous Logic + process ( mgtRxClk, mgtRxRst ) begin + if mgtRxRst = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + rxPcsResetCnt <= (others=>'0') after tpd; + rxStateCnt <= (others=>'0') after tpd; + mgtRxPmaReset <= '1' after tpd; + mgtRxReset <= '0' after tpd; + mgtRxReady <= '0' after tpd; + elsif rising_edge(mgtRxClk) then + + -- Pass on reset signals + mgtRxPmaReset <= intRxPmaReset after tpd; + mgtRxReset <= intRxReset after tpd; + + -- Update state + if mgtRxInit = '1' then + curRxState <= RX_SYSTEM_RESET after tpd; + else + curRxState <= nxtRxState after tpd; + end if; + + -- Rx State Counter + if rxStateCntRst = '1' then + rxStateCnt <= (others=>'0') after tpd; + else + rxStateCnt <= rxStateCnt + 1 after tpd; + end if; + + -- RX Loop Counter + if rxPcsResetCntRst = '1' then + rxPcsResetCnt <= (others=>'0') after tpd; + elsif rxPcsResetCntEn = '1' then + rxPcsResetCnt <= rxPcsResetCnt + 1 after tpd; + end if; + + -- Ready flag + mgtRxReady <= rxClockReady after tpd; + + end if; + end process; + + + -- Async RX State Logic + process ( curRxState, rxStateCnt, mgtRxLock, mgtRxBuffError, rxPcsResetCnt ) begin + case curRxState is + + -- System Reset State + when RX_SYSTEM_RESET => + rxPcsResetCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxStateCntRst <= '1'; + intRxPmaReset <= '1'; + intRxReset <= '0'; + rxClockReady <= '0'; + nxtRxState <= RX_PMA_RESET; + + -- PMA Reset State + when RX_PMA_RESET => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '1'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Wait for three clocks + if rxStateCnt = 3 then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Wait for RX Lock + when RX_WAIT_LOCK => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= not mgtRxLock; + rxClockReady <= '0'; + + -- Wait for rx to be locked for 16K clock cycles + if rxStateCnt = "11111111111111" then + nxtRxState <= RX_PCS_RESET; + else + nxtRxState <= curRxState; + end if; + + -- Assert PCS Reset + when RX_PCS_RESET => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '1'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + + -- Wait for three clocks + elsif rxStateCnt = 3 then + nxtRxState <= RX_WAIT_PCS; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Wait 5 clocks after PCS reset + when RX_WAIT_PCS => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + + -- Wait for five clocks + elsif rxStateCnt = 5 then + nxtRxState <= RX_ALMOST_READY; + rxStateCntRst <= '1'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + end if; + + -- Almost Ready State + when RX_ALMOST_READY => + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxClockReady <= '0'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + + -- RX Buffer Error + elsif mgtRxBuffError = '1' then + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '1'; + + -- 16 Cycles have occured, reset PLL + if rxPcsResetCnt = 15 then + nxtRxState <= RX_PMA_RESET; + rxPcsResetCntRst <= '1'; + + -- Go back to PCS Reset + else + nxtRxState <= RX_PCS_RESET; + rxPcsResetCntRst <= '0'; + end if; + + -- Wait for 64 clocks + elsif rxStateCnt = 63 then + nxtRxState <= RX_READY; + rxStateCntRst <= '1'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + else + nxtRxState <= curRxState; + rxStateCntRst <= '0'; + rxPcsResetCntEn <= '0'; + rxPcsResetCntRst <= '0'; + end if; + + -- Ready State + when RX_READY => + rxPcsResetCntRst <= '1'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= '1'; + rxClockReady <= '1'; + + -- Loss of Lock + if mgtRxLock = '0' then + nxtRxState <= RX_WAIT_LOCK; + + -- Buffer error has occured + elsif mgtRxBuffError = '1' then + nxtRxState <= RX_PCS_RESET; + else + nxtRxState <= curRxState; + end if; + + -- Just in case + when others => + rxPcsResetCntRst <= '0'; + rxPcsResetCntEn <= '0'; + intRxPmaReset <= '0'; + intRxReset <= '0'; + rxStateCntRst <= '0'; + rxClockReady <= '0'; + nxtRxState <= RX_SYSTEM_RESET; + end case; + end process; + +end Pgp2MgtRxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtTxRst.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtTxRst.vhd new file mode 100755 index 0000000000000000000000000000000000000000..8c855ff906d72c291343e0378db0fdd40703db69 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/Pgp2MgtTxRst.vhd @@ -0,0 +1,283 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, MGT TX Reset Control +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2MgtTxRst.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/27/2009 +------------------------------------------------------------------------------- +-- Description: +-- This module contains the logic to control the reset of the TX MGT. +------------------------------------------------------------------------------- +-- Copyright (c) 2009 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/27/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity Pgp2MgtTxRst is port ( + + -- Clock and reset, must not be derived from MGT transmit PLL + mgtTxClk : in std_logic; + mgtTxRst : in std_logic; + + -- TX Side is ready + mgtTxReady : out std_logic; + + -- Lock status + mgtTxLock : in std_logic; + + -- PCS & PMA Reset + mgtTxPmaReset : out std_logic; + mgtTxReset : out std_logic; + + -- Buffer error + mgtTxBuffError : in std_logic + ); + +end Pgp2MgtTxRst; + + +-- Define architecture +architecture Pgp2MgtTxRst of Pgp2MgtTxRst is + + -- Local Signals + signal txPcsResetCnt : std_logic_vector(3 downto 0); + signal txPcsResetCntRst : std_logic; + signal txPcsResetCntEn : std_logic; + signal txStateCnt : std_logic_vector(5 downto 0); + signal txStateCntRst : std_logic; + signal intTxPmaReset : std_logic; + signal intTxReset : std_logic; + signal txClockReady : std_logic; + + -- TX Reset State Machine + constant TX_SYSTEM_RESET : std_logic_vector(2 downto 0) := "000"; + constant TX_PMA_RESET : std_logic_vector(2 downto 0) := "001"; + constant TX_WAIT_LOCK : std_logic_vector(2 downto 0) := "010"; + constant TX_PCS_RESET : std_logic_vector(2 downto 0) := "011"; + constant TX_WAIT_PCS : std_logic_vector(2 downto 0) := "100"; + constant TX_ALMOST_READY : std_logic_vector(2 downto 0) := "101"; + constant TX_READY : std_logic_vector(2 downto 0) := "110"; + signal curTxState : std_logic_vector(2 downto 0); + signal nxtTxState : std_logic_vector(2 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- State Machine Synchronous Logic + process ( mgtTxClk, mgtTxRst ) begin + if mgtTxRst = '1' then + curTxState <= TX_SYSTEM_RESET after tpd; + txPcsResetCnt <= (others=>'0') after tpd; + txStateCnt <= (others=>'0') after tpd; + mgtTxPmaReset <= '1' after tpd; + mgtTxReset <= '0' after tpd; + mgtTxReady <= '0' after tpd; + elsif rising_edge(mgtTxClk) then + + -- Pass on reset signals + mgtTxPmaReset <= intTxPmaReset after tpd; + mgtTxReset <= intTxReset after tpd; + + -- Update state + curTxState <= nxtTxState after tpd; + + -- Tx State Counter + if txStateCntRst = '1' then + txStateCnt <= (others=>'0') after tpd; + else + txStateCnt <= txStateCnt + 1 after tpd; + end if; + + -- TX Loop Counter + if txPcsResetCntRst = '1' then + txPcsResetCnt <= (others=>'0') after tpd; + elsif txPcsResetCntEn = '1' then + txPcsResetCnt <= txPcsResetCnt + 1 after tpd; + end if; + + -- Ready flag + mgtTxReady <= txClockReady after tpd; + end if; + end process; + + + -- Async TX State Logic + process ( curTxState, txStateCnt, mgtTxLock, mgtTxBuffError, txPcsResetCnt ) begin + case curTxState is + + -- System Reset State + when TX_SYSTEM_RESET => + txPcsResetCntRst <= '1'; + txPcsResetCntEn <= '0'; + txStateCntRst <= '1'; + intTxPmaReset <= '1'; + intTxReset <= '0'; + txClockReady <= '0'; + nxtTxState <= TX_PMA_RESET; + + -- PMA Reset State + when TX_PMA_RESET => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '1'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Wait for three clocks + if txStateCnt = 3 then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Wait for TX Lock + when TX_WAIT_LOCK => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '1'; + txClockReady <= '0'; + + -- Wait for three clocks + if mgtTxLock = '1' then + nxtTxState <= TX_PCS_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Assert PCS Reset + when TX_PCS_RESET => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '1'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + + -- Wait for three clocks + elsif txStateCnt = 3 then + nxtTxState <= TX_WAIT_PCS; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Wait 5 clocks after PCS reset + when TX_WAIT_PCS => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + + -- Wait for three clocks + elsif txStateCnt = 5 then + nxtTxState <= TX_ALMOST_READY; + txStateCntRst <= '1'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + end if; + + -- Almost Ready State + when TX_ALMOST_READY => + intTxPmaReset <= '0'; + intTxReset <= '0'; + txClockReady <= '0'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + txStateCntRst <= '1'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + + -- TX Buffer Error + elsif mgtTxBuffError = '1' then + txStateCntRst <= '1'; + txPcsResetCntEn <= '1'; + + -- 16 Cycles have occured, reset PLL + if txPcsResetCnt = 15 then + nxtTxState <= TX_PMA_RESET; + txPcsResetCntRst <= '1'; + + -- Go back to PCS Reset + else + nxtTxState <= TX_PCS_RESET; + txPcsResetCntRst <= '0'; + end if; + + -- Wait for 64 clocks + elsif txStateCnt = 63 then + nxtTxState <= TX_READY; + txStateCntRst <= '1'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + else + nxtTxState <= curTxState; + txStateCntRst <= '0'; + txPcsResetCntEn <= '0'; + txPcsResetCntRst <= '0'; + end if; + + -- Ready State + when TX_READY => + txPcsResetCntRst <= '1'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '1'; + txClockReady <= '1'; + + -- Loss of Lock + if mgtTxLock = '0' then + nxtTxState <= TX_WAIT_LOCK; + + -- Buffer error has occured + elsif mgtTxBuffError = '1' then + nxtTxState <= TX_PCS_RESET; + else + nxtTxState <= curTxState; + end if; + + -- Just in case + when others => + txPcsResetCntRst <= '0'; + txPcsResetCntEn <= '0'; + intTxPmaReset <= '0'; + intTxReset <= '0'; + txStateCntRst <= '0'; + txClockReady <= '0'; + nxtTxState <= TX_SYSTEM_RESET; + end case; + end process; + +end Pgp2MgtTxRst; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/mgt/PgpClkGen.vhd b/rce/fw-hsio/modules/pgp2/hdl/mgt/PgpClkGen.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4af2acf3a74ee6772e4fa3dfe06fe6dd6ee6f0b6 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/mgt/PgpClkGen.vhd @@ -0,0 +1,298 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, V2, Clock Generation Block +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2MgtClk.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 05/28/2009 +------------------------------------------------------------------------------- +-- Description: +-- PGP Clock Module. Contains DCM to support PGP. +-- Used to generate global buffer clock for PGP core at the same frequency +-- as the input reference clock. Will also generate an optional 125Mhz +-- global clock and reset for external logic use. +-- RefClk should be generated from external GT11CLK Module. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 05/28/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.Pgp2MgtPackage.all; +library UNISIM; +use UNISIM.VCOMPONENTS.ALL; + +entity PgpClkGen is + generic ( + RefClkEn1 : string := "ENABLE"; -- ENABLE or DISABLE + RefClkEn2 : string := "DISABLE"; -- ENABLE or DISABLE + DcmClkSrc : string := "RefClk1"; -- RefClk1 or RefClk2 + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Pad Inputs + pgpRefClkInP : in std_logic; + pgpRefClkInN : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Reference Clock To PGP MGT + -- Use one, See RefClkEn1 & RefClkEn2 Generics + pgpRefClk1 : out std_logic; + pgpRefClk2 : out std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpClk90 : out std_logic; + pgpReset : out std_logic; + + clk320 : out std_logic; + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic; + + -- Output unbuffered clocks + pgpClkUnbuf : out std_logic; + pgpClk90Unbuf : out std_logic; + locClkUnbuf : out std_logic + ); + +end PgpClkGen; + + +-- Define architecture +architecture PgpClkGen of PgpClkGen is + + -- Xilinx GTLL Clock Module + component GT11CLK + generic ( + REFCLKSEL : string := "MGTCLK"; + SYNCLK1OUTEN : string := "ENABLE"; + SYNCLK2OUTEN : string := "DISABLE" + ); + port ( + SYNCLK1OUT : out std_ulogic; + SYNCLK2OUT : out std_ulogic; + MGTCLKN : in std_ulogic; + MGTCLKP : in std_ulogic; + REFCLK : in std_ulogic; + RXBCLK : in std_ulogic; + SYNCLK1IN : in std_ulogic; + SYNCLK2IN : in std_ulogic + ); + end component; + + -- Local Signals + signal ponReset : std_logic; + signal intRefClk1 : std_logic; + signal intRefClk2 : std_logic; + signal tmpPgpClk : std_logic; + signal tmpPgpClk90 : std_logic; + signal intPgpClk : std_logic; + signal intPgpClk90 : std_logic; + signal intPgpRst : std_logic; + signal tmpLocClk : std_logic; + signal tmp320Clk : std_logic; + signal int320Clk : std_logic; + signal intUsrClk : std_logic; + signal intUsrRst : std_logic; + signal syncPgpRstIn : std_logic_vector(2 downto 0); + signal pgpRstCnt : std_logic_vector(3 downto 0); + signal syncLocRstIn : std_logic_vector(2 downto 0); + signal locRstCnt : std_logic_vector(3 downto 0); + signal dcmRefClk : std_logic; + signal dcmLock : std_logic; + signal resetIn : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output Generated Clock And Reset Signals + pgpRefClk1 <= intRefClk1; + pgpRefClk2 <= intRefClk2; + pgpClk <= intPgpClk; + pgpClk90 <= intPgpClk90; + clk320 <= int320Clk; + pgpReset <= intPgpRst; + userClk <= intUsrClk; + userReset <= intUsrRst; + + -- Output unbuffered clocks + pgpClkUnbuf <= tmpPgpClk; + pgpClk90Unbuf <= tmpPgpClk90; + locClkUnbuf <= tmpLocClk; + + -- Invert power on reset + ponReset <= not ponResetL; + + -- MGT Clock Module + U_PgpClkGT11: GT11CLK generic map ( + SYNCLK1OUTEN => RefClkEn1, + SYNCLK2OUTEN => RefClkEn2, + REFCLKSEL => "MGTCLK" + ) port map ( + MGTCLKN => pgpRefClkInN, + MGTCLKP => pgpRefClkInP, + REFCLK => '0', + RXBCLK => '0', + SYNCLK1IN => '0', + SYNCLK2IN => '0', + SYNCLK1OUT => intRefClk1, + SYNCLK2OUT => intRefClk2 + ); + + + -- REF Clock 1 Is Selected As DCM Source + U_DCM_REF1: if DcmClkSrc = "RefClk1" generate + dcmRefClk <= intRefClk1; + end generate; + + -- REF Clock 2 Is Selected As DCM Source + U_DCM_REF2: if DcmClkSrc = "RefClk2" generate + dcmRefClk <= intRefClk2; + end generate; + + + + -- DCM For PGP Clock & User Clock + U_PgpDcm: DCM + generic map ( + DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "HIGH", + DUTY_CYCLE_CORRECTION => FALSE, CLKIN_DIVIDE_BY_2 => FALSE, + CLK_FEEDBACK => "1X", CLKOUT_PHASE_SHIFT => "NONE", + STARTUP_WAIT => false, PHASE_SHIFT => 0, + CLKFX_MULTIPLY => UserFxMult, CLKFX_DIVIDE => UserFxDiv, + CLKDV_DIVIDE => 4.0, CLKIN_PERIOD => 6.4, + DSS_MODE => "NONE", FACTORY_JF => X"C080", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS" + ) + port map ( + CLKIN => dcmRefClk, CLKFB => intPgpClk, + CLK0 => tmpPgpClk, CLK90 => tmpPgpClk90, + CLK180 => open, CLK270 => open, + CLK2X => tmp320Clk, CLK2X180 => open, + CLKDV => tmpLocClk, CLKFX => open, + CLKFX180 => open, LOCKED => dcmLock, + PSDONE => open, STATUS => open, + DSSEN => '0', PSCLK => '0', + PSEN => '0', PSINCDEC => '0', + RST => ponReset + ); + + + -- Global Buffer For PGP Clock + U_PgpClkBuff: BUFGMUX port map ( + O => intPgpClk, + I0 => tmpPgpClk, + I1 => '0', + S => '0' + ); + U_PgpClkBuff90: BUFGMUX port map ( + O => intPgpClk90, + I0 => tmpPgpClk90, + I1 => '0', + S => '0' + ); + + + -- Global Buffer For 125Mhz Clock + U_LocClkBuff: BUFGMUX port map ( + O => intUsrClk, + I0 => tmpLocClk, + I1 => '0', + S => '0' + ); + U_320ClkBuff: BUFGMUX port map ( + O => int320Clk, + I0 => tmp320Clk, + I1 => '0', + S => '0' + ); + + + -- Generate reset input + resetIn <= (not dcmLock) or ponReset or locReset; + + -- PGP Clock Synced Reset + process ( pgpClkIn, resetIn ) begin + if resetIn = '1' then + syncPgpRstIn <= (others=>'0') after tpd; + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + elsif rising_edge(pgpClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncPgpRstIn(0) <= '1' after tpd; + syncPgpRstIn(1) <= syncPgpRstIn(0) after tpd; + syncPgpRstIn(2) <= syncPgpRstIn(1) after tpd; + + -- Reset counter on reset + if syncPgpRstIn(2) = '0' then + pgpRstCnt <= (others=>'0') after tpd; + intPgpRst <= '1' after tpd; + + -- Count Up To Max Value + elsif pgpRstCnt = "1111" then + intPgpRst <= '0' after tpd; + + -- Increment counter + else + intPgpRst <= '1' after tpd; + pgpRstCnt <= pgpRstCnt + 1 after tpd; + end if; + end if; + end process; + + -- Local User Clock Synced Reset + process ( userClkIn, resetIn ) begin + if resetIn = '1' then + syncLocRstIn <= (others=>'0') after tpd; + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + elsif rising_edge(userClkIn) then + + -- Sync local reset, lock and power on reset to local clock + -- Negative asserted signal + syncLocRstIn(0) <= '1' after tpd; + syncLocRstIn(1) <= syncLocRstIn(0) after tpd; + syncLocRstIn(2) <= syncLocRstIn(1) after tpd; + + -- Reset counter on reset + if syncLocRstIn(2) = '0' then + locRstCnt <= (others=>'0') after tpd; + intUsrRst <= '1' after tpd; + + -- Count Up To Max Value + elsif locRstCnt = "1111" then + intUsrRst <= '0' after tpd; + + -- Increment counter + else + intUsrRst <= '1' after tpd; + locRstCnt <= locRstCnt + 1 after tpd; + end if; + end if; + end process; + +end PgpClkGen; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2Rce.vhd b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2Rce.vhd new file mode 100755 index 0000000000000000000000000000000000000000..daedd77652af58e22ceaad659f3e56e59ade4dff --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2Rce.vhd @@ -0,0 +1,682 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, RCE Interface +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2Rce.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 06/06/2007 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source for PGP2 interface to RCE. 4-Lane version. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/18/2010: created. +-- 09/08/2010: Integrated 4x and 2x into one module. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use work.Pgp2RcePackage.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2Rce is + generic ( + FreeListA : natural := 1; -- Free List For VC 0 + FreeListB : natural := 2; -- Free List For VC 1 + FreeListC : natural := 3; -- Free List For VC 2 + FreeListD : natural := 4; -- Free List For VC 3 + RefClkSel : string := "REFCLK1"; -- Reference Clock To Use "REFCLK1" or "REFCLK2" + PgpLaneCnt : natural := 4 -- Number of PGP lanes, 2 or 4. + ); + port ( + + -- Import Interface + Import_Clock : out std_logic; + Import_Core_Reset : in std_logic; + Import_Free_List : out std_logic_vector( 3 downto 0); + Import_Advance_Data_Pipeline : out std_logic; + Import_Data_Last_Line : out std_logic; + Import_Data_Last_Valid_Byte : out std_logic_vector( 2 downto 0); + Import_Data : out std_logic_vector(63 downto 0); + Import_Data_Pipeline_Full : in std_logic; + Import_Pause : in std_logic; + + -- Export Interface + Export_Clock : out std_logic; + Export_Core_Reset : in std_logic; + Export_Data_Available : in std_logic; + Export_Data_Start : in std_logic; + Export_Advance_Data_Pipeline : out std_logic; + Export_Data_Last_Line : in std_logic; + Export_Data_Last_Valid_Byte : in std_logic_vector( 2 downto 0); + Export_Data : in std_logic_vector(63 downto 0); + Export_Advance_Status_Pipeline : out std_logic; + Export_Status : out std_logic_vector(31 downto 0); + Export_Status_Full : in std_logic; + + -- DCR Bus + Dcr_Clock : in std_logic; + Dcr_Write : in std_logic; + Dcr_Write_Data : in std_logic_vector(31 downto 0); + Dcr_Read_Address : in std_logic_vector( 1 downto 0); + Dcr_Read_Data : out std_logic_vector(31 downto 0); + + -- Reference Clock, PGP Clock & Reset Signals + -- Use one ref clock, tie other to 0, see RefClkSel above + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic_vector(PgpLaneCnt-1 downto 0); + mgtRxP : in std_logic_vector(PgpLaneCnt-1 downto 0); + mgtTxN : out std_logic_vector(PgpLaneCnt-1 downto 0); + mgtTxP : out std_logic_vector(PgpLaneCnt-1 downto 0) + ); +end Pgp2Rce; + + +-- Define architecture +architecture Pgp2Rce of Pgp2Rce is + + -- Local Signals + signal vcFrameTxVc : std_logic_vector(1 downto 0); + signal vcFrameTxSOF : std_logic; + signal vcFrameTxEOF : std_logic; + signal vcFrameTxEOFE : std_logic; + signal vcFrameTxData : std_logic_vector(15 downto 0); + signal vcFrameTxValid : std_logic_vector(3 downto 0); + signal vcFrameTxReady : std_logic_vector(3 downto 0); + signal vcRemBuffAFull : std_logic_vector(15 downto 0); + signal vcRemBuffFull : std_logic_vector(15 downto 0); + signal vcFrameRxSOF : std_logic_vector(3 downto 0); + signal vcFrameRxEOF : std_logic_vector(3 downto 0); + signal vcFrameRxEOFE : std_logic_vector(3 downto 0); + signal vcFrameRxDataA : std_logic_vector(63 downto 0); + signal vcFrameRxDataB : std_logic_vector(63 downto 0); + signal vcFrameRxDataC : std_logic_vector(63 downto 0); + signal vcFrameRxDataD : std_logic_vector(63 downto 0); + signal vcFrameRxReq : std_logic_vector(3 downto 0); + signal vcFrameRxValid : std_logic_vector(3 downto 0); + signal vcFrameRxReady : std_logic_vector(3 downto 0); + signal vcFrameRxWidthA : std_logic_vector(1 downto 0); + signal vcFrameRxWidthB : std_logic_vector(1 downto 0); + signal vcFrameRxWidthC : std_logic_vector(1 downto 0); + signal vcFrameRxWidthD : std_logic_vector(1 downto 0); + signal pgpRemLinkReady : std_logic_vector(3 downto 0); + signal pgpLocLinkReady : std_logic_vector(3 downto 0); + signal cntReset : std_logic; + signal pgpCntCellErrorA : std_logic_vector(3 downto 0); + signal pgpCntCellErrorB : std_logic_vector(3 downto 0); + signal pgpCntCellErrorC : std_logic_vector(3 downto 0); + signal pgpCntCellErrorD : std_logic_vector(3 downto 0); + signal pgpCntLinkDownA : std_logic_vector(3 downto 0); + signal pgpCntLinkDownB : std_logic_vector(3 downto 0); + signal pgpCntLinkDownC : std_logic_vector(3 downto 0); + signal pgpCntLinkDownD : std_logic_vector(3 downto 0); + signal pgpCntLinkErrorA : std_logic_vector(3 downto 0); + signal pgpCntLinkErrorB : std_logic_vector(3 downto 0); + signal pgpCntLinkErrorC : std_logic_vector(3 downto 0); + signal pgpCntLinkErrorD : std_logic_vector(3 downto 0); + signal pgpRxFifoErr : std_logic_vector(3 downto 0); + signal mgtLoopback : std_logic_vector(3 downto 0); + signal mgtCombusOutA : std_logic_vector(15 downto 0); + signal mgtCombusOutB : std_logic_vector(15 downto 0); + signal mgtCombusOutC : std_logic_vector(15 downto 0); + signal mgtCombusOutD : std_logic_vector(15 downto 0); + signal pllTxRst : std_logic_vector(3 downto 0); + signal pllRxRst : std_logic_vector(3 downto 0); + signal pllTxReady : std_logic_vector(3 downto 0); + signal pllRxReady : std_logic_vector(3 downto 0); + signal dcrReset : std_logic; + signal dcrResetSync : std_logic; + signal writeData : std_logic_vector(31 downto 0); + signal writeDataSync : std_logic_vector(31 downto 0); + signal csControl0 : std_logic_vector(35 downto 0); + signal csControl1 : std_logic_vector(35 downto 0); + signal csData : std_logic_vector(63 downto 0); + signal csCntrl : std_logic_vector(15 downto 0); + signal csStat : std_logic_vector(15 downto 0); + signal importDebug : std_logic_vector(63 downto 0); + signal exportDebug : std_logic_vector(63 downto 0); + signal lane0Debug : std_logic_vector(63 downto 0); + signal lane1Debug : std_logic_vector(63 downto 0); + signal importReset : std_logic_vector(3 downto 0); + signal pgpRxCntD : std_logic_vector(3 downto 0); + signal pgpRxCntC : std_logic_vector(3 downto 0); + signal pgpRxCntB : std_logic_vector(3 downto 0); + signal pgpRxCntA : std_logic_vector(3 downto 0); + signal bigEndian : std_logic; + signal importPauseDly : std_logic; + signal importPauseCnt : std_logic_vector(3 downto 0); + + -- ICON + component pgp2_v4_icon + PORT ( + CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CONTROL1 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); + end component; + + -- ILA + component pgp2_v4_ila + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + DATA : IN STD_LOGIC_VECTOR(63 DOWNTO 0); + TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); + end component; + + -- VIO + component pgp2_v4_vio + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + SYNC_IN : IN STD_LOGIC_VECTOR(15 DOWNTO 0); + SYNC_OUT : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); + end component; + + -- Chipscope attributes + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of pgp2_v4_icon : component is TRUE; + attribute syn_noprune of pgp2_v4_icon : component is TRUE; + attribute syn_black_box of pgp2_v4_ila : component is TRUE; + attribute syn_noprune of pgp2_v4_ila : component is TRUE; + attribute syn_black_box of pgp2_v4_vio : component is TRUE; + attribute syn_noprune of pgp2_v4_vio : component is TRUE; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Create import reset vector + importReset <= Import_Core_Reset & Import_Core_Reset & Import_Core_Reset & Import_Core_Reset; + + -- Dcr Reset generation, Sync to DCR Clock + process ( Dcr_Clock ) begin + if rising_edge(Dcr_Clock) then + dcrResetSync <= pgpReset after tpd; + dcrReset <= dcrResetSync after tpd; + end if; + end process; + + + -- DCR Read + process ( dcrReset, Dcr_Clock ) begin + if dcrReset = '1' then + Dcr_Read_Data <= (others=>'0') after tpd; + elsif rising_edge(Dcr_Clock) then + case Dcr_Read_Address is + when "00" => + Dcr_Read_Data(31 downto 28) <= pgpRemLinkReady after tpd; + Dcr_Read_Data(27 downto 24) <= pgpLocLinkReady after tpd; + Dcr_Read_Data(23 downto 20) <= pllTxReady after tpd; + Dcr_Read_Data(19 downto 16) <= pllRxReady after tpd; + Dcr_Read_Data(15 downto 14) <= (others=>'0') after tpd; + Dcr_Read_Data(13) <= bigEndian after tpd; + Dcr_Read_Data(12) <= cntReset after tpd; + Dcr_Read_Data(11 downto 8) <= pllTxRst after tpd; + Dcr_Read_Data(7 downto 4) <= pllRxRst after tpd; + Dcr_Read_Data(3 downto 0) <= mgtLoopback after tpd; + when "01" => + Dcr_Read_Data(31 downto 28) <= pgpCntCellErrorD after tpd; + Dcr_Read_Data(27 downto 24) <= pgpCntCellErrorC after tpd; + Dcr_Read_Data(23 downto 20) <= pgpCntCellErrorB after tpd; + Dcr_Read_Data(19 downto 16) <= pgpCntCellErrorA after tpd; + Dcr_Read_Data(15 downto 12) <= pgpCntLinkErrorD after tpd; + Dcr_Read_Data(11 downto 8) <= pgpCntLinkErrorC after tpd; + Dcr_Read_Data( 7 downto 4) <= pgpCntLinkErrorB after tpd; + Dcr_Read_Data( 3 downto 0) <= pgpCntLinkErrorA after tpd; + when "10" => + Dcr_Read_Data(31 downto 20) <= (others=>'0') after tpd; + Dcr_Read_Data(19 downto 16) <= pgpRxFifoErr after tpd; + Dcr_Read_Data(15 downto 12) <= pgpCntLinkDownD after tpd; + Dcr_Read_Data(11 downto 8) <= pgpCntLinkDownC after tpd; + Dcr_Read_Data( 7 downto 4) <= pgpCntLinkDownB after tpd; + Dcr_Read_Data( 3 downto 0) <= pgpCntLinkDownA after tpd; + when "11" => + Dcr_Read_Data(31 downto 20) <= (others=>'0') after tpd; + Dcr_Read_Data(19 downto 16) <= importPauseCnt after tpd; + Dcr_Read_Data(15 downto 12) <= pgpRxCntD after tpd; + Dcr_Read_Data(11 downto 8) <= pgpRxCntC after tpd; + Dcr_Read_Data( 7 downto 4) <= pgpRxCntB after tpd; + Dcr_Read_Data( 3 downto 0) <= pgpRxCntA after tpd; + when others => + Dcr_Read_Data <= (others=>'0') after tpd; + end case; + end if; + end process; + + + -- DCR Write + process ( dcrReset, Dcr_Clock ) begin + if dcrReset = '1' then + writeData <= (others=>'0') after tpd; + elsif rising_edge(Dcr_Clock) then + if Dcr_Write = '1' then + writeData <= Dcr_Write_Data after tpd; + end if; + end if; + end process; + + + -- Synchronize Write Data + process ( pgpReset, pgpClk ) begin + if pgpReset = '1' then + writeDataSync <= (others=>'0') after tpd; + cntReset <= '0' after tpd; + bigEndian <= '0' after tpd; + pllTxRst <= (others=>'0') after tpd; + pllRxRst <= (others=>'0') after tpd; + mgtLoopback <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + writeDataSync <= writeData after tpd; + bigEndian <= writeDataSync(13) after tpd; + cntReset <= writeDataSync(12) or csCntrl(12) or importReset(0) after tpd; + pllTxRst <= writeDataSync(11 downto 8) or csCntrl(3 downto 0) after tpd; + pllRxRst <= writeDataSync(7 downto 4) or csCntrl(7 downto 4) or importReset after tpd; + mgtLoopback <= writeDataSync(3 downto 0) or csCntrl(11 downto 8) after tpd; + end if; + end process; + + + -- Pause cycle counter + process ( pgpReset, pgpClk ) begin + if pgpReset = '1' then + importPauseDly <= '0' after tpd; + importPauseCnt <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + importPauseDly <= Import_Pause after tpd; + + -- Pause assertion counter + if cntReset = '1' then + importPauseCnt <= (others=>'0') after tpd; + elsif Import_Pause = '1' and importPauseDly = '0' and importPauseCnt /= x"F" then + importPauseCnt <= importPauseCnt + 1 after tpd; + end if; + end if; + end process; + + + -- Export Interface + U_Pgp2RceExport: Pgp2RcePackage.Pgp2RceExport port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + Export_Clock => Export_Clock, + Export_Core_Reset => Export_Core_Reset, + Export_Data_Available => Export_Data_Available, + Export_Data_Start => Export_Data_Start, + Export_Advance_Data_Pipeline => Export_Advance_Data_Pipeline, + Export_Data_Last_Line => Export_Data_Last_Line, + Export_Data_Last_Valid_Byte => Export_Data_Last_Valid_Byte, + Export_Data => Export_Data, + Export_Advance_Status_Pipeline => Export_Advance_Status_Pipeline, + Export_Status => Export_Status, + Export_Status_Full => Export_Status_Full, + pgpRemLinkReady => pgpRemLinkReady, + vcFrameTxVc => vcFrameTxVc, + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcFrameTxValid => vcFrameTxValid, + vcFrameTxReady => vcFrameTxReady, + vcRemBuffAFull => vcRemBuffAFull, + vcRemBuffFull => vcRemBuffFull, + bigEndian => bigEndian, + debug => exportDebug + ); + + + -- Import Interface + U_Pgp2RceImport: Pgp2RcePackage.Pgp2RceImport + generic map ( + FreeListA => FreeListA, + FreeListB => FreeListB, + FreeListC => FreeListC, + FreeListD => FreeListD + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + Import_Clock => Import_Clock, + Import_Core_Reset => Import_Core_Reset, + Import_Free_List => Import_Free_List, + Import_Advance_Data_Pipeline => Import_Advance_Data_Pipeline, + Import_Data_Last_Line => Import_Data_Last_Line, + Import_Data_Last_Valid_Byte => Import_Data_Last_Valid_Byte, + Import_Data => Import_Data, + Import_Data_Pipeline_Full => Import_Data_Pipeline_Full, + Import_Pause => Import_Pause, + pgpLocLinkReady => pgpLocLinkReady, + vcFrameRxSOF => vcFrameRxSOF, + vcFrameRxEOF => vcFrameRxEOF, + vcFrameRxEOFE => vcFrameRxEOFE, + vcFrameRxDataA => vcFrameRxDataA, + vcFrameRxDataB => vcFrameRxDataB, + vcFrameRxDataC => vcFrameRxDataC, + vcFrameRxDataD => vcFrameRxDataD, + vcFrameRxReq => vcFrameRxReq, + vcFrameRxValid => vcFrameRxValid, + vcFrameRxReady => vcFrameRxReady, + vcFrameRxWidthA => vcFrameRxWidthA, + vcFrameRxWidthB => vcFrameRxWidthB, + vcFrameRxWidthC => vcFrameRxWidthC, + vcFrameRxWidthD => vcFrameRxWidthD, + bigEndian => bigEndian, + debug => importDebug + ); + + + -- Lane A + U_Pgp2RceLaneA: Pgp2RcePackage.Pgp2RceLane + generic map ( + MgtMode => "A", + RefClkSel => RefClkSel + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pllTxRst => pllTxRst(0), + pllRxRst => pllRxRst(0), + pllRxReady => pllRxReady(0), + pllTxReady => pllTxReady(0), + pgpLocLinkReady => pgpLocLinkReady(0), + pgpRemLinkReady => pgpRemLinkReady(0), + cntReset => cntReset, + pgpCntCellError => pgpCntCellErrorA, + pgpCntLinkDown => pgpCntLinkDownA, + pgpCntLinkError => pgpCntLinkErrorA, + pgpRxFifoErr => pgpRxFifoErr(0), + pgpRxCnt => pgpRxCntA, + laneNumber => "00", + vcFrameRxSOF => vcFrameRxSOF(0), + vcFrameRxEOF => vcFrameRxEOF(0), + vcFrameRxEOFE => vcFrameRxEOFE(0), + vcFrameRxData => vcFrameRxDataA, + vcFrameRxReq => vcFrameRxReq(0), + vcFrameRxValid => vcFrameRxValid(0), + vcFrameRxReady => vcFrameRxReady(0), + vcFrameRxWidth => vcFrameRxWidthA, + vcFrameTxVc => vcFrameTxVc, + vcFrameTxValid => vcFrameTxValid(0), + vcFrameTxReady => vcFrameTxReady(0), + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcRemBuffAFull => vcRemBuffAFull(3 downto 0), + vcRemBuffFull => vcRemBuffFull(3 downto 0), + mgtLoopback => mgtLoopback(0), + mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, + mgtRxN => mgtRxN(0), + mgtRxP => mgtRxP(0), + mgtTxN => mgtTxN(0), + mgtTxP => mgtTxP(0), + mgtCombusIn => mgtCombusOutB, + mgtCombusOut => mgtCombusOutA, + debug => lane0Debug + ); + + + -- Lane B + U_Pgp2RceLaneB: Pgp2RcePackage.Pgp2RceLane + generic map ( + MgtMode => "B", + RefClkSel => RefClkSel + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pllTxRst => pllTxRst(1), + pllRxRst => pllRxRst(1), + pllRxReady => pllRxReady(1), + pllTxReady => pllTxReady(1), + pgpLocLinkReady => pgpLocLinkReady(1), + pgpRemLinkReady => pgpRemLinkReady(1), + cntReset => cntReset, + pgpCntCellError => pgpCntCellErrorB, + pgpCntLinkDown => pgpCntLinkDownB, + pgpCntLinkError => pgpCntLinkErrorB, + pgpRxFifoErr => pgpRxFifoErr(1), + pgpRxCnt => pgpRxCntB, + laneNumber => "01", + vcFrameRxSOF => vcFrameRxSOF(1), + vcFrameRxEOF => vcFrameRxEOF(1), + vcFrameRxEOFE => vcFrameRxEOFE(1), + vcFrameRxData => vcFrameRxDataB, + vcFrameRxReq => vcFrameRxReq(1), + vcFrameRxValid => vcFrameRxValid(1), + vcFrameRxReady => vcFrameRxReady(1), + vcFrameRxWidth => vcFrameRxWidthB, + vcFrameTxVc => vcFrameTxVc, + vcFrameTxValid => vcFrameTxValid(1), + vcFrameTxReady => vcFrameTxReady(1), + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcRemBuffAFull => vcRemBuffAFull(7 downto 4), + vcRemBuffFull => vcRemBuffFull(7 downto 4), + mgtLoopback => mgtLoopback(1), + mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, + mgtRxN => mgtRxN(1), + mgtRxP => mgtRxP(1), + mgtTxN => mgtTxN(1), + mgtTxP => mgtTxP(1), + mgtCombusIn => mgtCombusOutA, + mgtCombusOut => mgtCombusOutB, + debug => lane1Debug + ); + + + -- Enable upper two lanes + Pgp2UpperEn: if ( PgpLaneCnt = 4 ) generate + + -- Lane C + U_Pgp2RceLaneC: Pgp2RcePackage.Pgp2RceLane + generic map ( + MgtMode => "A", + RefClkSel => RefClkSel + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pllTxRst => pllTxRst(2), + pllRxRst => pllRxRst(2), + pllRxReady => pllRxReady(2), + pllTxReady => pllTxReady(2), + pgpLocLinkReady => pgpLocLinkReady(2), + pgpRemLinkReady => pgpRemLinkReady(2), + cntReset => cntReset, + pgpCntCellError => pgpCntCellErrorC, + pgpCntLinkDown => pgpCntLinkDownC, + pgpCntLinkError => pgpCntLinkErrorC, + pgpRxFifoErr => pgpRxFifoErr(2), + pgpRxCnt => pgpRxCntC, + laneNumber => "10", + vcFrameRxSOF => vcFrameRxSOF(2), + vcFrameRxEOF => vcFrameRxEOF(2), + vcFrameRxEOFE => vcFrameRxEOFE(2), + vcFrameRxData => vcFrameRxDataC, + vcFrameRxReq => vcFrameRxReq(2), + vcFrameRxValid => vcFrameRxValid(2), + vcFrameRxReady => vcFrameRxReady(2), + vcFrameRxWidth => vcFrameRxWidthC, + vcFrameTxVc => vcFrameTxVc, + vcFrameTxValid => vcFrameTxValid(2), + vcFrameTxReady => vcFrameTxReady(2), + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcRemBuffAFull => vcRemBuffAFull(11 downto 8), + vcRemBuffFull => vcRemBuffFull(11 downto 8), + mgtLoopback => mgtLoopback(2), + mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, + mgtRxN => mgtRxN(2), + mgtRxP => mgtRxP(2), + mgtTxN => mgtTxN(2), + mgtTxP => mgtTxP(2), + mgtCombusIn => mgtCombusOutD, + mgtCombusOut => mgtCombusOutC, + debug => open + ); + + + -- Lane D + U_Pgp2RceLaneD: Pgp2RcePackage.Pgp2RceLane + generic map ( + MgtMode => "B", + RefClkSel => RefClkSel + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pllTxRst => pllTxRst(3), + pllRxRst => pllRxRst(3), + pllRxReady => pllRxReady(3), + pllTxReady => pllTxReady(3), + pgpLocLinkReady => pgpLocLinkReady(3), + pgpRemLinkReady => pgpRemLinkReady(3), + cntReset => cntReset, + pgpCntCellError => pgpCntCellErrorD, + pgpCntLinkDown => pgpCntLinkDownD, + pgpCntLinkError => pgpCntLinkErrorD, + pgpRxFifoErr => pgpRxFifoErr(3), + pgpRxCnt => pgpRxCntD, + laneNumber => "11", + vcFrameRxSOF => vcFrameRxSOF(3), + vcFrameRxEOF => vcFrameRxEOF(3), + vcFrameRxEOFE => vcFrameRxEOFE(3), + vcFrameRxData => vcFrameRxDataD, + vcFrameRxReq => vcFrameRxReq(3), + vcFrameRxValid => vcFrameRxValid(3), + vcFrameRxReady => vcFrameRxReady(3), + vcFrameRxWidth => vcFrameRxWidthD, + vcFrameTxVc => vcFrameTxVc, + vcFrameTxValid => vcFrameTxValid(3), + vcFrameTxReady => vcFrameTxReady(3), + vcFrameTxSOF => vcFrameTxSOF, + vcFrameTxEOF => vcFrameTxEOF, + vcFrameTxEOFE => vcFrameTxEOFE, + vcFrameTxData => vcFrameTxData, + vcRemBuffAFull => vcRemBuffAFull(15 downto 12), + vcRemBuffFull => vcRemBuffFull(15 downto 12), + mgtLoopback => mgtLoopback(3), + mgtRefClk1 => pgpRefClk1, + mgtRefClk2 => pgpRefClk2, + mgtRxN => mgtRxN(3), + mgtRxP => mgtRxP(3), + mgtTxN => mgtTxN(3), + mgtTxP => mgtTxP(3), + mgtCombusIn => mgtCombusOutC, + mgtCombusOut => mgtCombusOutD, + debug => open + ); + end generate; + + + -- Disable upper two lanes + Pgp2UpperDis: if ( PgpLaneCnt = 2 ) generate + + -- Lane C + pllRxReady(2) <= '0'; + pllTxReady(2) <= '0'; + pgpLocLinkReady(2) <= '0'; + pgpRemLinkReady(2) <= '0'; + pgpCntCellErrorC <= (others=>'0'); + pgpCntLinkDownC <= (others=>'0'); + pgpCntLinkErrorC <= (others=>'0'); + pgpRxFifoErr(2) <= '0'; + pgpRxCntC <= (others=>'0'); + vcFrameRxSOF(2) <= '0'; + vcFrameRxEOF(2) <= '0'; + vcFrameRxEOFE(2) <= '0'; + vcFrameRxDataC <= (others=>'0'); + vcFrameRxReq(2) <= '0'; + vcFrameRxValid(2) <= '0'; + vcFrameRxWidthC <= (others=>'0'); + vcFrameTxReady(2) <= '0'; + vcRemBuffAFull(11 downto 8) <= (others=>'0'); + vcRemBuffFull(11 downto 8) <= (others=>'0'); + mgtCombusOutC <= (others=>'0'); + + -- Lane D + pllRxReady(3) <= '0'; + pllTxReady(3) <= '0'; + pgpLocLinkReady(3) <= '0'; + pgpRemLinkReady(3) <= '0'; + pgpCntCellErrorD <= (others=>'0'); + pgpCntLinkDownD <= (others=>'0'); + pgpCntLinkErrorD <= (others=>'0'); + pgpRxFifoErr(3) <= '0'; + pgpRxCntD <= (others=>'0'); + vcFrameRxSOF(3) <= '0'; + vcFrameRxEOF(3) <= '0'; + vcFrameRxEOFE(3) <= '0'; + vcFrameRxDataD <= (others=>'0'); + vcFrameRxReq(3) <= '0'; + vcFrameRxValid(3) <= '0'; + vcFrameRxWidthD <= (others=>'0'); + vcFrameTxReady(3) <= '0'; + vcRemBuffAFull(15 downto 12) <= (others=>'0'); + vcRemBuffFull(15 downto 12) <= (others=>'0'); + mgtCombusOutD <= (others=>'0'); + + end generate; + + + ----------------------------- + -- Debug + ----------------------------- + + U_icon : pgp2_v4_icon port map ( + CONTROL0 => csControl0, + CONTROL1 => csControl1 + ); + + U_ila : pgp2_v4_ila port map ( + CONTROL => csControl0, + CLK => pgpClk, + DATA => csData, + TRIG0 => csData(7 downto 0) + ); + + U_vio : pgp2_v4_vio port map ( + CONTROL => csControl1, + CLK => pgpClk, + SYNC_IN => csStat, + SYNC_OUT => csCntrl + ); + + -- Status Bits + csStat(15 downto 4) <= (others=>'0'); + csStat(3 downto 2) <= pgpRemLinkReady(1 downto 0); + csStat(1 downto 0) <= pgpLocLinkReady(1 downto 0); + + -- Control Bits + -- cntReset csCntrl(12) + -- pllTxRst csCntrl(3 downto 0) + -- pllRxRst csCntrl(7 downto 4) + -- mgtLoopback csCntrl(11 downto 8) + + -- Register chipscope signals + process ( pgpClk ) begin + if rising_edge(pgpClk) then + case csCntrl(15 downto 14) is + when "00" => csData <= importDebug after tpd; + when "01" => csData <= exportDebug after tpd; + when "10" => csData <= lane0Debug after tpd; + when others => csData <= lane1Debug after tpd; + end case; + end if; + end process; + + +end Pgp2Rce; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceExport.vhd b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceExport.vhd new file mode 100755 index 0000000000000000000000000000000000000000..ca259b2632a2f93618a7956ed1bda6032306ea20 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceExport.vhd @@ -0,0 +1,583 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, RCE Export Block +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : Pgp2RceExport.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/16/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for the interface between the PIC Export interface and +-- the PGP TX Interface. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/16/2010: created. +-- 08/24/2010: 32-bit endian swap. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2RceExport is port ( + + -- System clock & reset + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- PIC Export Interface + Export_Clock : out std_logic; + Export_Core_Reset : in std_logic; + Export_Data_Available : in std_logic; + Export_Data_Start : in std_logic; + Export_Advance_Data_Pipeline : out std_logic; + Export_Data_Last_Line : in std_logic; + Export_Data_Last_Valid_Byte : in std_logic_vector( 2 downto 0); + Export_Data : in std_logic_vector(63 downto 0); + Export_Advance_Status_Pipeline : out std_logic; + Export_Status : out std_logic_vector(31 downto 0); + Export_Status_Full : in std_logic; + + -- Remote Link Status + pgpRemLinkReady : in std_logic_vector(3 downto 0); + + -- Common Transmit Signals + vcFrameTxVc : out std_logic_vector(1 downto 0); + vcFrameTxSOF : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + + -- Transmit Control Signals, one per lane + vcFrameTxValid : out std_logic_vector(3 downto 0); + vcFrameTxReady : in std_logic_vector(3 downto 0); + + -- Remote flow control, one per lane/vc + vcRemBuffAFull : in std_logic_vector(15 downto 0); + vcRemBuffFull : in std_logic_vector(15 downto 0); + + -- Big endian mode + bigEndian : in std_logic; + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); +end Pgp2RceExport; + + +-- Define architecture +architecture Pgp2RceExport of Pgp2RceExport is + + -- Local Signals + signal pgpReady : std_logic; + signal intLinkReady : std_logic; + signal pgpTxValid0 : std_logic; + signal pgpTxSOF0 : std_logic; + signal pgpTxEOF0 : std_logic; + signal pgpTxEOFE0 : std_logic; + signal pgpTxData0 : std_logic_vector(15 downto 0); + signal pgpTxValid1 : std_logic; + signal pgpTxEOF1 : std_logic; + signal pgpTxEOFE1 : std_logic; + signal pgpTxData1 : std_logic_vector(15 downto 0); + signal pgpTxValid2 : std_logic; + signal pgpTxEOF2 : std_logic; + signal pgpTxData2 : std_logic_vector(15 downto 0); + signal pgpTxValid3 : std_logic; + signal pgpTxEOF3 : std_logic; + signal pgpTxData3 : std_logic_vector(15 downto 0); + signal expVc : std_logic_vector(1 downto 0); + signal expLane : std_logic_vector(1 downto 0); + signal expCID : std_logic_vector(23 downto 0); + signal expSOF : std_logic; + signal exportRd : std_logic; + signal exportWr : std_logic; + signal statusWr : std_logic; + signal statusBad : std_logic; + signal pgpAFull : std_logic; + signal pgpFull : std_logic; + + -- Transmit states + signal curTxState : std_logic_vector(3 downto 0); + signal nxtTxState : std_logic_vector(3 downto 0); + constant TX_IDLE : std_logic_vector(3 downto 0) := "0000"; + constant TX_VC : std_logic_vector(3 downto 0) := "0001"; + constant TX_SOF : std_logic_vector(3 downto 0) := "0010"; + constant TX_WAIT : std_logic_vector(3 downto 0) := "0011"; + constant TX_READ : std_logic_vector(3 downto 0) := "0100"; + constant TX_DUMP : std_logic_vector(3 downto 0) := "0101"; + constant TX_SBAD_A : std_logic_vector(3 downto 0) := "0110"; + constant TX_SBAD_B : std_logic_vector(3 downto 0) := "0111"; + constant TX_SOK : std_logic_vector(3 downto 0) := "1000"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Drive Export Clock and Read + Export_Clock <= pgpClk; + Export_Advance_Data_Pipeline <= exportRd; + + -- Valid to VCs + vcFrameTxValid(0) <= pgpTxValid0 when expLane = 0 else '0'; + vcFrameTxValid(1) <= pgpTxValid0 when expLane = 1 else '0'; + vcFrameTxValid(2) <= pgpTxValid0 when expLane = 2 else '0'; + vcFrameTxValid(3) <= pgpTxValid0 when expLane = 3 else '0'; + vcFrameTxVc <= expVc; + + -- VC Data + vcFrameTxSOF <= pgpTxSOF0; + vcFrameTxEOF <= pgpTxEOF0; + vcFrameTxEOFE <= pgpTxEOFE0; + vcFrameTxData <= pgpTxData0; + vcFrameTxVc <= expVc; + + -- VC Ready Signals + pgpReady <= vcFrameTxReady(conv_integer(expLane)); + + -- Link ready signal + intLinkReady <= pgpRemLinkReady(conv_integer(expLane)); + + -- Select Flow Control + pgpAFull <= vcRemBuffAFull(conv_integer(expLane & expVc)); + pgpFull <= vcRemBuffFull(conv_integer(expLane & expVc)); + + -- Pipeline for data going to PGP + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + pgpTxValid0 <= '0' after tpd; + pgpTxSOF0 <= '0' after tpd; + pgpTxEOF0 <= '0' after tpd; + pgpTxEOFE0 <= '0' after tpd; + pgpTxData0 <= (others=>'0') after tpd; + pgpTxValid1 <= '0' after tpd; + pgpTxEOF1 <= '0' after tpd; + pgpTxEOFE1 <= '0' after tpd; + pgpTxData1 <= (others=>'0') after tpd; + pgpTxValid2 <= '0' after tpd; + pgpTxEOF2 <= '0' after tpd; + pgpTxData2 <= (others=>'0') after tpd; + pgpTxValid3 <= '0' after tpd; + pgpTxEOF3 <= '0' after tpd; + pgpTxData3 <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Core reset or link down. Clear Valid + if Export_Core_Reset = '1' and intLinkReady = '0' then + pgpTxValid0 <= '0' after tpd; + pgpTxValid1 <= '0' after tpd; + pgpTxValid2 <= '0' after tpd; + pgpTxValid3 <= '0' after tpd; + + -- Data shift from Export Control + elsif exportWr = '1' then + + -- Set SOF0 + pgpTxSOF0 <= expSOF after tpd; + + -- Little endian data + if bigEndian = '0' then + pgpTxData0(7 downto 0) <= Export_Data(31 downto 24) after tpd; + pgpTxData0(15 downto 8) <= Export_Data(23 downto 16) after tpd; + pgpTxData1(7 downto 0) <= Export_Data(15 downto 8) after tpd; + pgpTxData1(15 downto 8) <= Export_Data(7 downto 0) after tpd; + pgpTxData2(7 downto 0) <= Export_Data(63 downto 56) after tpd; + pgpTxData2(15 downto 8) <= Export_Data(55 downto 48) after tpd; + pgpTxData3(7 downto 0) <= Export_Data(47 downto 40) after tpd; + pgpTxData3(15 downto 8) <= Export_Data(39 downto 32) after tpd; + + -- Big endian data + else + pgpTxData0 <= Export_Data(15 downto 0) after tpd; + pgpTxData1 <= Export_Data(31 downto 16) after tpd; + pgpTxData2 <= Export_Data(47 downto 32) after tpd; + pgpTxData3 <= Export_Data(63 downto 48) after tpd; + end if; + + -- Valid, EOF & Width Depend On Last Line/Valid Byte Flags + if Export_Data_Last_Line = '1' then + + -- Init VCs and EOF Flags + pgpTxValid0 <= '1' after tpd; + pgpTxEOF0 <= '0' after tpd; + pgpTxEOFE0 <= '0' after tpd; + pgpTxValid1 <= '1' after tpd; + pgpTxEOF2 <= '0' after tpd; + + -- Determine last transfer size + case Export_Data_Last_Valid_Byte is + when "011" => -- 32-bits + pgpTxEOF1 <= '1' after tpd; + pgpTxEOFE1 <= '0' after tpd; + pgpTxValid2 <= '0' after tpd; + pgpTxValid3 <= '0' after tpd; + pgpTxEOF3 <= '0' after tpd; + when "111" => -- 64-bits + pgpTxEOF1 <= '0' after tpd; + pgpTxEOFE1 <= '0' after tpd; + pgpTxValid2 <= '1' after tpd; + pgpTxValid3 <= '1' after tpd; + pgpTxEOF3 <= '1' after tpd; + when others => -- Invalid Alignment + pgpTxEOF1 <= '1' after tpd; + pgpTxEOFE1 <= '1' after tpd; + pgpTxValid2 <= '0' after tpd; + pgpTxValid3 <= '0' after tpd; + pgpTxEOF3 <= '0' after tpd; + end case; + + -- Normal data shift + else + pgpTxValid0 <= '1' after tpd; + pgpTxEOF0 <= '0' after tpd; + pgpTxEOFE0 <= '0' after tpd; + pgpTxValid1 <= '1' after tpd; + pgpTxEOF1 <= '0' after tpd; + pgpTxValid2 <= '1' after tpd; + pgpTxEOF2 <= '0' after tpd; + pgpTxValid3 <= '1' after tpd; + pgpTxEOF3 <= '0' after tpd; + end if; + + -- Otherwise shift data for each PGP transfer + elsif pgpTxValid0 = '1' and pgpReady = '1' then + + -- Clear SOF + pgptxSOF0 <= '0' after tpd; + + -- Shift Data + pgpTxData0 <= pgpTxData1 after tpd; + pgpTxData1 <= pgpTxData2 after tpd; + pgpTxData2 <= pgpTxData3 after tpd; + pgpTxData3 <= (others=>'0') after tpd; + + -- Shift Valid + pgpTxValid0 <= pgpTxValid1 after tpd; + pgpTxValid1 <= pgpTxValid2 after tpd; + pgpTxValid2 <= pgpTxValid3 after tpd; + pgpTxValid3 <= '0' after tpd; + + -- Shift EOF + pgpTxEOF0 <= pgpTxEOF1 after tpd; + pgpTxEOF1 <= pgpTxEOF2 after tpd; + pgpTxEOF2 <= pgpTxEOF3 after tpd; + pgpTxEOF3 <= '0' after tpd; + + -- Shift EOFE + pgpTxEOFE0 <= pgpTxEOFE1 after tpd; + pgpTxEOFE1 <= '0' after tpd; + end if; + end if; + end process; + + + -- State machine to control read from PIC Interface + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + curTxState <= TX_IDLE after tpd; + expVc <= (others=>'0') after tpd; + expLane <= (others=>'0') after tpd; + expCID <= (others=>'0') after tpd; + Export_Advance_Status_Pipeline <= '0' after tpd; + Export_Status <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Reset state on protocol reset or link down + if Export_Core_Reset = '1' then + curTxState <= TX_IDLE after tpd; + else + curTxState <= nxtTxState after tpd; + end if; + + -- Store CID, VC, Lane + if expSOF = '1' then + + -- Little endian + if bigEndian = '0' then + expCID(23 downto 16) <= Export_Data(7 downto 0) after tpd; + expCID(15 downto 8) <= Export_Data(15 downto 8) after tpd; + expCID(7 downto 0) <= Export_Data(23 downto 16) after tpd; + expVc <= Export_Data(25 downto 24) after tpd; + expLane <= Export_Data(31 downto 30) after tpd; + + -- Big endian + else + expCID <= Export_Data(31 downto 8) after tpd; + expVc <= Export_Data(1 downto 0) after tpd; + expLane <= Export_Data(7 downto 6) after tpd; + end if; + end if; + + -- Status Write + Export_Advance_Status_Pipeline <= statusWr after tpd; + Export_Status(31 downto 8) <= expCID after tpd; + Export_Status(7 downto 2) <= (others=>'0') after tpd; + Export_Status(1) <= statusBad after tpd; + Export_Status(0) <= statusBad after tpd; + end if; + end process; + + + -- Combinitorial transmit state logic + process ( curTxState, Export_Data_Available, Export_Data_Start, pgpReset, + Export_Data_Last_Line, Export_Core_Reset, pgpTxValid0, pgpTxValid1, + pgpReady, pgpAFull, pgpFull, Export_Status_Full, intLinkReady ) begin + + case curTxState is + + -- Idle, Ready to read first cell from PIC + when TX_IDLE => + + -- No Write + exportWr <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '0'; + + -- Wait for start indication from PIC, Wait for PGP shift to be idle. + if Export_Core_Reset = '0' and pgpReset = '0' and pgpTxValid0 = '0' and + Export_Data_Start = '1' and Export_Data_Available = '1' then + exportRd <= '1'; + nxtTxState <= TX_VC; + else + exportRd <= '0'; + nxtTxState <= curTxState; + end if; + + -- Register VC, Lane and CID + when TX_VC => + + -- No read or write + exportRd <= '0'; + exportWr <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '1'; + + -- Go to SOF state + nxtTxState <= TX_SOF; + + -- Transfer SOF + when TX_SOF => + + -- No read + exportRd <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '1'; + + -- Link is down for selected lane + if intLinkReady = '0' then + exportWr <= '0'; + nxtTxState <= TX_DUMP; + + -- PGP Almost Full Flag is asserted, pause + elsif pgpAFull = '1' then + exportWr <= '0'; + nxtTxState <= curTxState; + + -- Output of shift register is empty + elsif pgpTxValid0 = '0' then + nxtTxState <= TX_WAIT; + exportWr <= '1'; + + -- Wait + else + nxtTxState <= curTxState; + exportWr <= '0'; + end if; + + -- Write just occured to shift register. Wait for next data + -- to be available on PIC export. Also check for last line. + when TX_WAIT => + + -- No Write + exportWr <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '0'; + + -- Link is down for selected lane + if intLinkReady = '0' then + exportRd <= '0'; + nxtTxState <= TX_DUMP; + + -- Last byte was sent + elsif Export_Data_Last_Line = '1' then + exportRd <= '0'; + nxtTxState <= TX_SOK; + + -- Next data is ready + elsif Export_Data_Available = '1' then + exportRd <= '1'; + nxtTxState <= TX_READ; + + -- Wait + else + exportRd <= '0'; + nxtTxState <= curTxState; + end if; + + -- Data read from PIC Interface + -- Wait for shift of PGP data before writing to shift register + when TX_READ => + + -- No Read + exportRd <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '0'; + + -- Link is down for selected lane + if intLinkReady = '0' then + exportWr <= '0'; + nxtTxState <= TX_DUMP; + + -- Output of shift register is empty + -- or 2nd stage is empty and shift is about to occur + elsif pgpTxValid0 = '0' or (pgpTxValid1 = '0' and pgpReady = '1') then + + -- Full flag is asserted, pause + if pgpFull = '1' then + exportWr <= '0'; + nxtTxState <= curTxState; + else + exportWr <= '1'; + nxtTxState <= TX_WAIT; + end if; + else + exportWr <= '0'; + nxtTxState <= curTxState; + end if; + + -- Dump Data + when TX_DUMP => + + -- No Write + exportWr <= '0'; + statusWr <= '0'; + statusBad <= '0'; + expSOF <= '0'; + + -- Last byte was sent + if Export_Data_Last_Line = '1' then + exportRd <= '0'; + nxtTxState <= TX_SBAD_A; + + -- Next data is ready + elsif Export_Data_Available = '1' then + exportRd <= '1'; + nxtTxState <= curTxState; + + -- Wait + else + exportRd <= '0'; + nxtTxState <= curTxState; + end if; + + -- Write bad status, word 0 + when TX_SBAD_A => + + -- No Write or Read + exportWr <= '0'; + exportRd <= '0'; + expSOF <= '0'; + statusBad <= '1'; + + -- Wait for status to be ready + if Export_Status_Full = '0' then + statusWr <= '1'; + nxtTxState <= TX_SBAD_B; + else + statusWr <= '0'; + nxtTxState <= curTxState; + end if; + + -- Write bad status, word 1 + when TX_SBAD_B => + + -- No Write or Read + exportWr <= '0'; + exportRd <= '0'; + expSOF <= '0'; + statusBad <= '1'; + + -- Wait for status to be ready + if Export_Status_Full = '0' then + statusWr <= '1'; + nxtTxState <= TX_IDLE; + else + statusWr <= '0'; + nxtTxState <= curTxState; + end if; + + -- Write ok status + when TX_SOK => + + -- No Write or Read + exportWr <= '0'; + exportRd <= '0'; + expSOF <= '0'; + statusBad <= '0'; + + -- Wait for status to be ready + if Export_Status_Full = '0' then + statusWr <= '1'; + nxtTxState <= TX_IDLE; + else + statusWr <= '0'; + nxtTxState <= curTxState; + end if; + + when others => + expSOF <= '0'; + exportWr <= '0'; + statusWr <= '0'; + statusBad <= '0'; + exportRd <= '0'; + nxtTxState <= TX_IDLE; + end case; + end process; + + -- Debug + debug(63 downto 56) <= Export_Data(7 downto 0); + debug(55 downto 48) <= vcRemBuffAFull(7 downto 0); + debug(47 downto 40) <= vcRemBuffFull(7 downto 0); + debug(39 downto 36) <= pgpRemLinkReady; + debug(35 downto 32) <= vcFrameTxReady; + debug(31) <= pgpTxValid0; + debug(30) <= pgpTxSOF0; + debug(29) <= pgpTxEOF0; + debug(28) <= pgpTxEOFE0; + debug(27) <= pgpTxValid1; + debug(26) <= pgpTxEOF1; + debug(25) <= pgpTxEOFE1; + debug(24) <= pgpTxValid2; + debug(23) <= pgpTxEOF2; + debug(22) <= pgpTxValid3; + debug(21) <= pgpTxEOF3; + debug(20) <= expSOF; + debug(19) <= pgpAFull; + debug(18) <= pgpFull; + debug(17 downto 16) <= expVc; + debug(15 downto 14) <= expLane; + debug(13) <= Export_Status_Full; + debug(12) <= Export_Data_Last_Line; + debug(11 downto 9) <= Export_Data_Last_Valid_Byte; + debug(8) <= pgpReady; + debug(7) <= intLinkReady; + debug(6) <= statusBad; + debug(5) <= statusWr; + debug(4) <= exportWr; + debug(3) <= exportRd; + debug(2) <= Export_Data_Start; + debug(1) <= Export_Core_Reset; + debug(0) <= Export_Data_Available; + +end Pgp2RceExport; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceImport.vhd b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceImport.vhd new file mode 100755 index 0000000000000000000000000000000000000000..edc63c63fbaa0b6c472ffc72c5388232c521c4b4 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceImport.vhd @@ -0,0 +1,457 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, RCE Import Block +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : Pgp2RceImport.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 09/17/2007 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for the interface between the PIC Import interface and +-- the PGP RX Interface. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/16/2010: created. +-- 07/06/2010: Added payload count as generic. +-- 08/24/2010: 32-bit endian swap. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +USE work.Pgp2CorePackage.all; + +entity Pgp2RceImport is + generic ( + FreeListA : natural := 1; -- Free List For Lane 0 + FreeListB : natural := 2; -- Free List For Lane 1 + FreeListC : natural := 3; -- Free List For Lane 2 + FreeListD : natural := 4; -- Free List For Lane 3 + PayloadCntTop : integer := 7 -- Top bit for payload counter + ); + port ( + + -- System clock & reset + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- Import Interface + Import_Clock : out std_logic; + Import_Core_Reset : in std_logic; + Import_Free_List : out std_logic_vector( 3 downto 0); + Import_Advance_Data_Pipeline : out std_logic; + Import_Data_Last_Line : out std_logic; + Import_Data_Last_Valid_Byte : out std_logic_vector( 2 downto 0); + Import_Data : out std_logic_vector(63 downto 0); + Import_Data_Pipeline_Full : in std_logic; + Import_Pause : in std_logic; + + -- Link states + pgpLocLinkReady : in std_logic_vector(3 downto 0); + + -- Lane Receive Signals + vcFrameRxSOF : in std_logic_vector(3 downto 0); + vcFrameRxEOF : in std_logic_vector(3 downto 0); + vcFrameRxEOFE : in std_logic_vector(3 downto 0); + vcFrameRxDataA : in std_logic_vector(63 downto 0); + vcFrameRxDataB : in std_logic_vector(63 downto 0); + vcFrameRxDataC : in std_logic_vector(63 downto 0); + vcFrameRxDataD : in std_logic_vector(63 downto 0); + vcFrameRxReq : in std_logic_vector(3 downto 0); + vcFrameRxValid : in std_logic_vector(3 downto 0); + vcFrameRxReady : out std_logic_vector(3 downto 0); + vcFrameRxWidthA : in std_logic_vector(1 downto 0); + vcFrameRxWidthB : in std_logic_vector(1 downto 0); + vcFrameRxWidthC : in std_logic_vector(1 downto 0); + vcFrameRxWidthD : in std_logic_vector(1 downto 0); + + -- Big endian mode + bigEndian : in std_logic; + + -- Debug + debug : out std_logic_vector(63 downto 0) + ); +end Pgp2RceImport; + + +-- Define architecture +architecture Pgp2RceImport of Pgp2RceImport is + + -- Local Signals + signal intFrameRxSOF : std_logic; + signal intFrameRxEOF : std_logic; + signal intFrameRxEOFE : std_logic; + signal intFrameRxData : std_logic_vector(63 downto 0); + signal intFrameRxValid : std_logic; + signal intFrameRxWidth : std_logic_vector(1 downto 0); + signal intLocLinkReady : std_logic; + signal curSource : std_logic_vector(1 downto 0); + signal nxtSource : std_logic_vector(1 downto 0); + signal arbSource : std_logic_vector(1 downto 0); + signal userStatus : std_logic_vector(15 downto 0); + signal dataEn : std_logic; + signal statusEn : std_logic; + signal lastEn : std_logic; + signal firstEn : std_logic; + signal curWidthErr : std_logic; + signal curEofeErr : std_logic; + signal curLinkErr : std_logic; + signal nxtLinkErr : std_logic; + signal cellCount : std_logic_vector(PayloadCntTop downto 2); + signal importAdvance : std_logic; + signal importLast : std_logic; + signal importLastValid : std_logic_vector(2 downto 0); + signal importFreeList : std_logic_vector(3 downto 0); + signal importData : std_logic_vector(63 downto 0); + + -- Receive states + signal curState : std_logic_vector(1 downto 0); + signal nxtState : std_logic_vector(1 downto 0); + constant ST_IDLE : std_logic_vector(1 downto 0) := "00"; + constant ST_SOC : std_logic_vector(1 downto 0) := "01"; + constant ST_DATA : std_logic_vector(1 downto 0) := "10"; + constant ST_STATUS : std_logic_vector(1 downto 0) := "11"; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Outgoing clock + Import_Clock <= pgpClk; + + -- Decode lane selection + intFrameRxSOF <= vcFrameRxSOF(conv_integer(curSource)); + intFrameRxEOF <= vcFrameRxEOF(conv_integer(curSource)); + intFrameRxEOFE <= vcFrameRxEOFE(conv_integer(curSource)); + intFrameRxValid <= vcFrameRxValid(conv_integer(curSource)); + + -- Ready outputs + vcFrameRxReady(0) <= dataEn when curSource = 0 else '0'; + vcFrameRxReady(1) <= dataEn when curSource = 1 else '0'; + vcFrameRxReady(2) <= dataEn when curSource = 2 else '0'; + vcFrameRxReady(3) <= dataEn when curSource = 3 else '0'; + + -- Data input + intFrameRxData <= vcFrameRxDataA when curSource = 0 else + vcFrameRxDataB when curSource = 1 else + vcFrameRxDataC when curSource = 2 else + vcFrameRxDataD; + + -- Width input + intFrameRxWidth <= vcFrameRxWidthA when curSource = 0 else + vcFrameRxWidthB when curSource = 1 else + vcFrameRxWidthC when curSource = 2 else + vcFrameRxWidthD; + + -- PIC Signals + Import_Advance_Data_Pipeline <= importAdvance; + Import_Data_Last_Line <= importLast; + Import_Data_Last_Valid_Byte <= importLastValid; + Import_Free_List <= importFreeList; + Import_Data <= importData; + + -- Sync state + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + curState <= ST_IDLE after tpd; + curSource <= "00" after tpd; + importAdvance <= '0' after tpd; + importLast <= '0' after tpd; + importLastValid <= "000" after tpd; + importFreeList <= (others=>'0') after tpd; + importData <= (others=>'0') after tpd; + userStatus <= (others=>'0') after tpd; + curWidthErr <= '0' after tpd; + curEofeErr <= '0' after tpd; + curLinkErr <= '0' after tpd; + cellCount <= (others=>'0') after tpd; + intLocLinkReady <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Link ready of current source + intLocLinkReady <= pgpLocLinkReady(conv_integer(curSource)) after tpd; + + -- Arbiter reset + if Import_Core_Reset = '1' then + curState <= ST_IDLE after tpd; + curSource <= "00" after tpd; + else + curState <= nxtState after tpd; + curSource <= nxtSource after tpd; + end if; + + -- Output signals + importAdvance <= dataEn or statusEn or firstEn after tpd; + importLast <= lastEn after tpd; + importLastValid <= "1" & intFrameRxWidth after tpd; + + -- Free list selection + if firstEn = '1' then + importFreeList(3 downto 2) <= (others=>'0') after tpd; + importFreeList(1 downto 0) <= curSource after tpd; + else + case (curSource) is + when "00" => importFreeList <= conv_std_logic_vector(FreeListA,4) after tpd; + when "01" => importFreeList <= conv_std_logic_vector(FreeListB,4) after tpd; + when "10" => importFreeList <= conv_std_logic_vector(FreeListC,4) after tpd; + when "11" => importFreeList <= conv_std_logic_vector(FreeListD,4) after tpd; + when others => importFreeList <= (others=>'0') after tpd; + end case; + end if; + + -- Select Data + if firstEn = '1' then + importData <= (others=>'0') after tpd; + + -- Data + elsif dataEn = '1' then + + -- Little endian + if bigEndian = '0' then + importData(63 downto 56) <= intFrameRxData(39 downto 32) after tpd; + importData(55 downto 48) <= intFrameRxData(47 downto 40) after tpd; + importData(47 downto 40) <= intFrameRxData(55 downto 48) after tpd; + importData(39 downto 32) <= intFrameRxData(63 downto 56) after tpd; + importData(31 downto 24) <= intFrameRxData(7 downto 0) after tpd; + importData(23 downto 16) <= intFrameRxData(15 downto 8) after tpd; + importData(15 downto 8) <= intFrameRxData(23 downto 16) after tpd; + importData(7 downto 0) <= intFrameRxData(31 downto 24) after tpd; + + -- Big endian + else + importData <= intFrameRxData after tpd; + end if; + + -- Status + elsif statusEn = '1' then + importData(63 downto 32) <= (others=>'0') after tpd; + importData(31 downto 16) <= userStatus after tpd; + importData(15 downto 4) <= (others=>'0') after tpd; + importData(3) <= curLinkErr after tpd; + importData(2) <= curWidthErr after tpd; + importData(1) <= curEofeErr after tpd; + + -- User status + if userStatus /= 0 then + importData(5) <= '1' after tpd; + else + importData(5) <= '0' after tpd; + end if; + + -- Error bit + if userStatus /= 0 or curLinkErr = '1' or + curWidthErr = '1' or curEofeErr = '1' then + importData(0) <= '1' after tpd; + else + importData(0) <= '0' after tpd; + end if; + end if; + + -- CELL Counter + if firstEn = '1' then + cellCount <= (others=>'1') after tpd; + elsif dataEn = '1' then + cellCount <= cellCount - 1 after tpd; + end if; + + -- Last line, store status + if lastEn = '1' then + if intFrameRxWidth(1) = '0' then + userStatus <= intFrameRxData(31 downto 16) after tpd; + else + userStatus <= intFrameRxData(63 downto 48) after tpd; + end if; + curWidthErr <= not intFrameRxWidth(0) after tpd; + curEOFEErr <= intFrameRxEOFE after tpd; + end if; + + -- SOF error + curLinkErr <= nxtLinkErr after tpd; + end if; + end process; + + + -- State transition + process ( curState, curSource, arbSource, vcFrameRxReq, Import_Pause, + Import_Data_Pipeline_Full, intLocLinkReady, cellCount, Import_Core_Reset, + intFrameRxEOF, intFrameRxValid, curLinkErr ) begin + + case curState is + + -- Idle, New Request + when ST_IDLE => + dataEn <= '0'; + statusEn <= '0'; + lastEn <= '0'; + firstEn <= '0'; + nxtLinkErr <= '0'; + + -- New requester + if Import_Core_Reset = '0' and vcFrameRxReq /= 0 then + nxtSource <= arbSource; + nxtState <= ST_SOC; + else + nxtSource <= curSource; + nxtState <= curState; + end if; + + -- Start of cell, write blank data and VC value + when ST_SOC => + dataEn <= '0'; + lastEn <= '0'; + nxtLinkErr <= '0'; + statusEn <= '0'; + nxtSource <= curSource; + + -- Link is lost on selected channel + if intLocLinkReady = '0' then + firstEn <= '0'; + nxtState <= ST_IDLE; + + -- Data is ready and pipeline is ready + elsif Import_Pause = '0' and Import_Data_Pipeline_Full = '0' then + firstEn <= '1'; + nxtState <= ST_DATA; + else + firstEn <= '0'; + nxtState <= curState; + end if; + + -- Read Data + when ST_DATA => + firstEn <= '0'; + statusEn <= '0'; + nxtSource <= curSource; + + -- Link is lost on selected channel + if intLocLinkReady = '0' then + nxtLinkErr <= '1'; + dataEn <= '1'; + lastEn <= '1'; + nxtState <= ST_STATUS; + + -- Data is ready and pipeline is ready + elsif Import_Pause = '0' and Import_Data_Pipeline_Full = '0' and intFrameRxValid = '1' then + nxtLinkErr <= '0'; + dataEn <= '1'; + + -- Last line is set + if intFrameRxEOF = '1' then + lastEn <= '1'; + nxtState <= ST_STATUS; + + -- Last word of cell + elsif cellCount = 0 then + lastEn <= '0'; + nxtState <= ST_IDLE; + else + lastEn <= '0'; + nxtState <= curState; + end if; + else + nxtLinkErr <= '0'; + dataEn <= '0'; + lastEn <= '0'; + nxtState <= curState; + end if; + + -- Status Write + when ST_STATUS => + nxtLinkErr <= curLinkErr; + nxtSource <= curSource; + dataEn <= '0'; + lastEn <= '0'; + firstEn <= '0'; + + -- Data is ready and pipeline is ready + if Import_Data_Pipeline_Full = '0' then + statusEn <= '1'; + nxtState <= ST_IDLE; + else + statusEn <= '0'; + nxtState <= curState; + end if; + + -- Default + when others => + nxtLinkErr <= '0'; + nxtSource <= "00"; + dataEn <= '0'; + lastEn <= '0'; + firstEn <= '0'; + statusEn <= '0'; + nxtState <= ST_IDLE; + end case; + end process; + + + -- Block to determine next data source + process ( curSource, vcFrameRxReq ) begin + case curSource is + when "00" => + if vcFrameRxReq(1) = '1' then arbSource <= "01"; + elsif vcFrameRxReq(2) = '1' then arbSource <= "10"; + elsif vcFrameRxReq(3) = '1' then arbSource <= "11"; + elsif vcFrameRxReq(0) = '1' then arbSource <= "00"; + else arbSource <= "00"; end if; + when "01" => + if vcFrameRxReq(2) = '1' then arbSource <= "10"; + elsif vcFrameRxReq(3) = '1' then arbSource <= "11"; + elsif vcFrameRxReq(0) = '1' then arbSource <= "00"; + elsif vcFrameRxReq(1) = '1' then arbSource <= "01"; + else arbSource <= "00"; end if; + when "10" => + if vcFrameRxReq(3) = '1' then arbSource <= "11"; + elsif vcFrameRxReq(0) = '1' then arbSource <= "00"; + elsif vcFrameRxReq(1) = '1' then arbSource <= "01"; + elsif vcFrameRxReq(2) = '1' then arbSource <= "10"; + else arbSource <= "00"; end if; + when "11" => + if vcFrameRxReq(0) = '1' then arbSource <= "00"; + elsif vcFrameRxReq(1) = '1' then arbSource <= "01"; + elsif vcFrameRxReq(2) = '1' then arbSource <= "10"; + elsif vcFrameRxReq(3) = '1' then arbSource <= "11"; + else arbSource <= "00"; end if; + when others => arbSource <= "00"; + end case; + end process; + + -- Debug + debug(63 downto 56) <= importData(7 downto 0); + debug(55 downto 52) <= vcFrameRxReq; + debug(51 downto 48) <= vcFrameRxEOFE; + debug(47 downto 44) <= vcFrameRxEOF; + debug(43 downto 40) <= vcFrameRxSOF; + debug(39 downto 36) <= vcFrameRxValid; + debug(35) <= intFrameRxEOFE; + debug(34) <= Import_Data_Pipeline_Full; + debug(33) <= Import_Pause; + debug(32 downto 29) <= pgpLocLinkReady; + debug(28 downto 27) <= userStatus(1 downto 0); + debug(26 downto 23) <= importFreeList; + debug(22 downto 20) <= importLastValid; + debug(19 downto 18) <= intFrameRxWidth; + debug(17) <= intLocLinkReady; + debug(16) <= curLinkErr; + debug(15) <= curEofeErr; + debug(14) <= curWidthErr; + debug(13) <= firstEn; + debug(12) <= lastEn; + debug(11) <= statusEn; + debug(10) <= dataEn; + debug(9 downto 8) <= curSource; + debug(7) <= intFrameRxValid; + debug(6) <= Import_Core_Reset; + debug(5) <= intFrameRxEOF; + debug(4) <= intFrameRxSOF; + debug(3 downto 2) <= curState; + debug(1) <= importLast; + debug(0) <= importAdvance; + +end Pgp2RceImport; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceLane.vhd b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceLane.vhd new file mode 100755 index 0000000000000000000000000000000000000000..5fe78e16cddaffcf55f3046b8d6379e1cec53dbb --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RceLane.vhd @@ -0,0 +1,462 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, RCE Lane +-- Project : Reconfigurable Cluster Element +------------------------------------------------------------------------------- +-- File : Pgp2RceLane.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 01/14/2010 +------------------------------------------------------------------------------- +-- Description: +-- VHDL source file for RCE lane interface. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 01/14/2010: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +use work.all; +use work.Pgp2MgtPackage.all; +--use work.Pgp2TbPackage.all; -- For Simulation +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity Pgp2RceLane is + generic ( + MgtMode : string := "A"; + RefClkSel : string := "REFCLK1" + ); port ( + + -- Clock and reset + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- PGP Status + pllTxRst : in std_logic; + pllRxRst : in std_logic; + pllRxReady : out std_logic; + pllTxReady : out std_logic; + pgpLocLinkReady : out std_logic; + pgpRemLinkReady : out std_logic; + + -- PGP Counters + cntReset : in std_logic; + pgpCntCellError : out std_logic_vector(3 downto 0); + pgpCntLinkDown : out std_logic_vector(3 downto 0); + pgpCntLinkError : out std_logic_vector(3 downto 0); + pgpRxFifoErr : out std_logic; + pgpRxCnt : out std_logic_vector(3 downto 0); + + -- Lane Number for header + laneNumber : in std_logic_vector(1 downto 0); + + -- VC Receive Signals + vcFrameRxSOF : out std_logic; + vcFrameRxEOF : out std_logic; + vcFrameRxEOFE : out std_logic; + vcFrameRxData : out std_logic_vector(63 downto 0); + vcFrameRxReq : out std_logic; + vcFrameRxValid : out std_logic; + vcFrameRxReady : in std_logic; + vcFrameRxWidth : out std_logic_vector(1 downto 0); + + -- VC Transmit Signals + vcFrameTxVc : in std_logic_vector(1 downto 0); + vcFrameTxValid : in std_logic; + vcFrameTxReady : out std_logic; + vcFrameTxSOF : in std_logic; + vcFrameTxEOF : in std_logic; + vcFrameTxEOFE : in std_logic; + vcFrameTxData : in std_logic_vector(15 downto 0); + + -- Remote flow control + vcRemBuffAFull : out std_logic_vector(3 downto 0); + vcRemBuffFull : out std_logic_vector(3 downto 0); + + -- MGT Signals + mgtLoopback : in std_logic; + mgtRefClk1 : in std_logic; + mgtRefClk2 : in std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0); + + -- Debug + debug : out std_logic_vector(63 downto 0) + + ); +end Pgp2RceLane; + + +-- Define architecture +architecture Pgp2RceLane of Pgp2RceLane is + + -- Receive FIFO + component pgp2_v4_fifo_69x512 + port ( + clk: IN std_logic; + rst: IN std_logic; + din: IN std_logic_VECTOR(68 downto 0); + wr_en: IN std_logic; + rd_en: IN std_logic; + dout: OUT std_logic_VECTOR(68 downto 0); + full: OUT std_logic; + empty: OUT std_logic; + data_count: OUT std_logic_VECTOR(8 downto 0) + ); + end component; + + -- Local Signals + signal pgpRxCellError : std_logic; + signal pgpRxLinkDown : std_logic; + signal pgpRxLinkError : std_logic; + signal currVc : std_logic_vector(1 downto 0); + signal intCntCellError : std_logic_vector(3 downto 0); + signal intCntLinkDown : std_logic_vector(3 downto 0); + signal intCntLinkError : std_logic_vector(3 downto 0); + signal intCntRx : std_logic_vector(3 downto 0); + signal vcLocBuffAFull : std_logic; + signal vcLocBuffFull : std_logic; + signal intFrameTxValid : std_logic_vector(3 downto 0); + signal intFrameTxReady : std_logic_vector(3 downto 0); + signal intLocLinkReady : std_logic; + signal intFrameRxSOF : std_logic; + signal intFrameRxEOF : std_logic; + signal intFrameRxEOFE : std_logic; + signal intFrameRxData : std_logic_vector(15 downto 0); + signal intFrameRxValid : std_logic_vector(3 downto 0); + signal fifoWrData : std_logic_vector(68 downto 0); + signal fifoWrEn : std_logic; + signal fifoRdEn : std_logic; + signal fifoRdEnDly : std_logic; + signal fifoRdData : std_logic_vector(68 downto 0); + signal fifoFull : std_logic; + signal fifoRst : std_logic; + signal fifoEmpty : std_logic; + signal fifoCount : std_logic_vector(8 downto 0); + signal fifoWrCnt : std_logic_vector(1 downto 0); + signal fifoEofCnt : std_logic_vector(8 downto 0); + signal fifoEofRd : std_logic; + signal fifoEofWr : std_logic; + signal intValid : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output counters + pgpCntCellError <= intCntCellError; + pgpCntLinkDown <= intCntLinkDown; + pgpCntLinkError <= intCntLinkError; + pgpRxCnt <= intCntRx; + + -- Link status + pgpLocLinkReady <= intLocLinkReady; + + -- Decode VC valid + intFrameTxValid(0) <= vcFrameTxValid when vcFrameTxVc = 0 else '0'; + intFrameTxValid(1) <= vcFrameTxValid when vcFrameTxVc = 1 else '0'; + intFrameTxValid(2) <= vcFrameTxValid when vcFrameTxVc = 2 else '0'; + intFrameTxValid(3) <= vcFrameTxValid when vcFrameTxVc = 3 else '0'; + + -- MUX VC ready + vcFrameTxReady <= intFrameTxReady(0) when vcFrameTxVc = 0 else + intFrameTxReady(1) when vcFrameTxVc = 1 else + intFrameTxReady(2) when vcFrameTxVc = 2 else + intFrameTxReady(3) when vcFrameTxVc = 3 else '0'; + + -- Encode VC + currVc <= "00" when intFrameRxValid(0) = '1' else + "01" when intFrameRxValid(1) = '1' else + "10" when intFrameRxValid(2) = '1' else + "11"; + + -- Error Counters + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intCntCellError <= (others=>'0') after tpd; + intCntLinkDown <= (others=>'0') after tpd; + intCntLinkError <= (others=>'0') after tpd; + intCntRx <= (others=>'0') after tpd; + elsif rising_edge(pgpClk) then + + -- Cell error counter + if cntReset = '1' then + intCntCellError <= (others=>'0') after tpd; + elsif pgpRxCellError = '1' and intCntCellError /= x"F" then + intCntCellError <= intCntCellError + 1 after tpd; + end if; + + -- Link error counter + if cntReset = '1' then + intCntLinkError <= (others=>'0') after tpd; + elsif pgpRxLinkError = '1' and intCntLinkError /= x"F" then + intCntLinkError <= intCntLinkError + 1 after tpd; + end if; + + -- Link down counter + if cntReset = '1' then + intCntLinkDown <= (others=>'0') after tpd; + elsif pgpRxLinkDown = '1' and intCntLinkDown /= x"F" then + intCntLinkDown <= intCntLinkDown + 1 after tpd; + end if; + + -- Rx Counter + if cntReset = '1' then + intCntRx <= (others=>'0') after tpd; + elsif intFrameRxValid /= 0 and intFrameRxEOF = '1' then + intCntRx <= intCntRx + 1 after tpd; + end if; + + end if; + end process; + + + -- Receive Buffer Writes + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + fifoWrData <= (others=>'0') after tpd; + fifoWrEn <= '0' after tpd; + fifoWrCnt <= "00" after tpd; + vcLocBuffAFull <= '0' after tpd; + vcLocBuffFull <= '0' after tpd; + pgpRxFifoErr <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Almost full 1/4 + vcLocBuffAFull <= fifoFull or fifoCount(8) or fifoCount(7) after tpd; + + -- Full 1/2 + vcLocBuffFull <= fifoFull or fifoCount(8) after tpd; + + -- Track write errors + if fifoWrEn = '1' and fifoFull = '1' then + pgpRxFifoErr <= '1' after tpd; + elsif cntReset = '1' then + pgpRxFifoErr <= '0' after tpd; + end if; + + -- Link is down + if intLocLinkReady = '0' then + fifoWrEn <= '0' after tpd; + fifoWrCnt <= "00" after tpd; + + -- FIFO is valid + elsif intFrameRxValid /= 0 then + fifoWrData(68 downto 67) <= fifoWrCnt after tpd; + fifoWrData(66) <= intFrameRxEOFE after tpd; + fifoWrData(65) <= intFrameRxEOF after tpd; + + -- Save SOF + if fifoWrCnt = 0 then + fifoWrData(64) <= intFrameRxSOF after tpd; + end if; + + -- Which word are we on + if ( fifoWrCnt = "00" ) then + fifoWrData(15 downto 8) <= intFrameRxData(15 downto 8) after tpd; + fifoWrData(5 downto 2) <= intFrameRxData(5 downto 2) after tpd; + if intFrameRxSOF = '1' then + fifoWrData(7 downto 6) <= laneNumber after tpd; -- Overwrite Lane number in header + fifoWrData(1 downto 0) <= currVc after tpd; -- Overwrite VC number in header + else + fifoWrData(7 downto 6) <= intFrameRxData(7 downto 6) after tpd; + fifoWrData(1 downto 0) <= intFrameRxData(1 downto 0) after tpd; + end if; + end if; + if ( fifoWrCnt = "01" ) then fifoWrData(31 downto 16) <= intFrameRxData after tpd; end if; + if ( fifoWrCnt = "10" ) then fifoWrData(47 downto 32) <= intFrameRxData after tpd; end if; + if ( fifoWrCnt = "11" ) then fifoWrData(63 downto 48) <= intFrameRxData after tpd; end if; + + -- Reset on EOF + if intFrameRxEOF = '1' then + fifoWrCnt <= "00" after tpd; + else + fifoWrCnt <= fifoWrCnt + 1 after tpd; + end if; + + -- Write on EOF or count of 3 + if intFrameRxEOF = '1' or fifoWrCnt = "11" then + fifoWrEn <= '1' after tpd; + else + fifoWrEn <= '0' after tpd; + end if; + else + fifoWrEn <= '0' after tpd; + end if; + end if; + end process; + + -- FIFO reset + fifoRst <= pgpReset or not intLocLinkReady; + + -- Upstream FIFO, 2 block rams + U_UsFifo: pgp2_v4_fifo_69x512 port map ( + clk => pgpClk, + rst => fifoRst, + din => fifoWrData, + wr_en => fifoWrEn, + rd_en => fifoRdEn, + dout => fifoRdData, + full => fifoFull, + empty => fifoEmpty, + data_count => fifoCount + ); + + -- EOF read/write detect + fifoEofWr <= fifoWrEn and fifoWrData(65); + fifoEofRd <= fifoRdEnDly and fifoRdData(65); + + + -- Read control + process ( pgpClk, pgpReset ) begin + if pgpReset = '1' then + intValid <= '0' after tpd; + fifoRdEnDly <= '0' after tpd; + fifoEofCnt <= (others=>'0') after tpd; + vcFrameRxReq <= '0' after tpd; + elsif rising_edge(pgpClk) then + + -- Read occured + fifoRdEnDly <= fifoRdEn after tpd; + + -- Link is down + if intLocLinkReady = '0' then + fifoEofCnt <= (others=>'0') after tpd; + intValid <= '0' after tpd; + vcFrameRxReq <= '0' after tpd; + else + + -- EOF Counter + if fifoEofWr = '1' and fifoEofRd = '0' then + fifoEofCnt <= fifoEofCnt + 1 after tpd; + elsif fifoEofWr = '0' and fifoEofRd = '1' then + fifoEofCnt <= fifoEofCnt - 1 after tpd; + end if; + + -- Track Valid + if fifoRdEn = '1' then + intValid <= '1' after tpd; + elsif vcFrameRxReady = '1' then + intValid <= '0' after tpd; + end if; + + -- Valid output, EOF is at output or more than 1 EOF in buffer or 127 entries are in buffer + if vcFrameRxReady = '0' and intValid = '1' and + (fifoEofCnt /= 0 or fifoRdData(65) = '1' or fifoCount >= 63) then + vcFrameRxReq <= '1' after tpd; + else + vcFrameRxReq <= '0' after tpd; + end if; + end if; + end if; + end process; + + + -- Control reads + fifoRdEn <= (not fifoEmpty) and ((not intValid) or vcFrameRxReady); + + -- Outgoing signals + vcFrameRxEOFE <= fifoRdData(66); + vcFrameRxEOF <= fifoRdData(65); + vcFrameRxSOF <= fifoRdData(64); + vcFrameRxData <= fifoRdData(63 downto 0); + vcFrameRxValid <= intValid; + vcFrameRxWidth <= fifoRdData(68 downto 67); + + + -- 16-bit wrapper + U_Pgp2Mgt16: Pgp2MgtPackage.Pgp2Mgt16 + --U_Pgp2Mgt16Model: Pgp2TbPackage.Pgp2Mgt16Model -- For Simulation + generic map ( + EnShortCells => 1, + VcInterleave => 1, + MgtMode => MgtMode, + RefClkSel => RefClkSel + ) port map ( + pgpClk => pgpClk, + pgpReset => pgpReset, + pgpFlush => '0', + pllTxRst => pllTxRst, + pllRxRst => pllRxRst, + pllRxReady => pllRxReady, + pllTxReady => pllTxReady, + pgpRemData => open, + pgpLocData => (others=>'0'), + pgpTxOpCodeEn => '0', + pgpTxOpCode => (others=>'0'), + pgpRxOpCodeEn => open, + pgpRxOpCode => open, + pgpLocLinkReady => intLocLinkReady, + pgpRemLinkReady => pgpRemLinkReady, + pgpRxCellError => pgpRxCellError, + pgpRxLinkDown => pgpRxLinkDown, + pgpRxLinkError => pgpRxLinkError, + vc0FrameTxValid => intFrameTxValid(0), + vc0FrameTxReady => intFrameTxReady(0), + vc0FrameTxSOF => vcFrameTxSOF, + vc0FrameTxEOF => vcFrameTxEOF, + vc0FrameTxEOFE => vcFrameTxEOFE, + vc0FrameTxData => vcFrameTxData, + vc0LocBuffAFull => vcLocBuffAFull, + vc0LocBuffFull => vcLocBuffFull, + vc1FrameTxValid => intFrameTxValid(1), + vc1FrameTxReady => intFrameTxReady(1), + vc1FrameTxSOF => vcFrameTxSOF, + vc1FrameTxEOF => vcFrameTxEOF, + vc1FrameTxEOFE => vcFrameTxEOFE, + vc1FrameTxData => vcFrameTxData, + vc1LocBuffAFull => vcLocBuffAFull, + vc1LocBuffFull => vcLocBuffFull, + vc2FrameTxValid => intFrameTxValid(2), + vc2FrameTxReady => intFrameTxReady(2), + vc2FrameTxSOF => vcFrameTxSOF, + vc2FrameTxEOF => vcFrameTxEOF, + vc2FrameTxEOFE => vcFrameTxEOFE, + vc2FrameTxData => vcFrameTxData, + vc2LocBuffAFull => vcLocBuffAFull, + vc2LocBuffFull => vcLocBuffFull, + vc3FrameTxValid => intFrameTxValid(3), + vc3FrameTxReady => intFrameTxReady(3), + vc3FrameTxSOF => vcFrameTxSOF, + vc3FrameTxEOF => vcFrameTxEOF, + vc3FrameTxEOFE => vcFrameTxEOFE, + vc3FrameTxData => vcFrameTxData, + vc3LocBuffAFull => vcLocBuffAFull, + vc3LocBuffFull => vcLocBuffFull, + vcFrameRxSOF => intFrameRxSOF, + vcFrameRxEOF => intFrameRxEOF, + vcFrameRxEOFE => intFrameRxEOFE, + vcFrameRxData => intFrameRxData, + vc0FrameRxValid => intFrameRxValid(0), + vc0RemBuffAFull => vcRemBuffAFull(0), + vc0RemBuffFull => vcRemBuffFull(0), + vc1FrameRxValid => intFrameRxValid(1), + vc1RemBuffAFull => vcRemBuffAFull(1), + vc1RemBuffFull => vcRemBuffFull(1), + vc2FrameRxValid => intFrameRxValid(2), + vc2RemBuffAFull => vcRemBuffAFull(2), + vc2RemBuffFull => vcRemBuffFull(2), + vc3FrameRxValid => intFrameRxValid(3), + vc3RemBuffAFull => vcRemBuffAFull(3), + vc3RemBuffFull => vcRemBuffFull(3), + mgtLoopback => mgtLoopback, + mgtRefClk1 => mgtRefClk1, + mgtRefClk2 => mgtRefClk2, + mgtRxRecClk => open, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, + mgtTxN => mgtTxN, + mgtTxP => mgtTxP, + mgtCombusIn => mgtCombusIn, + mgtCombusOut => mgtCombusOut, + debug => debug + ); + +end Pgp2RceLane; + diff --git a/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RcePackage.vhd b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RcePackage.vhd new file mode 100755 index 0000000000000000000000000000000000000000..676de005bb317a80fe4e507af9ffa92f6cb2d3e2 --- /dev/null +++ b/rce/fw-hsio/modules/pgp2/hdl/rce/Pgp2RcePackage.vhd @@ -0,0 +1,196 @@ +------------------------------------------------------------------------------- +-- Title : Pretty Good Protocol, RCE Package +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : Pgp2RcePackage.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 11/23/2009 +------------------------------------------------------------------------------- +-- Description: +-- Application Components package. +------------------------------------------------------------------------------- +-- Copyright (c) 2006 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 11/23/2009: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Pgp2RcePackage is + + -- PGP Lane + component Pgp2RceLane + generic ( + MgtMode : string := "A"; + RefClkSel : string := "REFCLK1" + ); port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + pllTxRst : in std_logic; + pllRxRst : in std_logic; + pllRxReady : out std_logic; + pllTxReady : out std_logic; + pgpLocLinkReady : out std_logic; + pgpRemLinkReady : out std_logic; + cntReset : in std_logic; + pgpCntCellError : out std_logic_vector(3 downto 0); + pgpCntLinkDown : out std_logic_vector(3 downto 0); + pgpCntLinkError : out std_logic_vector(3 downto 0); + pgpRxFifoErr : out std_logic; + pgpRxCnt : out std_logic_vector(3 downto 0); + laneNumber : in std_logic_vector(1 downto 0); + vcFrameRxSOF : out std_logic; + vcFrameRxEOF : out std_logic; + vcFrameRxEOFE : out std_logic; + vcFrameRxData : out std_logic_vector(63 downto 0); + vcFrameRxReq : out std_logic; + vcFrameRxValid : out std_logic; + vcFrameRxReady : in std_logic; + vcFrameRxWidth : out std_logic_vector(1 downto 0); + vcFrameTxVc : in std_logic_vector(1 downto 0); + vcFrameTxValid : in std_logic; + vcFrameTxReady : out std_logic; + vcFrameTxSOF : in std_logic; + vcFrameTxEOF : in std_logic; + vcFrameTxEOFE : in std_logic; + vcFrameTxData : in std_logic_vector(15 downto 0); + vcRemBuffAFull : out std_logic_vector(3 downto 0); + vcRemBuffFull : out std_logic_vector(3 downto 0); + mgtLoopback : in std_logic; + mgtRefClk1 : in std_logic; + mgtRefClk2 : in std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0); + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- RCE Export Block + component Pgp2RceExport + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + Export_Clock : out std_logic; + Export_Core_Reset : in std_logic; + Export_Data_Available : in std_logic; + Export_Data_Start : in std_logic; + Export_Advance_Data_Pipeline : out std_logic; + Export_Data_Last_Line : in std_logic; + Export_Data_Last_Valid_Byte : in std_logic_vector(2 downto 0); + Export_Data : in std_logic_vector(63 downto 0); + Export_Advance_Status_Pipeline : out std_logic; + Export_Status : out std_logic_vector(31 downto 0); + Export_Status_Full : in std_logic; + pgpRemLinkReady : in std_logic_vector(3 downto 0); + vcFrameTxVc : out std_logic_vector(1 downto 0); + vcFrameTxSOF : out std_logic; + vcFrameTxEOF : out std_logic; + vcFrameTxEOFE : out std_logic; + vcFrameTxData : out std_logic_vector(15 downto 0); + vcFrameTxValid : out std_logic_vector(3 downto 0); + vcFrameTxReady : in std_logic_vector(3 downto 0); + vcRemBuffAFull : in std_logic_vector(15 downto 0); + vcRemBuffFull : in std_logic_vector(15 downto 0); + bigEndian : in std_logic; + debug : out std_logic_vector(63 downto 0) + ); + end component; + + -- RCE Import Block + component Pgp2RceImport + generic ( + FreeListA : natural := 1; + FreeListB : natural := 2; + FreeListC : natural := 3; + FreeListD : natural := 4; + PayloadCntTop : integer := 7 + ); + port ( + pgpClk : in std_logic; + pgpReset : in std_logic; + Import_Clock : out std_logic; + Import_Core_Reset : in std_logic; + Import_Free_List : out std_logic_vector( 3 downto 0); + Import_Advance_Data_Pipeline : out std_logic; + Import_Data_Last_Line : out std_logic; + Import_Data_Last_Valid_Byte : out std_logic_vector( 2 downto 0); + Import_Data : out std_logic_vector(63 downto 0); + Import_Data_Pipeline_Full : in std_logic; + Import_Pause : in std_logic; + pgpLocLinkReady : in std_logic_vector(3 downto 0); + vcFrameRxSOF : in std_logic_vector(3 downto 0); + vcFrameRxEOF : in std_logic_vector(3 downto 0); + vcFrameRxEOFE : in std_logic_vector(3 downto 0); + vcFrameRxDataA : in std_logic_vector(63 downto 0); + vcFrameRxDataB : in std_logic_vector(63 downto 0); + vcFrameRxDataC : in std_logic_vector(63 downto 0); + vcFrameRxDataD : in std_logic_vector(63 downto 0); + vcFrameRxReq : in std_logic_vector(3 downto 0); + vcFrameRxValid : in std_logic_vector(3 downto 0); + vcFrameRxReady : out std_logic_vector(3 downto 0); + vcFrameRxWidthA : in std_logic_vector(1 downto 0); + vcFrameRxWidthB : in std_logic_vector(1 downto 0); + vcFrameRxWidthC : in std_logic_vector(1 downto 0); + vcFrameRxWidthD : in std_logic_vector(1 downto 0); + bigEndian : in std_logic; + debug : out std_logic_vector(63 downto 0) + ); + end component; + + + -- RCE Wrapper + component Pgp2Rce + generic ( + FreeListA : natural := 1; + FreeListB : natural := 2; + FreeListC : natural := 3; + FreeListD : natural := 4; + RefClkSel : string := "REFCLK1"; + PgpLaneCnt : natural := 4 + ); + port ( + Import_Clock : out std_logic; + Import_Core_Reset : in std_logic; + Import_Free_List : out std_logic_vector( 3 downto 0); + Import_Advance_Data_Pipeline : out std_logic; + Import_Data_Last_Line : out std_logic; + Import_Data_Last_Valid_Byte : out std_logic_vector( 2 downto 0); + Import_Data : out std_logic_vector(63 downto 0); + Import_Data_Pipeline_Full : in std_logic; + Import_Pause : in std_logic; + Export_Clock : out std_logic; + Export_Core_Reset : in std_logic; + Export_Data_Available : in std_logic; + Export_Data_Start : in std_logic; + Export_Advance_Data_Pipeline : out std_logic; + Export_Data_Last_Line : in std_logic; + Export_Data_Last_Valid_Byte : in std_logic_vector( 2 downto 0); + Export_Data : in std_logic_vector(63 downto 0); + Export_Advance_Status_Pipeline : out std_logic; + Export_Status : out std_logic_vector(31 downto 0); + Export_Status_Full : in std_logic; + Dcr_Clock : in std_logic; + Dcr_Write : in std_logic; + Dcr_Write_Data : in std_logic_vector(31 downto 0); + Dcr_Read_Address : in std_logic_vector( 1 downto 0); + Dcr_Read_Data : out std_logic_vector(31 downto 0); + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + mgtRxN : in std_logic_vector(PgpLaneCnt-1 downto 0); + mgtRxP : in std_logic_vector(PgpLaneCnt-1 downto 0); + mgtTxN : out std_logic_vector(PgpLaneCnt-1 downto 0); + mgtTxP : out std_logic_vector(PgpLaneCnt-1 downto 0) + ); + end component; + + +end Pgp2RcePackage; + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo4096.xco b/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo4096.xco new file mode 100644 index 0000000000000000000000000000000000000000..d4f3988bd9596b40afdfa033e259ec873f1d59f2 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo4096.xco @@ -0,0 +1,213 @@ +############################################################## +# +# Xilinx Core Generator version 14.6 +# Date: Wed Jan 14 15:48:02 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:9.3 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT FIFO_Generator xilinx.com:ip:fifo_generator:9.3 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=true +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=data24bitfifo4096 +CSET data_count=false +CSET data_count_width=12 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=4 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=5 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=3300 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=3299 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=25 +CSET input_depth=4096 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=25 +CSET output_depth=4096 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=First_Word_Fall_Through +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=No_Programmable_Empty_Threshold +CSET programmable_empty_type_rach=No_Programmable_Empty_Threshold +CSET programmable_empty_type_rdch=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wach=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wdch=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wrch=No_Programmable_Empty_Threshold +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=No_Programmable_Full_Threshold +CSET programmable_full_type_rach=No_Programmable_Full_Threshold +CSET programmable_full_type_rdch=No_Programmable_Full_Threshold +CSET programmable_full_type_wach=No_Programmable_Full_Threshold +CSET programmable_full_type_wdch=No_Programmable_Full_Threshold +CSET programmable_full_type_wrch=No_Programmable_Full_Threshold +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=12 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET synchronization_stages=2 +CSET synchronization_stages_axi=2 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=12 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-11-19T12:39:56Z +# END Extra information +GENERATE +# CRC: 2c9b652f diff --git a/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo8192.xco b/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo8192.xco new file mode 100644 index 0000000000000000000000000000000000000000..53fc3ceacf8c4007bc933dceb989714c1a02b446 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/data24bitfifo8192.xco @@ -0,0 +1,213 @@ +############################################################## +# +# Xilinx Core Generator version 14.6 +# Date: Fri Jan 9 16:39:38 2015 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:9.3 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT FIFO_Generator xilinx.com:ip:fifo_generator:9.3 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=true +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=data24bitfifo8192 +CSET data_count=false +CSET data_count_width=13 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=4 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=5 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=6122 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=6121 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=25 +CSET input_depth=8192 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=25 +CSET output_depth=8192 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=First_Word_Fall_Through +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=No_Programmable_Empty_Threshold +CSET programmable_empty_type_rach=No_Programmable_Empty_Threshold +CSET programmable_empty_type_rdch=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wach=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wdch=No_Programmable_Empty_Threshold +CSET programmable_empty_type_wrch=No_Programmable_Empty_Threshold +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=No_Programmable_Full_Threshold +CSET programmable_full_type_rach=No_Programmable_Full_Threshold +CSET programmable_full_type_rdch=No_Programmable_Full_Threshold +CSET programmable_full_type_wach=No_Programmable_Full_Threshold +CSET programmable_full_type_wdch=No_Programmable_Full_Threshold +CSET programmable_full_type_wrch=No_Programmable_Full_Threshold +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=13 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET synchronization_stages=2 +CSET synchronization_stages_axi=2 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=13 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2012-11-19T12:39:56Z +# END Extra information +GENERATE +# CRC: a10a793a diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo1024.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo1024.xco new file mode 100644 index 0000000000000000000000000000000000000000..55a09724c07c882cc5e222920fc7545c54b90dbc --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo1024.xco @@ -0,0 +1,203 @@ +############################################################## +# +# Xilinx Core Generator version 12.4 +# Date: Mon Sep 12 21:53:03 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 7.2 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo1024 +CSET data_count=false +CSET data_count_width=10 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=800 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=799 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=1024 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=1024 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=10 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=10 +CSET wuser_width=1 +# END Parameters +GENERATE +# CRC: 9d592f8b diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo131072.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo131072.xco new file mode 100644 index 0000000000000000000000000000000000000000..afd476aac96d7ca24c4661f34444d96ecca9226f --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo131072.xco @@ -0,0 +1,219 @@ +############################################################## +# +# Xilinx Core Generator version 13.4 +# Date: Fri Aug 24 21:57:54 2012 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:8.4 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.4 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo131072 +CSET data_count=false +CSET data_count_width=17 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=125000 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=124999 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=131072 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=131072 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=17 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET synchronization_stages=2 +CSET synchronization_stages_axi=2 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=17 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-10-22T06:08:52Z +# END Extra information +GENERATE +# CRC: 61e37ce4 diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo16384.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo16384.xco new file mode 100644 index 0000000000000000000000000000000000000000..bdeaa5f663888bab056231cb7138ac4f55400c0a --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo16384.xco @@ -0,0 +1,219 @@ +############################################################## +# +# Xilinx Core Generator version 13.4 +# Date: Mon Oct 22 15:12:15 2012 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:8.4 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.4 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo16384 +CSET data_count=false +CSET data_count_width=14 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=14000 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=13999 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=16384 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=16384 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=14 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET synchronization_stages=2 +CSET synchronization_stages_axi=2 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=14 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-10-22T06:08:52Z +# END Extra information +GENERATE +# CRC: dfc3057f diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo32768.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo32768.xco new file mode 100644 index 0000000000000000000000000000000000000000..13f5ed50700fcd543a19b84f327c64c11e80d11b --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo32768.xco @@ -0,0 +1,203 @@ +############################################################## +# +# Xilinx Core Generator version 12.4 +# Date: Wed Oct 12 15:32:01 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 7.2 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo32768 +CSET data_count=false +CSET data_count_width=15 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=31000 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=30999 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=32768 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=32768 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=15 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=15 +CSET wuser_width=1 +# END Parameters +GENERATE +# CRC: 381e6d04 diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo4096.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo4096.xco new file mode 100644 index 0000000000000000000000000000000000000000..0be2d64047bfad07bc83e8768640092e25109770 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo4096.xco @@ -0,0 +1,219 @@ +############################################################## +# +# Xilinx Core Generator version 14.6 +# Date: Thu Nov 6 16:47:16 2014 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:8.4 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.4 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo4096 +CSET data_count=false +CSET data_count_width=12 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=3300 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=3299 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=4096 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=4096 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=12 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET synchronization_stages=2 +CSET synchronization_stages_axi=2 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=12 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-10-22T06:08:52Z +# END Extra information +GENERATE +# CRC: 344ff49c diff --git a/rce/fw-hsio/modules/pixelcore/coregen/datafifo8192.xco b/rce/fw-hsio/modules/pixelcore/coregen/datafifo8192.xco new file mode 100644 index 0000000000000000000000000000000000000000..1461984b4750235143cb850f6fd8971adc8e8d26 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/datafifo8192.xco @@ -0,0 +1,203 @@ +############################################################## +# +# Xilinx Core Generator version 12.4 +# Date: Fri Jun 17 18:39:09 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 7.2 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=datafifo8192 +CSET data_count=false +CSET data_count_width=13 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=6166 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=6165 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=18 +CSET input_depth=8192 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=18 +CSET output_depth=8192 +CSET overflow_flag=true +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=13 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=true +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=true +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=13 +CSET wuser_width=1 +# END Parameters +GENERATE +# CRC: d00dfff1 diff --git a/rce/fw-hsio/modules/pixelcore/coregen/dataflagfifo.xco b/rce/fw-hsio/modules/pixelcore/coregen/dataflagfifo.xco new file mode 100644 index 0000000000000000000000000000000000000000..98ca6b930dcef38c4a51d37c51d231d41af8fab3 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/dataflagfifo.xco @@ -0,0 +1,217 @@ +############################################################## +# +# Xilinx Core Generator version 14.6 +# Date: Fri Nov 7 14:50:15 2014 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:8.2 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.2 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=true +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=dataflagfifo +CSET data_count=false +CSET data_count_width=14 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=3 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=0 +CSET full_threshold_assert_value=16381 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=16380 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=1 +CSET input_depth=16384 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=1 +CSET output_depth=16384 +CSET overflow_flag=false +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=14 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=false +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=14 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-03-14T07:12:32Z +# END Extra information +GENERATE +# CRC: ef470f0d diff --git a/rce/fw-hsio/modules/pixelcore/coregen/eofcounter.xco b/rce/fw-hsio/modules/pixelcore/coregen/eofcounter.xco new file mode 100644 index 0000000000000000000000000000000000000000..feba6ec74562e31f34b79ca87772ea617ed2a401 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/eofcounter.xco @@ -0,0 +1,64 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Thu Oct 22 20:13:59 2009 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Binary_Counter family Xilinx,_Inc. 8.0 +# END Select +# BEGIN Parameters +CSET aclr=true +CSET ainit=false +CSET ainit_value=0 +CSET aset=false +CSET async_threshold_output=false +CSET ce=true +CSET component_name=eofcounter +CSET count_mode=UPDOWN +CSET cycle_early_threshold_output=true +CSET final_count_value=1 +CSET increment_value=1 +CSET load=false +CSET load_ce_priority=CE_Overrides_Load +CSET output_width=16 +CSET restrict_count=false +CSET sclr=false +CSET sinit=false +CSET sinit_value=0 +CSET sset=false +CSET sync_ce_priority=Sync_Overrides_CE +CSET sync_threshold_output=true +CSET syncctrlpriority=Reset_Overrides_Set +CSET threshold_value=0 +# END Parameters +GENERATE +# CRC: f94ff18d + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.ngc b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.ngc new file mode 100644 index 0000000000000000000000000000000000000000..78b1bc8c46d9cd398baa1f3dbad249dcccc4ccd0 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.4e +$26b4g<,[o}e~g`n;"2*413&;$>"9 > %71?*ga{&ygmn!z/da,ojenig%fecgcau-{mioip&He`L}fc.zjhZehzly$x`~ _be,tdrsm{dTnaePmdo-jbi>39:;<=>?0163?56789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012346=6&9;87<>5IORVP?gcl{k757>112924?OIX\^1mij}b=;94;7338?1EC^ZT;CG@WG;9=0;2<:4148JJUSS2HNO^O2>4;2=55=62@D[YY4xe`>3>58682;1EC^ZT;uff96=87;97><5IORVP?BNI59:6=0>2:11>LHW]]0OEO2<1;2=56=4:3CE\XZ5dhlb867=87;87><5IORVP?bnfk68=7>112906?IR\Y__6IAN<2394;743:81CXZ_UU8GKG:493:5=85<2;MVPUSS2me~xl2<1;2=50=4:3E^X][[:emvpg:493:5=<5;:HLSQQ<CAYK7?7>11097>LHW]]0OE]L33;2=55=32@D[YY4XE@>0>58682>1EC^ZT;UFF95=87;9794@UURVP?BHXH686=0>2:69KPRW]]0OC]L33;2=b>2qnq<;jk?>53/24==FLMXJ0=06;@FGVD:68730MIJ]A=32:<=FLMXJ0<<19:CG@WG;9:4i7LJKR@>20?6912KOH_O315<;?DBCZH6:255NDEPB878?3HNO^L2<>99B@ATF4=437LJKR@>6:==FLMXJ0;07;@FGVD:0611JHI\N<9<;?DBCZH62255NDEPA858>3HNO^O2>0?;8EABUJ5;:245NDEPA844912KOH_L312<a?DBCZK6:87>19:CG@WD;9=437LJKRC>2:==FLMXI0?07;@FGVG:4611JHI\M<5<;?DBCZK6>255NDEPA838?3HNO^O28>99B@ATE41437LJKRC>::6=FDE90NX<7;CWP[LHAGh1HM^MNDDKMEd=DIZIJHHGABc9@EVEFLLE^XLl4C@Q@EACH]]H:>6MGEBI\HLEBFZOTXT^J4:AOOD2<KEAI56M@MLKWP@B6<2ID^HQHEOGQEQOHFVCEJB94CSGBP@B13MCJ0=08;EKB8469?2NBM1?>>69GMD:6:7=0HDO312<4?AOF48>5;6JFA=36:2=CAH6::394DHC?52803MCJ0<617:FJE97>6?1OEL2>>69GMD:587=0HDO320<4?AOF4;85;6JFA=00:2=CAH698394DHC?60803MCJ0?817:FJE9406>1OEL2=8?58@LG;:04=7IGN<3<4?AOF4::556JFA=12>5803MCJ0>?16:FJE959>2NBM1:16:FJE939>2NBM1816:FJE919>2NBM1616:FJE9?9>2NBN1>17:FJF9776>1OEO2>1?58@LD;9;4<7IGM<01=3>BNJ5;?2:5KIC>21;1<L@H7=;08;EKA8419?2NBN1?7>69GMG:617<0HDL31?58@LD;:94<7IGM<33=3>BNJ5892:5KIC>17;1<L@H7>908;EKA8739?2NBN1<9>69GMG:5?7=0HDL329<4?AOE4;35:6JFB=0=3>BNJ59;245KIC>05?69?2NBN1=>>79GMG:46?1OEO2;>79GMG:26?1OEO29>79GMG:06?1OEO27>79GMG:>6>1OE]O30?58@LVF484<7IG_A=0==>BNXH686=08;EKSE959?2NB\O2?>69GMUD;97=0HD^M<3<:?AOWJ591<394DHRA86813MEJ0=08;EMB8469?2NDM1?>>69GKD:6:7=0HBO312<4?AIF48>5;6J@A=36:2=CGH6::394DNC?52803MEJ0<617:FLE97>6?1OCL2>>69GKD:587=0HBO320<4?AIF4;85;6J@A=00:2=CGH698394DNC?60803MEJ0?817:FLE9406>1OCL2=8?58@JG;:04=7IAN<3<4?AIF4::556J@A=12>5803MEJ0>?16:FLE959>2NDM1:16:FLE939>2NDM1816:FLE919>2NDM1616:FLE9?9?2NDMR\JG79GKG:76>1OCO2>0?58@JD;984<7IAM<00=3>BHJ5;82:5KOC>20;1<LFH7=808;EMA8409?2NDN1?8>69GKG:607=0HBL318<5?AIE484<7IAM<32=3>BHJ58:2:5KOC>16;1<LFH7>>08;EMA8729?2NDN1<:>69GKG:5>7=0HBL326<4?AIE4;25;6J@B=0::3=CGK692:5KOC>04;?<LFH7?<4?>69GKG:497<0HBL33?48@JD;<7<0HBL35?48@JD;>7<0HBL37?48@JD;07<0HBL39?58@JDXZLM<7IA_A=2=3>BHXH6:2:5KOQC?6;?<LFZJ0>4?>69GKUG;;7=0HB^M<1<4?AIWJ5;5;6J@PC>1:<=CGYH7?7>17:FLTG:46:1NBL=4EO@6?CGK[L;0K>5HNE:8MKOSXV:;46GAIUR\44><AGC_\R>=8:KMMQVX8:20ECG[P^27<>OIA]ZT<864IOKWTZ6102CEEY^P0658MKOSW9:<7D@FT^223>OIA]U;>:5FNHV\461<AGC_S=:8;HLJPZ62?2CEEYQ?669JJLRX8>=0ECG[_1:4?LHN\V:2;6GAIU]3E2=NF@^T<O94IOKW[5E03@DBXR>K7:KMMQY7M>1BBDZP0G58MKOSW8:<7D@FT^323>OIA]U:>:5FNHV\561<AGC_S<:8;HLJPZ72?2CEEYQ>669JJLRX9>=0ECG[_0:4?LHN\V;2;6GAIU]2E2=NF@^T=O94IOKW[4E03@DBXR?K7:KMMQY6M>1BBDZP1G58MKOSW;:<7D@FT^023>OIA]U9>:5FNHV\661<AGC_S?:8;HLJPZ42?2CEEYQ=669JJLRX:>=0ECG[_3:4?LHN\V82;6GAIU]1E2=NF@^T>O94IOKW[7E03@DBXR<K7:KMMQY5M>1BBDZP2G58MKOSW::<7D@FT^123>OIA]U8>:5FNHV\761<AGC_S>:8;HLJPZ52?2CEEYQ<669JJLRX;>=0ECG[_2:4?LHN\V92;6GAIU]0E2=NF@^T?O94IOKW[6E03@DBXR=K7:KMMQY4M>1BBDZP3G48MKOSWH<0ECG[_C;8MKOSWOCGI<<4IOTFVQYDDBUOCLQ]EF31?LHQM[^TOAEPDN@\V@A13EEJHHJ8;MMDMFGKk2Gjfb|Yesqjkke<E`dd~[k}shmm7>H68=1E==>;;O3351=I998?7C??359M55233G;;995A1147?K77?=1E==6;;O33=6=I98>0B<??4:L2542<F8;986@>1268J473<2D:=8:4N0350>H69>>0B<?74:L25<5<F88?7C?=059M57733G;9>95A1317?K75<=1E=?8;;O31<1=I9;387C?<4:L2752<F89:86@>3368J454<2D:?9:4N0160>H6;?>0B<=84:L27=2<F892?6@>459M51633G;?=95A1507?K73;=1E=9:;;O3711=I9=<?7C?;759M51>33G;?5>5A1468J437<2D:9<:4N0710>H6=:>0B<;;4:L2102<F8?=86@>5668J43?<2D:94=4N040?K70;2D:4>5A1808J75<F;:87C<>3:L166=I::90B?:<;O067>H5>:1E>:=4N3:0?K4>:2D8?6@<029M745<F:887C=<3:L006=I;<90B>8<;O147>H40:1E?4<4N518J1643G>:?6@;229M065<F=>87C::3:L736=I<080B8=4N420?K36;2D>>>5A5218J0243G?>?6@:629M125<F<287C;62:L57>H18:1E:<=4N700?K04;2D=8>5A6418J3043G<<?6@9829M2<4<F>90B:><;O527>H0::1E;>=4N660?K12;2D<:>5A7618J2>43G=2>6@73:L;46=I0890B5<<;O:07>H?<:1E48=4N940?K>0;2D34>5A8808J<5<F0:87C7>3:L:66=I1:90B4:<;O;67>H>>:1E5:=4N8:0?K?>n2DISO[\PHL\TWIW[>1EIYY@RJ68JJHB12DDSNFNNFG1?JM63Y>0\L\[a:RJJZDR[@NSn6^FN^@VWKGJM?1YM@L>6g9QEHYBP]OE_DAA_@d8VDKXMQ^NB^G@N^@`?WCFLV]BHYFPAb9QADBX_@N_DRL9;SGDG@G13[OLOHL7;RCUAAGSI890_DCPCNNOMVOHFVICINE9;RMVVFC03ZX]MAQN7:QQRDJXJ=1X__O;;RQQF1=SQYO>86[?/cnh[hcjWnoeio{os-ueioc&jy~"|nmmmlt^6Z&{kf"!y4^kmmq(uid%_^XKPDQ,PMKAKMVZYE@ [DQ77?P6(jeaTahcPgdlfvdrhz&|j`dj!crvq+wgjdfe{W<S!r`o-v*p3W`dbx#|nm.VQQ@YCX'YBBJBJ_QPJI+RCXh1^_H\PAMKBWf=R[LXTZD]FBMG0?SED12\BIZQ[YQG5?RCF494=7ZKN<0<5?RCF4;437ZKN<283:3=PMH682;5XEC>3:3=PMK6:2;5XEC>1:==PMK686=09;VGA868d3^XBXHQBOEG\Ef=PZ@^NS@AKE^@g?RTN\LU\EIZG_@f8SWOSMV]BHYFPB0f8\LJNFQ'SHO.?.0"PPPD'8';+M^MFI79[WQJNJ>1S_YQHNE`8\ZEHZLUBBKA9;Yfa[Lba3QncS]|fmWgqwlii991Sh`QBakmqR`ttafd:<6Vkm^OjjjtQm{ybcc64aefqe-6.02koho'1(:8eabui!8"46okdsc+7,><imnym%:&8:cg`wg/= 20mij}a)4*<>gcl{k#;$64aefqe->.02koho'9(:8eabui5:546okdsc?5;><imnym1<18:cg`wg;;720mij}a=6=<>gcl{k79364aefqe90902koho37?:8eabui525m6okdsc?=?6902koho39?:8eabuj!:"46okds`+5,><imnyn%<&8:cg`wd/; 20mij}b)6*<>gcl{h#9$64aefqf-0.02kohl'7(:8eabuj!2"46okds`+=,><imnyn1>18:cg`wd;9720mij}b=0=<>gcl{h7?364aefqf92902kohl35?:8eabuj5<546okds`?3;><imnyn161a:cg`wd;13:546okds`?=;543kf`S`kb_fgm[s4X0%*Seagax!ALV@&@mgoymya} 02-5+64W`z886mck`68gime?2nieyk}r69gmkg/8 =0hd`n(0+;?aoii!;;%55kioc+54/?3mcem%?=)99gmkg/9:#37igaa)37-==cagk#=8'7;ekme-71!11oeco'16+;?aoii!;3%55kioc+5</03mcem%<&8:fjjd.58 20hd`n(33*<>bnfh"9>$64dhlb,75.02nbbl&=4(:8`lhf ;?"46jfn`*12,><l`dj$?9&8:fjjd.50 20hd`n(3;*3>bnfh"8%55kioc+75/?3mcem%=>)69gmkg/< =0hd`n(4+4?aoii!<";6jfn`*4-2=cagk#4$94dhlb,</03mcem1>18:fjjd:68720hd`n<03=<>bnfh6:>364dhlb845902nbbl2>4?:8`lhf48?546jfn`>22;><l`dj0<918:fjjd:60720hd`n<0;=3>bnfh6:255kioc?658?3mcem1<>>99gmkg;:;437igaa=00:==cagk7>907;ekme942611oeco327<;?aoii58<255kioc?6=8?3mcem1<6>69gmkg;:720hd`n<22=e>bnfh68=7>18:fjjd:497=0hd`n<2<4?aoii5>5;6jfn`>6:2=cagk7:394dhlb82803mcem1617:fjjd:>6>1oecl'0(58`lhe 8#37igab)33-==cagh#=<'7;ekmf-75!11oecl'12+;?aoij!;?%55kio`+50/?3mcen%?9)99gmkd/9>#37igab)3;-==cagh#=4'8;ekmf-4.02nbbo&=0(:8`lhe ;;"46jfnc*16,><l`di$?=&8:fjjg.5< 20hd`m(37*<>bnfk"9:$64dhla,71.02nbbo&=8(:8`lhe ;3";6jfnc*0-==cagh#?='7;ekmf-56!>1oecl'4(58`lhe <#<7igab)4*3>bnfk"<%:5kio`+<,1<l`di$4'8;ekmf96902nbbo2>0?:8`lhe48;546jfnc>26;><l`di0<=18:fjjg:6<720hd`m<07=<>bnfk6::364dhla841902nbbo2>8?:8`lhe4835;6jfnc>2:==cagh7>=07;ekmf946611oecl323<;?aoij588255kio`?618?3mcen1<:>99gmkd;:?437igab=04:==cagh7>507;ekmf94>6>1oecl32?:8`lhe4::5m6jfnc>05?6902nbbo2<1?58`lhe4:4<7igab=6=3>bnfk6>2:5kio`?2;1<l`di0:08;ekmf9>9?2nbbo26>99gkprf 9#37iazt`*2-<=cg|~j$<>&9:flqqg/98#27iazt`*26,?<lfm%?<)89gkprf 8>"56j`uuc+50/>3me~xl&>6(;8`jssi!;<%45kotvb,4>.12ndyyo'18+;?air|h"9%45kotvb,76.12ndyyo'20+:?air|h"9>$74dnwwe-44!01ocxzn(36*=>bh}}k#>8'6;emvpd.5> 30hb{{a)04-<=cg|~j$?6&9:flqqg/:0#37iazt`*0-<=cg|~j$>>&9:flqqg/;8#37iazt`*7-==cg|~j$8'7;emvpd.1!11ocxzn(6+;?air|h"3%55kotvb,</?3me~xl2?>89gkprf48:556j`uuc?548>3me~xl2>2?;8`jssi5;8245kotvb842912ndyyo314<:?air|h6::374dnwwe970601ocxzn<0:==>bh}}k7=407;emvpd:6601ocxzn<32==>bh}}k7><06;emvpd:5:730hb{{a=00:<=cg|~j0?:19:flqqg;:<427iazt`>12;?<lfm1<8>89gkprf4;2556j`uuc?6<8?3me~xl2=>89gkprf4::5n6j`uuc?74<7601ocxzn<23=<>bh}}k7?364dnwwe92902ndyyo35?:8`jssi5<546j`uuc?3;><lfm1618:flqqg;1720hb{{b)2*<>bh}}h#=$74dnwwf-77!01ocxzm(03*=>bh}}h#=?'6;emvpg.6; 30hb{{b)37-<=cg|~i$<;&9:flqqd/9?#27iaztc*23,?<lfn%?7)89gkpre 83"46j`uu`+6,?<lfn%<?)89gkpre ;;"56j`uu`+67/>3me~xo&=3(;8`jssj!8?%45kotva,73.12ndyyl'27+:?air|k"9;$74dnwwf-4?!01ocxzm(3;*<>bh}}h#?$74dnwwf-57!01ocxzm(23*<>bh}}h#8$64dnwwf-3.02ndyyl'6(:8`jssj!="46j`uu`+<,><lfn%7&8:flqqd;8730hb{{b=33:<=cg|~i0<?19:flqqd;9;427iaztc>27;?<lfn1?;>89gkpre48?556j`uu`?538>3me~xo2>7?;8`jssj5;3245kotva84?902ndyyl31?;8`jssj58;245kotva877912ndyyl323<:?air|k69?374dnwwf943601ocxzm<37==>bh}}h7>;06;emvpg:5?730hb{{b=0;:<=cg|~i0?718:flqqd;:730hb{{b=13:g=cg|~i0>?50?;8`jssj59:255kotva868?3me~xo2;>99gkpre4<437iaztc>5:==cg|~i0:07;emvpg:?611ocxzm<8<;?`bnn;dlh>5jn`18akd?3gmhnxgcdg9seqrbzgUi`fQbel0b?ugs|lxeSobd_lgn(gjlWdofSjka_w0\<)HHFL&ECCK<769seqrbzgUi`fQbel.ahnYjmdUlicQy2^:/fYoizUyijmjb<2/gZnf{Vxnknkn=1.`[hcjW}s{i0<#c^rqmhYsqyo6=!mPshljpdYqie7; nQ}e`f\slbs`Vh6??"l_sgb`Zqnl}bTm0==,b]gmvgedlU|m`Pbit\gjjk59&hSd`ft^djh`Yiido6bbQlod]emicXdfkoii"l_vpjp`YjgmoTn0@@_BJBJBC+kV}yeykPmnff[d;IGVICMCIJ,b]nq}YwayogeckPsucdav;7$jUcm~Qbel]lqqvr|Vxnk~Qm=1.`[iiflVceeyQiimg>4)eX`hyTahcPotvsqqYumnyTm0>#c^uqmqcXllzdRl21107(fYpz`~nSikti]b9465<%iTdl}Psrpa95*dWakxS`{w_nwwtprXzlmxSo3?,b]kevYt{{k6<!mPh`q\ip~Xg|~{yyQ}efq\e86+kVkohoPwhfwl877$jUjhi|m_vkgpm;68%iThhhnumv\`drf59&hSx}j_da`95*dWhflcg{hl?2(fYcazki`hQxasl\fmpXzhdli0>#c^uqmqcX`ndRl233.`[rtn|lU|eizg_`?06)eXzlkoSikti]a9465<%iT~hok_egspmYf58:98!mPbxvf[vo}m43'oR}fm^alhiotafdToeklk<COH)eXkfgfccQllj?3(fYr{lUym`l>6cufvZtt|Vhcz0>#c^ufeZqnl}b6=!mPh`q\akd:9%iTdl}Peoc>5)eXlhT{dj{h<3/gZunf`~iS{oc=1.`khvhfldScobe<rbpqcufVhggRcjm-a\qvcXjp~nSzkm=1.`[pubWksiRyja<2/gZstmVnnjl{ct^fbpd;6$t8=7}o{tdpm[gjlWdofSobd_lgn[bciW8T4Rv|t^35?wc`klk=7khcd`4?vdn|lxy86}|r`68wvte>2}nm%>&8:ufe96=87<0{ho30?48s`d/8 20{hl30;2=2>qbj5:5qMN4`08DE~62O0?6<u\478072<328994km>:23`76}i:991=6`=0587?!4793;mh6s\458072<328994km>:23`76=T9:91?>o50;306=`d939:o>=4S56976g=83;8>5hl1;12g60<l:9i6=4>:0yP03<4;>0?6<==8ga2>67d;:1}X<k<:182>4<>jrY?:7=<7;69564?nj;1?<m<3:&2a`<6;=1]>=<52zw270<63|;8:7>4}%3g3?7>3k98n7>59`80><g|@8oh7W=l:9y:>d<22?0:=7?=:e8f>x"6m108?o5+212967`<a:936=44i21:>5<<a:>?6=4+1e;9713<f8n36=54i264>5<#9m31?964n0f;>5=<a;:n6=4+1e;964><f8n36=54i32g>5<#9m31><64n0f;>4=<a;:h6=4+1e;964><f8n36?54i32a>5<#9m31><64n0f;>6=<a;:j6=4+1e;964><f8n36954i32:>5<#9m31><64n0f;>0=<a;:36=4+1e;964><f8n36;54i324>5<#9m31><64n0f;>2=<a;:=6=4+1e;964><f8n36554i326>5<#9m31><64n0f;><=<a;886=4+1e;967b<f8n36=54i301>5<#9m31>?j4n0f;>4=<a;8:6=4+1e;967b<f8n36?54i303>5<#9m31>?j4n0f;>6=<a;;m6=4+1e;967b<f8n36954i33f>5<#9m31>?j4n0f;>0=<a;;o6=4+1e;967b<f8n36;54i33`>5<#9m31>?j4n0f;>2=<a;;i6=4+1e;967b<f8n36554i33b>5<#9m31>?j4n0f;><=<g;in6=4+1e;96`b<f8n36=54o3ag>5<#9m31>hj4n0f;>4=<g;ii6=4+1e;96`b<f8n36?54o3ab>5<#9m31>hj4n0f;>6=<g;i26=4+1e;96`b<f8n36954o3a;>5<#9m31>hj4n0f;>0=<g;i<6=4+1e;96`b<f8n36;54o3a5>5<#9m31>hj4n0f;>2=<g;i>6=4+1e;96`b<f8n36554o3a7>5<#9m31>hj4n0f;><=<g;i86=4+1e;96`b<f8n36l54o3a1>5<#9m31>hj4n0f;>g=<g;i;6=4+1e;96`b<f8n36n54o3`e>5<#9m31>hj4n0f;>a=<g;hn6=4+1e;96`b<f8n36h54o3`g>5<#9m31>hj4n0f;>c=<g;hh6=4+1e;96`b<f8n36<>4;n0af?6=,8n26?kk;o3g<?7632e9nl4?:%3g=?4bl2d:h54>2:9l6g?=83.:h44=ee9m5a>=9:10c?l7:18'5a?=:ln0b<j7:068?j4e?3:1(<j6:3gg?k7c03;>76a=d583>!7c138nh6`>d9822>=h:m91<7*>d881aa=i9m21=:54o3f1>5<#9m31>hj4n0f;>4><3f8o=7>5$0f:>7cc3g;o47?6;:m1`5<72-;o57<jd:l2`=<6i21d>nh50;&2`<<5mm1e=i651c98k7ed290/=i752df8j4b?28i07b<l1;29 4b>2;oo7c?k8;3g?>i5j?0;6)?k9;0f`>h6l10:i65`2c794?"6l009ii5a1e:95c=<g::m6=4+1e;977c<f8n36=54o22f>5<#9m31??k4n0f;>4=<g::h6=4+1e;977c<f8n36?54o22a>5<#9m31??k4n0f;>6=<g::j6=4+1e;977c<f8n36954o22:>5<#9m31??k4n0f;>0=<g::36=4+1e;977c<f8n36;54o224>5<#9m31??k4n0f;>2=<g::=6=4+1e;977c<f8n36554o226>5<#9m31??k4n0f;><=<g::?6=4+1e;977c<f8n36l54o220>5<#9m31??k4n0f;>g=<g:::6=4+1e;977c<f8n36n54o223>5<#9m31??k4n0f;>a=<g;lm6=4+1e;977c<f8n36h54o3df>5<#9m31??k4n0f;>c=<g;lo6=4+1e;977c<f8n36<>4;n0eg?6=,8n26><j;o3g<?7632e9jo4?:%3g=?55m2d:h54>2:9l6cg=83.:h44<2d9m5a>=9:10c?h6:18'5a?=;;o0b<j7:068?j4a03:1(<j6:20f?k7c03;>76a<1483>!7c1399i6`>d9822>=h;8>1<7*>d8806`=i9m21=:54o230>5<#9m31??k4n0f;>4><3f9:>7>5$0f:>64b3g;o47?6;:m054<72-;o57==e:l2`=<6i21d?<>50;&2`<<4:l1e=i651c98k66c290/=i7533g8j4b?28i07b=?2;29 4b>2:8n7c?k8;3g?>i5n>0;6)?k9;11a>h6l10:i65`2g494?"6l008>h5a1e:95c=<a;9;6=44i312>5<<a;>h6=4+1e;963d<f8n36=54i36a>5<#9m31>;l4n0f;>4=<a;>26=4+1e;963d<f8n36?54i36;>5<#9m31>;l4n0f;>6=<a;><6=4+1e;963d<f8n36954i365>5<#9m31>;l4n0f;>0=<a;>>6=4+1e;963d<f8n36;54i367>5<#9m31>;l4n0f;>2=<a;>86=4+1e;963d<f8n36554i361>5<#9m31>;l4n0f;><=<a;>:6=4+1e;963d<f8n36l54i363>5<#9m31>;l4n0f;>g=<a;9n6=4+1e;963d<f8n36n54i31g>5<#9m31>;l4n0f;>a=<a;9h6=4+1e;963d<f8n36h54i31a>5<#9m31>;l4n0f;>c=<a;9j6=4+1e;963d<f8n36<>4;h00=?6=,8n26?8m;o3g<?7632c9?54?:%3g=?41j2d:h54>2:9j661=83.:h44=6c9m5a>=9:10e?=9:18'5a?=:?h0b<j7:068?l44=3:1(<j6:34a?k7c03;>76g=5383>!7c138=n6`>d9822>=n:<;1<7*>d8812g=i9m21=:54i373>5<#9m31>;l4n0f;>4><3`8?j7>5$0f:>70e3g;o47?6;:k10`<72-;o57<9b:l2`=<6i21b>9j50;&2`<<5>k1e=i651c98m72f290/=i7527`8j4b?28i07d<<f;29 4b>2;<i7c?k8;3g?>o5;=0;6)?k9;05f>h6l10:i65f22194?"6l009:o5a1e:95c=<a;2o6=4+1e;96de<f8n36=54i3:`>5<#9m31>lm4n0f;>4=<a;2j6=4+1e;96de<f8n36?54i3::>5<#9m31>lm4n0f;>6=<a;236=4+1e;96de<f8n36954i3:4>5<#9m31>lm4n0f;>0=<a;2=6=4+1e;96de<f8n36;54i3:6>5<#9m31>lm4n0f;>2=<a;2?6=4+1e;96de<f8n36554i3:0>5<#9m31>lm4n0f;><=<a;296=4+1e;96de<f8n36l54i3:2>5<#9m31>lm4n0f;>g=<a;=m6=4+1e;96de<f8n36n54i35f>5<#9m31>lm4n0f;>a=<a;=o6=4+1e;96de<f8n36h54i35`>5<#9m31>lm4n0f;>c=<a;=i6=4+1e;96de<f8n36<>4;h04e?6=,8n26?ol;o3g<?7632c9;44?:%3g=?4fk2d:h54>2:9j62>=83.:h44=ab9m5a>=9:10e?98:18'5a?=:hi0b<j7:068?l40>3:1(<j6:3c`?k7c03;>76g=9283>!7c138jo6`>d9822>=n:081<7*>d881ef=i9m21=:54i3;2>5<#9m31>lm4n0f;>4><3`82<7>5$0f:>7gd3g;o47?6;:k1<c<72-;o57<nc:l2`=<6i21b>5k50;&2`<<5ij1e=i651c98m7>e290/=i752`a8j4b?28i07d<70;29 4b>2;kh7c?k8;3g?>o5?<0;6)?k9;0bg>h6l10:i65f26694?"6l009mn5a1e:95c=<j8oo6=4>:183M7bk2.:i54>ee9l5a0=831vnh;50;394?6|@8oh7)?j8;g6?jc32900qo=m:18b4?5=1kqC=hm4Z2a955}>2h0>6;4>1;31>a<b28;1=?46:`86>3<c2l0v(<k7:21f?!262:9h7):::21g?!7c93;o96g<3983>>o4;00;66g<4383>>o4<:0;66g<3g83>>o4<90;66g<4583>!7c139?96`>d983?>o4<>0;6)?k9;17<>h6l10;76g=0d83>!7c138:46`>d983?>o58m0;6)?k9;02<>h6l10:76g=0b83>!7c138:46`>d981?>o58k0;6)?k9;02<>h6l10876g=0`83>!7c138:46`>d987?>o5800;6)?k9;02<>h6l10>76g=0983>!7c138:46`>d985?>o58>0;6)?k9;02<>h6l10<76g=0783>!7c138:46`>d98;?>o58<0;6)?k9;02<>h6l10276g=2283>!7c1389h6`>d983?>o5:;0;6)?k9;01`>h6l10:76g=2083>!7c1389h6`>d981?>o5:90;6)?k9;01`>h6l10876g=1g83>!7c1389h6`>d987?>o59l0;6)?k9;01`>h6l10>76g=1e83>!7c1389h6`>d985?>o59j0;6)?k9;01`>h6l10<76g=1c83>!7c1389h6`>d98;?>o59h0;6)?k9;01`>h6l10276a<4083>>i5kl0;6)?k9;0f`>h6l10;76a=ce83>!7c138nh6`>d982?>i5kk0;6)?k9;0f`>h6l10976a=c`83>!7c138nh6`>d980?>i5k00;6)?k9;0f`>h6l10?76a=c983>!7c138nh6`>d986?>i5k>0;6)?k9;0f`>h6l10=76a=c783>!7c138nh6`>d984?>i5k<0;6)?k9;0f`>h6l10376a=c583>!7c138nh6`>d98:?>i5k:0;6)?k9;0f`>h6l10j76a=c383>!7c138nh6`>d98a?>i5k90;6)?k9;0f`>h6l10h76a=bg83>!7c138nh6`>d98g?>i5jl0;6)?k9;0f`>h6l10n76a=be83>!7c138nh6`>d98e?>i5jj0;6)?k9;0f`>h6l10:<65`2c`94?"6l009ii5a1e:954=<g;hj6=4+1e;96`b<f8n36<<4;n0a=?6=,8n26?kk;o3g<?7432e9n54?:%3g=?4bl2d:h54>4:9l6g1=83.:h44=ee9m5a>=9<10c?j;:18'5a?=:ln0b<j7:048?j4c;3:1(<j6:3gg?k7c03;<76a=d383>!7c138nh6`>d982<>=h:m;1<7*>d881aa=i9m21=454o3f3>5<#9m31>hj4n0f;>4g<3f8hj7>5$0f:>7cc3g;o47?m;:m1gf<72-;o57<jd:l2`=<6k21d>n?50;&2`<<5mm1e=i651e98k7d1290/=i752df8j4b?28o07b<m5;29 4b>2;oo7c?k8;3e?>i48o0;6)?k9;11a>h6l10;76a<0d83>!7c1399i6`>d982?>i48j0;6)?k9;11a>h6l10976a<0c83>!7c1399i6`>d980?>i48h0;6)?k9;11a>h6l10?76a<0883>!7c1399i6`>d986?>i4810;6)?k9;11a>h6l10=76a<0683>!7c1399i6`>d984?>i48?0;6)?k9;11a>h6l10376a<0483>!7c1399i6`>d98:?>i48=0;6)?k9;11a>h6l10j76a<0283>!7c1399i6`>d98a?>i4880;6)?k9;11a>h6l10h76a<0183>!7c1399i6`>d98g?>i5no0;6)?k9;11a>h6l10n76a=fd83>!7c1399i6`>d98e?>i5nm0;6)?k9;11a>h6l10:<65`2ga94?"6l008>h5a1e:954=<g;li6=4+1e;977c<f8n36<<4;n0ee?6=,8n26><j;o3g<?7432e9j44?:%3g=?55m2d:h54>4:9l6c>=83.:h44<2d9m5a>=9<10c>?::18'5a?=;;o0b<j7:048?j56<3:1(<j6:20f?k7c03;<76a<1283>!7c1399i6`>d982<>=h;881<7*>d8806`=i9m21=454o232>5<#9m31??k4n0f;>4g<3f9:<7>5$0f:>64b3g;o47?m;:m04a<72-;o57==e:l2`=<6k21d?=<50;&2`<<4:l1e=i651e98k7`0290/=i7533g8j4b?28o07b<i6;29 4b>2:8n7c?k8;3e?>o5;90;66g=3083>>o5<j0;6)?k9;05f>h6l10;76g=4c83>!7c138=n6`>d982?>o5<00;6)?k9;05f>h6l10976g=4983>!7c138=n6`>d980?>o5<>0;6)?k9;05f>h6l10?76g=4783>!7c138=n6`>d986?>o5<<0;6)?k9;05f>h6l10=76g=4583>!7c138=n6`>d984?>o5<:0;6)?k9;05f>h6l10376g=4383>!7c138=n6`>d98:?>o5<80;6)?k9;05f>h6l10j76g=4183>!7c138=n6`>d98a?>o5;l0;6)?k9;05f>h6l10h76g=3e83>!7c138=n6`>d98g?>o5;j0;6)?k9;05f>h6l10n76g=3c83>!7c138=n6`>d98e?>o5;h0;6)?k9;05f>h6l10:<65f22;94?"6l009:o5a1e:954=<a;936=4+1e;963d<f8n36<<4;h003?6=,8n26?8m;o3g<?7432c9?;4?:%3g=?41j2d:h54>4:9j663=83.:h44=6c9m5a>=9<10e?;=:18'5a?=:?h0b<j7:048?l4293:1(<j6:34a?k7c03;<76g=5183>!7c138=n6`>d982<>=n:=l1<7*>d8812g=i9m21=454i36f>5<#9m31>;l4n0f;>4g<3`8?h7>5$0f:>70e3g;o47?m;:k10d<72-;o57<9b:l2`=<6k21b>>h50;&2`<<5>k1e=i651e98m753290/=i7527`8j4b?28o07d<<3;29 4b>2;<i7c?k8;3e?>o50m0;6)?k9;0bg>h6l10;76g=8b83>!7c138jo6`>d982?>o50h0;6)?k9;0bg>h6l10976g=8883>!7c138jo6`>d980?>o5010;6)?k9;0bg>h6l10?76g=8683>!7c138jo6`>d986?>o50?0;6)?k9;0bg>h6l10=76g=8483>!7c138jo6`>d984?>o50=0;6)?k9;0bg>h6l10376g=8283>!7c138jo6`>d98:?>o50;0;6)?k9;0bg>h6l10j76g=8083>!7c138jo6`>d98a?>o5?o0;6)?k9;0bg>h6l10h76g=7d83>!7c138jo6`>d98g?>o5?m0;6)?k9;0bg>h6l10n76g=7b83>!7c138jo6`>d98e?>o5?k0;6)?k9;0bg>h6l10:<65f26c94?"6l009mn5a1e:954=<a;=26=4+1e;96de<f8n36<<4;h04<?6=,8n26?ol;o3g<?7432c9;:4?:%3g=?4fk2d:h54>4:9j620=83.:h44=ab9m5a>=9<10e?7<:18'5a?=:hi0b<j7:048?l4>:3:1(<j6:3c`?k7c03;<76g=9083>!7c138jo6`>d982<>=n:0:1<7*>d881ef=i9m21=454i3:e>5<#9m31>lm4n0f;>4g<3`83i7>5$0f:>7gd3g;o47?m;:k1<g<72-;o57<nc:l2`=<6k21b>5>50;&2`<<5ij1e=i651e98m712290/=i752`a8j4b?28o07d<84;29 4b>2;kh7c?k8;3e?>i5;;0;66l>fg83>4<729q/=h65e49K5cc<@8oh7bk;:188yg7bi3:1o?4?:1y'5`>=9mk0D<hj;I3fg>\4k3ip;765b;a956<6<3;>6<85f;33>41=910vbo:50:lg2?6<,88n6?5+13d96>"b>390(h953:&f<?5<,l31?6*ja;18 `d=;2.:i<4j3:&2a1<53-on6>5+eg80?!`72:1/j<4<;%d1>6=#n:087)h;:29'b0<43-l=6>5+f680?!`?2:1/j44<;%db>6=#nk087)hl:29'ba<43-ln6>5+fg80?!778390(<>>:29'554=;2.:<>4<;%330?5<,8:>6>5+11497>"68>087)??8;18 46>2:1/==o53:&24g<43-;;o7=4$02g>6=#99o1?6*>0g80?!768390(<?>:29'544=;2.:=>4<;%320?5<,8;>6>5+10497>"69>087)?>8;18 47>2:1/=<o53:&25g<43-;:o7=4$03g>6=#98o1?6*>1g80?!758390(<<>:29'574=;2.:>>4<;%310?5<,88>6>5+13497>"6:>087)?=8;18 44>2:1/=?o53:&26g<43-;9o7=4$00g>6=#9::1=i=4$012>`5<,8996h=4$0fa>4b43-;oo7?k3:l2`a<6:2d:hh4>2:&2a7<4i2.no7=4$df97>"6n00:h95+1gc95a2<f8li6<<4n0d`>44<,8o>6?5f3e83>>o4m3:17d:=:188m15=831bi<4?::k2`c<722c:i=4?::kf6?6=3`;n:7>5;h3f3?6=3f9m6=44o5294?=n:90;6)?k9;3e?k7c03:07d?j:18'5a?=9o1e=i651:9j5a<72-;o57?i;o3g<?4<3`;h6=4+1e;95c=i9m21?65f1c83>!7c13;m7c?k8;68?l4>290/=i751g9m5a>==21b>54?:%3g=?7a3g;o4784;h04>5<#9m31=k5a1e:93>=n:?0;6)?k9;3e?k7c03207d<::18'5a?=9o1e=i659:9j61<72-;o57?i;o3g<?g<3`886=4+1e;95c=i9m21n65f2383>!7c13;m7c?k8;a8?l46290/=i751g9m5a>=l21b=l4?:%3g=?7a3g;o47k4;h13>5<#9m31>k5a1e:94>=n:l0;6)?k9;0e?k7c03;07d<k:18'5a?=:o1e=i652:9j6f<72-;o57<i;o3g<?5<3`8i6=4+1e;96c=i9m21865f3883>!7c138m7c?k8;78?l5?290/=i752g9m5a>=>21b?:4?:%3g=?4a3g;o4794;h15>5<#9m31>k5a1e:9<>=n;<0;6)?k9;0e?k7c03307d=;:18'5a?=:o1e=i65a:9j76<72-;o57<i;o3g<?d<3`996=4+1e;96c=i9m21o65f3083>!7c138m7c?k8;f8?l4f290/=i752g9m5a>=m21b:=4?:%3g=?3a3g;o47>4;h7f>5<#9m319k5a1e:95>=n=j0;6)?k9;7e?k7c03807d;m:18'5a?==o1e=i653:9j1d<72-;o57;i;o3g<?2<3`?26=4+1e;91c=i9m21965f5983>!7c13?m7c?k8;48?l30290/=i755g9m5a>=?21b9;4?:%3g=?3a3g;o4764;h76>5<#9m319k5a1e:9=>=n==0;6)?k9;7e?k7c03k07d;<:18'5a?==o1e=i65b:9j14<72-;o57;i;o3g<?e<3`?;6=4+1e;91c=i9m21h65f4g83>!7c13?m7c?k8;g8?l2b290/=i755g9m5a>=n21b8i4?:%3g=?3a3g;o47??;:k7g?6=,8n268h4n0f;>47<3`>i6=4+1e;91c=i9m21=?54i5c94?"6l00>j6`>d9827>=n<00;6)?k9;7e?k7c03;?76g;8;29 4b>2<l0b<j7:078?l00290/=i755g9m5a>=9?10e;850;&2`<<2n2d:h54>7:9j20<72-;o57;i;o3g<?7?32c=87>5$0f:>0`<f8n36<74;h40>5<#9m319k5a1e:95d=<a?81<7*>d886b>h6l10:n65f6083>!7c13?m7c?k8;3`?>o2l3:1(<j6:4d8j4b?28n07d;=:18'5a?==o1e=i651d98m11=83.:h44:f:l2`=<6n21b4<4?:%3g=?>73g;o47>4;h5e>5<#9m314=5a1e:95>=n?m0;6)?k9;:3?k7c03807d9l:18'5a?=091e=i653:9j3g<72-;o576?;o3g<?2<3`=j6=4+1e;9<5=i9m21965f7883>!7c132;7c?k8;48?l1?290/=i75819m5a>=?21b;:4?:%3g=?>73g;o4764;h55>5<#9m314=5a1e:9=>=n?<0;6)?k9;:3?k7c03k07d9;:18'5a?=091e=i65b:9j37<72-;o576?;o3g<?e<3`=:6=4+1e;9<5=i9m21h65f7183>!7c132;7c?k8;g8?l0a290/=i75819m5a>=n21b:h4?:%3g=?>73g;o47??;:k5`?6=,8n265>4n0f;>47<3`<h6=4+1e;9<5=i9m21=?54i7`94?"6l003<6`>d9827>=n>h0;6)?k9;:3?k7c03;?76g99;29 4b>21:0b<j7:078?l>?290/=i75819m5a>=9?10e5950;&2`<<?82d:h54>7:9j<3<72-;o576?;o3g<?7?32c397>5$0f:>=6<f8n36<74;h:7>5<#9m314=5a1e:95d=<a191<7*>d88;4>h6l10:n65f8383>!7c132;7c?k8;3`?>o0m3:1(<j6:928j4b?28n07d9<:18'5a?=091e=i651d98m3>=83.:h4470:l2`=<6n21b4i4?:%3g=?>d3g;o47>4;h:a>5<#9m314n5a1e:95>=n0h0;6)?k9;:`?k7c03807d66:18'5a?=0j1e=i653:9j=7<72-;o577>;o3g<?6<3`3;6=4+1e;9=4=i9m21=65f8g83>!7c133:7c?k8;08?l>b290/=i75909m5a>=;21b=k=50;&2`<<6n;1e=i650:9j5c7=83.:h44>f39m5a>=921b=k>50;&2`<<6n;1e=i652:9j5``=83.:h44>f39m5a>=;21b=k650;&2`<<6n>1e=i650:9j5c0=83.:h44>f69m5a>=921b=k;50;&2`<<6n>1e=i652:9j5c2=83.:h44>f69m5a>=;21dmn4?:%3g=?ge3g;o47>4;ncb>5<#9m31mo5a1e:95>=hi10;6)?k9;ca?k7c03807bo8:18'5a?=ik1e=i653:9le3<72-;o57om;o3g<?2<3fk>6=4+1e;9eg=i9m21965`a583>!7c13ki7c?k8;48?jg4290/=i75ac9m5a>=?21dm?4?:%3g=?ge3g;o4764;nc2>5<#9m31mo5a1e:9=>=hi90;6)?k9;ca?k7c03k07b7i:18'5a?=ik1e=i65b:9l=a<72-;o57om;o3g<?e<3f3h6=4+1e;9eg=i9m21h65`9c83>!7c13ki7c?k8;g8?j?f290/=i75ac9m5a>=n21d544?:%3g=?ge3g;o47??;:m:<?6=,8n26ll4n0f;>47<3f3<6=4+1e;9eg=i9m21=?54o8494?"6l00jn6`>d9827>=h1<0;6)?k9;ca?k7c03;?76a64;29 4b>2hh0b<j7:078?jd4290/=i75ac9m5a>=9?10co<50;&2`<<fj2d:h54>7:9lf4<72-;o57om;o3g<?7?32ei<7>5$0f:>dd<f8n36<74;nce>5<#9m31mo5a1e:95d=<gho1<7*>d88bf>h6l10:n65`ae83>!7c13ki7c?k8;3`?>if13:1(<j6:``8j4b?28n07b7j:18'5a?=ik1e=i651d98k<5=83.:h44nb:l2`=<6n21doh4?:%3g=?ec3g;o47>4;na`>5<#9m31oi5a1e:95>=hkh0;6)?k9;ag?k7c03807bm6:18'5a?=km1e=i653:9lg=<72-;o57mk;o3g<?2<3fi<6=4+1e;9ga=i9m21965`c783>!7c13io7c?k8;48?je2290/=i75ce9m5a>=?21do94?:%3g=?ec3g;o4764;na0>5<#9m31oi5a1e:9=>=hk;0;6)?k9;ag?k7c03k07bm>:18'5a?=km1e=i65b:9lfc<72-;o57mk;o3g<?e<3fhn6=4+1e;9ga=i9m21h65`be83>!7c13io7c?k8;g8?jdd290/=i75ce9m5a>=n21dno4?:%3g=?ec3g;o47??;:mae?6=,8n26nj4n0f;>47<3fh26=4+1e;9ga=i9m21=?54oc:94?"6l00hh6`>d9827>=hj>0;6)?k9;ag?k7c03;?76am6;29 4b>2jn0b<j7:078?jb2290/=i75ce9m5a>=9?10ci:50;&2`<<dl2d:h54>7:9l`6<72-;o57mk;o3g<?7?32eo>7>5$0f:>fb<f8n36<74;nf2>5<#9m31oi5a1e:95d=<gm:1<7*>d88``>h6l10:n65`cg83>!7c13io7c?k8;3`?>idj3:1(<j6:bf8j4b?28n07bm?:18'5a?=km1e=i651d98kg3=83.:h44ld:l2`=<6n21dho4?:%3g=?bf3g;o47>4;nf:>5<#9m31hl5a1e:95>=hl10;6)?k9;fb?k7c03807bj8:18'5a?=lh1e=i653:9la5<72-;o57ji;o3g<?6<3fnn6=4+1e;9`c=i9m21=65`de83>!7c13nm7c?k8;08?jbd290/=i75dg9m5a>=;21vn<k6:18`6?6=8r.:i54>d`9K5cc<@8oh7W=l:by4>=<e2j0:?7?;:07953<a28:1=:4>8;mf1<73gn=6=5+13g96>"6:o097)k9:29'a2<43-o36>5+e880?!cf2:1/io4<;%3f5?c43-;n87<4$dg97>"bn390(k>53:&e5?5<,o81?6*i3;18 c2=;2.m97=4$g497>"a?390(k653:&e=?5<,ok1?6*ib;18 ce=;2.mh7=4$gg97>"an390(<>?:29'557=;2.:<?4<;%337?5<,8:?6>5+11797>"68?087)??7;18 46?2:1/==753:&24d<43-;;n7=4$02`>6=#99n1?6*>0d80?!77n390(<??:29'547=;2.:=?4<;%327?5<,8;?6>5+10797>"69?087)?>7;18 47?2:1/=<753:&25d<43-;:n7=4$03`>6=#98n1?6*>1d80?!76n390(<<?:29'577=;2.:>?4<;%317?5<,88?6>5+13797>"6:?087)?=7;18 44?2:1/=?753:&26d<43-;9n7=4$00`>6=#9;n1?6*>3182`6=#9:;1i>5+1209a6=#9mh1=i=4$0f`>4b43g;oh7?=;o3ga?753-;n>7=n;%g`>6=#mm087)?i9;3g0>"6nh0:h95a1g`957=i9oi1=?5+1d796>o4l3:17d=j:188m14=831b8>4?::kf5?6=3`;oj7>5;h3f4?6=3`o96=44i0g5>5<<a8o<6=44o2d94?=h<90;66g=0;29 4b>28l0b<j7:198m4c=83.:h44>f:l2`=<632c:h7>5$0f:>4`<f8n36?54i0a94?"6l00:j6`>d980?>o6j3:1(<j6:0d8j4b?2=10e?750;&2`<<6n2d:h54:;:k1<?6=,8n26<h4n0f;>3=<a;=1<7*>d882b>h6l10<76g=6;29 4b>28l0b<j7:998m73=83.:h44>f:l2`=<>32c987>5$0f:>4`<f8n36l54i3194?"6l00:j6`>d98a?>o5:3:1(<j6:0d8j4b?2j10e??50;&2`<<6n2d:h54k;:k2e?6=,8n26<h4n0f;>`=<a::1<7*>d881b>h6l10;76g=e;29 4b>2;l0b<j7:098m7b=83.:h44=f:l2`=<532c9o7>5$0f:>7`<f8n36>54i3`94?"6l009j6`>d987?>o413:1(<j6:3d8j4b?2<10e>650;&2`<<5n2d:h549;:k03?6=,8n26?h4n0f;>2=<a:<1<7*>d881b>h6l10376g<5;29 4b>2;l0b<j7:898m62=83.:h44=f:l2`=<f32c8?7>5$0f:>7`<f8n36o54i2094?"6l009j6`>d98`?>o493:1(<j6:3d8j4b?2m10e?o50;&2`<<5n2d:h54j;:k54?6=,8n268h4n0f;>5=<a<o1<7*>d886b>h6l10:76g:c;29 4b>2<l0b<j7:398m0d=83.:h44:f:l2`=<432c>m7>5$0f:>0`<f8n36954i4;94?"6l00>j6`>d986?>o203:1(<j6:4d8j4b?2?10e8950;&2`<<2n2d:h548;:k62?6=,8n268h4n0f;>==<a<?1<7*>d886b>h6l10276g:4;29 4b>2<l0b<j7:`98m05=83.:h44:f:l2`=<e32c>=7>5$0f:>0`<f8n36n54i4294?"6l00>j6`>d98g?>o3n3:1(<j6:4d8j4b?2l10e9k50;&2`<<2n2d:h54i;:k7`?6=,8n268h4n0f;>46<3`>h6=4+1e;91c=i9m21=<54i5`94?"6l00>j6`>d9826>=n<h0;6)?k9;7e?k7c03;876g;9;29 4b>2<l0b<j7:068?l2?290/=i755g9m5a>=9<10e;950;&2`<<2n2d:h54>6:9j23<72-;o57;i;o3g<?7032c=97>5$0f:>0`<f8n36<64;h47>5<#9m319k5a1e:95<=<a?91<7*>d886b>h6l10:m65f6383>!7c13?m7c?k8;3a?>o193:1(<j6:4d8j4b?28i07d;k:18'5a?==o1e=i651e98m04=83.:h44:f:l2`=<6m21b8:4?:%3g=?3a3g;o47?i;:k;5?6=,8n265>4n0f;>5=<a>l1<7*>d88;4>h6l10:76g8d;29 4b>21:0b<j7:398m2e=83.:h4470:l2`=<432c<n7>5$0f:>=6<f8n36954i6c94?"6l003<6`>d986?>o013:1(<j6:928j4b?2?10e:650;&2`<<?82d:h548;:k43?6=,8n265>4n0f;>==<a><1<7*>d88;4>h6l10276g85;29 4b>21:0b<j7:`98m22=83.:h4470:l2`=<e32c<>7>5$0f:>=6<f8n36n54i6394?"6l003<6`>d98g?>o083:1(<j6:928j4b?2l10e;h50;&2`<<?82d:h54i;:k5a?6=,8n265>4n0f;>46<3`<o6=4+1e;9<5=i9m21=<54i7a94?"6l003<6`>d9826>=n>k0;6)?k9;:3?k7c03;876g9a;29 4b>21:0b<j7:068?l0>290/=i75819m5a>=9<10e5650;&2`<<?82d:h54>6:9j<2<72-;o576?;o3g<?7032c3:7>5$0f:>=6<f8n36<64;h:6>5<#9m314=5a1e:95<=<a1>1<7*>d88;4>h6l10:m65f8283>!7c132;7c?k8;3a?>o?:3:1(<j6:928j4b?28i07d9j:18'5a?=091e=i651e98m25=83.:h4470:l2`=<6m21b:54?:%3g=?>73g;o47?i;:k;`?6=,8n265m4n0f;>5=<a1h1<7*>d88;g>h6l10:76g7a;29 4b>21i0b<j7:398m=?=83.:h447c:l2`=<432c2>7>5$0f:><7<f8n36=54i8294?"6l002=6`>d982?>o?n3:1(<j6:838j4b?2;10e5k50;&2`<<>92d:h54<;:k2b6<72-;o57?i2:l2`=<732c:j<4?:%3g=?7a:2d:h54>;:k2b5<72-;o57?i2:l2`=<532c:ik4?:%3g=?7a:2d:h54<;:k2b=<72-;o57?i7:l2`=<732c:j;4?:%3g=?7a?2d:h54>;:k2b0<72-;o57?i7:l2`=<532c:j94?:%3g=?7a?2d:h54<;:mbg?6=,8n26ll4n0f;>5=<ghk1<7*>d88bf>h6l10:76an8;29 4b>2hh0b<j7:398kd1=83.:h44nb:l2`=<432ej:7>5$0f:>dd<f8n36954o`794?"6l00jn6`>d986?>if<3:1(<j6:``8j4b?2?10cl=50;&2`<<fj2d:h548;:mb6?6=,8n26ll4n0f;>==<gh;1<7*>d88bf>h6l10276an0;29 4b>2hh0b<j7:`98k<`=83.:h44nb:l2`=<e32e2h7>5$0f:>dd<f8n36n54o8a94?"6l00jn6`>d98g?>i>j3:1(<j6:``8j4b?2l10c4o50;&2`<<fj2d:h54i;:m:=?6=,8n26ll4n0f;>46<3f336=4+1e;9eg=i9m21=<54o8594?"6l00jn6`>d9826>=h1?0;6)?k9;ca?k7c03;876a65;29 4b>2hh0b<j7:068?j?3290/=i75ac9m5a>=9<10co=50;&2`<<fj2d:h54>6:9lf7<72-;o57om;o3g<?7032ei=7>5$0f:>dd<f8n36<64;n`3>5<#9m31mo5a1e:95<=<ghl1<7*>d88bf>h6l10:m65`ad83>!7c13ki7c?k8;3a?>ifl3:1(<j6:``8j4b?28i07bo6:18'5a?=ik1e=i651e98k<c=83.:h44nb:l2`=<6m21d5>4?:%3g=?ge3g;o47?i;:m`a?6=,8n26nj4n0f;>5=<gji1<7*>d88``>h6l10:76ala;29 4b>2jn0b<j7:398kf?=83.:h44ld:l2`=<432eh47>5$0f:>fb<f8n36954ob594?"6l00hh6`>d986?>id>3:1(<j6:bf8j4b?2?10cn;50;&2`<<dl2d:h548;:m`0?6=,8n26nj4n0f;>==<gj91<7*>d88``>h6l10276al2;29 4b>2jn0b<j7:`98kf7=83.:h44ld:l2`=<e32eij7>5$0f:>fb<f8n36n54ocg94?"6l00hh6`>d98g?>iel3:1(<j6:bf8j4b?2l10com50;&2`<<dl2d:h54i;:maf?6=,8n26nj4n0f;>46<3fhj6=4+1e;9ga=i9m21=<54oc;94?"6l00hh6`>d9826>=hj10;6)?k9;ag?k7c03;876am7;29 4b>2jn0b<j7:068?jd1290/=i75ce9m5a>=9<10ci;50;&2`<<dl2d:h54>6:9l`1<72-;o57mk;o3g<?7032eo?7>5$0f:>fb<f8n36<64;nf1>5<#9m31oi5a1e:95<=<gm;1<7*>d88``>h6l10:m65`d183>!7c13io7c?k8;3a?>idn3:1(<j6:bf8j4b?28i07bmm:18'5a?=km1e=i651e98kf6=83.:h44ld:l2`=<6m21dn84?:%3g=?ec3g;o47?i;:mgf?6=,8n26io4n0f;>5=<gm31<7*>d88ge>h6l10:76ak8;29 4b>2mk0b<j7:398ka1=83.:h44ka:l2`=<432en<7>5$0f:>a`<f8n36=54oeg94?"6l00oj6`>d982?>icl3:1(<j6:ed8j4b?2;10cim50;&2`<<cn2d:h54<;:p717=83=8wS<<2:\004=:9ol1i9521dc97a=:9lk1?h521dc95a`<58oj6<k?;<3fe?7b>27:il4>e69>5`g=:916=ho5229>5`g=:;16=ho5209>5`g=9h16=ho5319>5`g=;:16=ho5339>5`g=;816=ho52`9>5`g=>916=ho55d9>5`g==j16=ho55c9>5`g==h16=ho5589>5`g==116=ho5569>5`g==?16=ho5549>5`g===16=ho5529>5`g==816=ho5519>5`g=<o16=ho54d9>5`g=<m16=ho5649>5`g=0816=ho57g9>5`g=?m16=ho57b9>5`g=?k16=ho57`9>5`g=?016=ho5799>5`g=?>16=ho5779>5`g=?<16=ho5759>5`g=?;16=ho5709>5`g=?916=ho56g9>5`g=>l16=ho5879>5`g=0m16=ho58c9>5`g=0h16=ho5889>5`g=1;16=ho5919>5`g=0o16=ho58d9>5`?=;m16=h753d9>5`?=9ml01<k6:0g3?87b13;n:63>e882a2=:9l31>=521d;966=:9l31>?521d;964=:9l31=l521d;975=:9l31?>521d;977=:9l31?<521d;96d=:9l31:=521d;91`=:9l319n521d;91g=:9l319l521d;91<=:9l3195521d;912=:9l319;521d;910=:9l3199521d;916=:9l319<521d;915=:9l318k521d;90`=:9l314<521d;93c=:9l31;i521d;93f=:9l31;o521d;93d=:9l31;4521d;93==:9l31;:521d;933=:9l31;8521d;931=:9l31;?521d;934=:9l31;=521d;92c=:9l314i521d;9<g=:9l315?521d;9=5=z{:936=4<{_10<>;6mh0n=63>e88f5>{t;:31<7=t^21:?87bi3o970?j9;g1?xu5;90;6>uQ222894cf2=801<k6:508yv4493:1?vP=309>5`g=<:16=h75429~w7cb2909wS<le:?2ad<>02wx>hm50;0xZ7ec34;nm778;|q1ad<72;qU>nl4=0gb><0<uz8n57>52z\1gd=:9lk1585rs3g;>5<5sW8h563>e`8:0>{t:l=1<7<t^3a;?87bi3h87p}=e783>7}Y:j=01<kn:c08yv4b=3:1>vP=c79>5`g=j91v?k;:181[4d=27:il4nf:p6`5=838pR?m;;<3fe?gb3ty9i?4?:3y]6f5<58oj6lj4}r0f5?6=:rT9o?521dc9e<=z{;nm6=4={_0`4>;6mh02i6s|2eg94?4|V;hm70?ja;;0?xu5lm0;6?uQ2cg894c>2m20q~<kc;296~X5jm16=h75989~w7be2909wS<mc:?2a<<>02wx>io50;0xZ7de34;n5778;|q1`<<72;qU>oo4=0g:><0<uz8o47>52z\1f<=:9l31585rs3f4>5<5sW8i463>e88:0>{t:m<1<7<t^3`4?87b13h87p}=f483>7}Y:m>01<k6:c08yv4a<3:1>vP=d29>5`?=l>1v?h<:181[4c:27:i44m1:p6c4=838pR?j>;<3f=?d73ty9j<4?:3y]6a6<58o26lh4}r0e4?6=:rT9ok521d;9e`=z{;om6=4={_0`g>;6m00jh6s|2d`94?4|V;i:70?j9;c:?xu5m90;6?uQ2c4894c>20o0q~<k5;296~X5j<16=h75929~w64a2909wS=?f:?2ad<ei2wx??j50;0xZ66b34;nm7l6;|q06g<72;qU?=m4=0gb>g><uz99m7>52z\04g=:9lk1n:5rs20:>5<5sW9;m63>e`8a2>{t;;21<7<t^22:?87bi3n>7p}<2683>7}Y;9201<kn:e68yv55>3:1>vP<069>5`g=l;1v><::181[57>27:il4k1:p772=838pR>>:;<3fe?b73ty8>>4?:3y]752<58oj6nh4}r116?6=:rT8<>521dc9gg=z{:8;6=4={_135>;6mh0h<6s|30d94?4|V::;70?ja;`6?xu49l0;6?uQ2gd894c>2mn0q~=>d;296~X5nl16=h75bc9~w67d2909wS<id:?2a<<ei2wx?<l50;0xZ7`d34;n57l6;|q05d<72;qU>kl4=0g:>g><uz9:57>52z\1bd=:9l31n:5rs23;>5<5sW8m563>e88a2>{t;8=1<7<t^3d;?87b13n>7p}<3783>7}Y;8?01<k6:e68yv54=3:1>vP<159>5`?=lj1v>=;:181[56;27:i44k3:p765=838pR>?=;<3f=?b53ty8??4?:3y]747<58o26i?4}r105?6=:rT8==521d;9`5=z{:9;6=4={_13`>;6m00hj6s|33a94?4|V::970?j9;aa?xu4:80;6?uQ2g5894c>2j:0q~=>6;296~X5n?16=h75b49~w6212902wS=;4:?2ad<6n:16=ho51g3894cf28l;70?ja;3fb>;6m00:j>521d;95c7<58o26<h?;<3f=?7bn2wx?9750;;xZ62034;nm7?i8:?2ad<6n?16=ho51g7894cf28l?70?j9;3e<>;6m00:j;521d;95c3<58o26<h;;|q15<<72:qU>=k4=0gb>4c<58o26<k4}r023?6=;rT9<i521dc95a=:9l31=i5rs335>5<4sW8;o63>e`82g>;6m00:o6s|20794?5|V;:i70?ja;3a?87b13;i7p}=1583>6}Y:9k01<kn:3;894c>2;30q~<>3;297~X58016=ho5299>5`?=:11v??=:180[47027:il4=7:?2a<<5?2wx><?50;1xZ76034;nm7<9;<3f=?413ty9==4?:2y]650<58oj6?;4=0g:>73<uz8;j7>53z\140=:9lk1>9521d;961=z{;8n6=4<{_017>;6mh09i63>e881a>{t:;i1<7=t^301?87bi38o70?j9;0g?xu5:k0;6>uQ233894cf2;i01<k6:3a8yv45i3:1?vP=219>5`g=:k16=h752c9~w74>2908wS<>f:?2ad<4127:i44<9:p67>=839pR??j;<3fe?5?34;n57=7;|q162<72:qU><j4=0gb>61<58o26>94}r012?6=;rT9=n521dc973=:9l31?;5rs306>5<4sW8:n63>e`801>;6m00896s|23694?5|V;;j70?ja;17?87b139?7p}=6b83>7}Y:=i01<kn:5a8yv41i3:1>vP=4c9>5`g=<k1v?87:181[43127:il4;a:p631=838pR?:7;<3fe?2>3ty9:;4?:3y]611<58oj6964}r051?6=:rT98;521dc922=z{;<?6=4={_071>;6mh0=:6s|27194?4|V;>?70?ja;47?xu5>;0;6?uQ251894cf2?90q~<91;296~X5<;16=ho5639~w7072909wS<;1:?2ad<192wx>8h50;0xZ72734;nm7;k;|q11a<72;qU>>k4=0gb>04<uz8>o7>52z\17a=:9lk18:5rs37a>5<5sW88o63>e88;e>{t:<k1<7<t^31a?87b13>o7p}=5883>7}Y::k01<k6:5a8yv4203:1>vP=389>5`?=<k1v?;8:181[44027:i44;a:p600=838pR?=8;<3f=?2>3ty9984?:3y]660<58o26964}r060?6=:rT9?8521d;922=z{;=86=4={_066>;6m00=:6s|26094?4|V;?:70?j9;::?xu5?80;6?uQ242894c>2??0q~<80;296~X5<o16=h75659~w70a2909wS<;e:?2a<<1;2wx>;k50;0xZ72c34;n578=;|q12a<72;qU>9o4=0g:>37<uz8=57>52z\17c=:9l319i5rs37f>5<5sW88863>e8866>{t:<91<7<t^310?87b13><7p}=ae83>7}Y:1n01<kn:7f8yv4fj3:1>vP=8b9>5`g=>j1v?o6:181[4?i27:il49b:p6d>=838pR?66;<3fe?0f3ty9m:4?:3y]6=><58oj6;74}r0b2?6=:rT94:521dc9<==z{;k>6=4={_0;2>;6mh03;6s|2`694?4|V;2>70?ja;:6?xu5i:0;6?uQ296894cf21>0q~<n2;296~X50:16=ho5829~w7g62909wS<72:?2ad<?:2wx>l>50;0xZ7>634;nm79j;|q1=`<72;qU>:h4=0gb>25<uz82h7>52z\13`=:9lk1:55rs3;`>5<5sW8<h63>e88;b>{t:0h1<7<t^35`?87b13<n7p}=9`83>7}Y:>h01<k6:7f8yv4>13:1>vP=7`9>5`?=>j1v?77:181[40127:i449b:p6<1=838pR?97;<3f=?0f3ty95;4?:3y]621<58o26;74}r0:1?6=:rT9;;521d;9<==z{;h?6=4={_0:7>;6m003;6s|2c194?4|V;3970?j9;:f?xu5j;0;6?uQ283894c>21<0q~<m1;296~X51916=h75849~w7d72909wS<7f:?2a<<?<2wx>lh50;0xZ7>b34;n576<;|q1e`<72;qU>5l4=0g:>=4<uz8jm7>52z\1<5=:9l31;h5rs3;e>5<5sW8<963>e8847>{t:0>1<7<t^357?87b13<37ps|22294?4|V;9;70=m:313?!7bj3;<n6s|27a94?4|V;>h70=m:36`?!7bj3;3:6s|27c94?4|V;>i70=m:36a?!7bj3;2=6s|27:94?4|V;>270=m:36:?!7bj3;2m6s|27594?4|V;>370=m:36;?!7bj3;j96s|27494?4|V;><70=m:364?!7bj3;i<6s|27794?4|V;>=70=m:365?!7bj3;in6s|27694?4|V;>>70=m:366?!7bj3;h:6s|27194?4|V;>?70=m:367?!7bj3;8;6s|27094?4|V;>870=m:360?!7bj3;?>6s|27394?4|V;>970=m:361?!7bj3;?h6s|27294?4|V;>:70=m:362?!7bj3;>:6s|24d94?4|V;>;70=m:363?!7bj3;==6s|24f94?4|V;9n70=m:31f?!7bj3;=o6s|24a94?4|V;9o70=m:31g?!7bj3;<;6s|24`94?4|V;9h70=m:31`?!7bj3;<46s|24c94?4|V;9i70=m:31a?!7bj3;<56s|24;94?4|V;9j70=m:31b?!7bj3;<m6s|24:94?4|V;9270=m:31:?!7bj3;<o6s|24594?4|V;9370=m:31;?!7bj3;<h6s|24494?4|V;9<70=m:314?!7bj3;<i6s|24794?4|V;9=70=m:315?!7bj3;<j6s|24694?4|V;9>70=m:316?!7bj3;3<6s|26194?4|V;?970=m:371?!7bj3;3=6s|26094?4|V;?:70=m:372?!7bj3;3>6s|26394?4|V;?;70=m:373?!7bj3;3?6s|26294?4|V;>m70=m:36e?!7bj3;386s|27d94?4|V;>n70=m:36f?!7bj3;396s|27g94?4|V;>o70=m:36g?!7bj3;3;6s|27f94?4|V;>j70=m:36b?!7bj3;346s|27;94?4|V;9m70=m:31e?!7bj3;356s|24g94?4|V;9?70=m:317?!7bj3;3m6s|24194?4|V;9870=m:310?!7bj3;3n6s|20;94?4|V;:n70=m:32f?!7bj3;3o6s|20594?4|V;:o70=m:32g?!7bj3;3h6s|20494?4|V;:h70=m:32`?!7bj3;3i6s|20794?4|V;:i70=m:32a?!7bj3;3j6s|20694?4|V;:j70=m:32b?!7bj3;2<6s|20194?4|V;:270=m:32:?!7bj3;2>6s|20094?4|V;:370=m:32;?!7bj3;2?6s|20394?4|V;:<70=m:324?!7bj3;286s|20294?4|V;:=70=m:325?!7bj3;296s|21d94?4|V;:>70=m:326?!7bj3;2:6s|32:94?4|V:9370=m:21;?!7bj3;2;6s|35494?4|V:>?70=m:267?!7bj3;246s|2dg94?4|V;in70=m:3af?!7bj3;256s|2da94?4|V;io70=m:3ag?!7bj3;2n6s|2dc94?4|V;ii70=m:3aa?!7bj3;2o6s|2d;94?4|V;ij70=m:3ab?!7bj3;2h6s|2d:94?4|V;i270=m:3a:?!7bj3;2i6s|2d594?4|V;i370=m:3a;?!7bj3;2j6s|2d494?4|V;i<70=m:3a4?!7bj3;j<6s|2d794?4|V;i=70=m:3a5?!7bj3;j=6s|2d694?4|V;i>70=m:3a6?!7bj3;j>6s|2d194?4|V;i?70=m:3a7?!7bj3;j?6s|2d094?4|V;i870=m:3a0?!7bj3;j86s|2d394?4|V;i970=m:3a1?!7bj3;j:6s|2ed94?4|V;i;70=m:3a3?!7bj3;j;6s|2eg94?4|V;hm70=m:3`e?!7bj3;j46s|2ef94?4|V;hn70=m:3`f?!7bj3;j56s|2ea94?4|V;ho70=m:3`g?!7bj3;jm6s|2e`94?4|V;hh70=m:3``?!7bj3;jn6s|2ec94?4|V;hi70=m:3`a?!7bj3;jo6s|2e;94?4|V;hj70=m:3`b?!7bj3;jh6s|2e:94?4|V;h270=m:3`:?!7bj3;ji6s|2e594?4|V;h370=m:3`;?!7bj3;jj6s|2e494?4|V;h<70=m:3`4?!7bj3;i=6s|2g794?4|V;n?70=m:3f7?!7bj3;i>6s|2g694?4|V;n870=m:3f0?!7bj3;i?6s|2g194?4|V;n970=m:3f1?!7bj3;i86s|2g094?4|V;n:70=m:3f2?!7bj3;i96s|2g394?4|V;n;70=m:3f3?!7bj3;i:6s|2g294?4|V;im70=m:3ae?!7bj3;i;6s|2dd94?4|V;ih70=m:3a`?!7bj3;i46s|2d`94?4|V;i:70=m:3a2?!7bj3;i56s|2d294?4|V;h=70=m:3`5?!7bj3;im6s|2e794?4|V;h>70=m:3`6?!7bj3;io6s|22394?4|V;9:70=m:312?!7bj3;ih6s|2`f94?4|V;2o70=m:3:g?!7bj3;ii6s|2``94?4|V;2h70=m:3:`?!7bj3;ij6s|2`;94?4|V;2j70=m:3:b?!7bj3;h<6s|2`:94?4|V;2270=m:3::?!7bj3;h=6s|2`594?4|V;2370=m:3:;?!7bj3;h>6s|2`494?4|V;2<70=m:3:4?!7bj3;h?6s|2`794?4|V;2=70=m:3:5?!7bj3;h86s|2`694?4|V;2>70=m:3:6?!7bj3;h96s|2`194?4|V;2?70=m:3:7?!7bj3;h;6s|2`094?4|V;2870=m:3:0?!7bj3;h46s|2`394?4|V;2970=m:3:1?!7bj3;h56s|2`294?4|V;2:70=m:3:2?!7bj3;hm6s|28g94?4|V;=m70=m:35e?!7bj3;hn6s|28f94?4|V;=n70=m:35f?!7bj3;ho6s|28a94?4|V;=o70=m:35g?!7bj3;hh6s|28`94?4|V;=h70=m:35`?!7bj3;hi6s|28c94?4|V;=i70=m:35a?!7bj3;hj6s|28;94?4|V;=j70=m:35b?!7bj3;o<6s|28:94?4|V;=270=m:35:?!7bj3;846s|28594?4|V;=370=m:35;?!7bj3;856s|28494?4|V;=<70=m:354?!7bj3;8m6s|28794?4|V;==70=m:355?!7bj3;8n6s|2c694?4|V;3870=m:3;0?!7bj3;8o6s|2c194?4|V;3970=m:3;1?!7bj3;8h6s|2c094?4|V;3:70=m:3;2?!7bj3;8i6s|2c394?4|V;3;70=m:3;3?!7bj3;8j6s|2c294?4|V;2m70=m:3:e?!7bj3;?<6s|2`d94?4|V;2n70=m:3:f?!7bj3;?=6s|2`g94?4|V;2i70=m:3:a?!7bj3;??6s|2`c94?4|V;2;70=m:3:3?!7bj3;?86s|28d94?4|V;=>70=m:356?!7bj3;?96s|28694?4|V;=?70=m:357?!7bj3;?:6s|23g94?4|V;8870=m:300?!7bj3;?;6s|23a94?4|V;8970=m:301?!7bj3;?46s|23`94?4|V;8:70=m:302?!7bj3;?56s|23c94?4|V;8;70=m:303?!7bj3;?m6s|23;94?4|V;;m70=m:33e?!7bj3;?n6s|23:94?4|V;;n70=m:33f?!7bj3;?o6s|23594?4|V;;o70=m:33g?!7bj3;?i6s|23494?4|V;;h70=m:33`?!7bj3;?j6s|23794?4|V;;i70=m:33a?!7bj3;><6s|23694?4|V;;j70=m:33b?!7bj3;>=6s|32;94?4|V:9270=m:21:?!7bj3;>>6s|35;94?4|V:><70=m:264?!7bj3;>?6s|33d94?4|V::m70=m:22e?!7bj3;>86s|33f94?4|V::n70=m:22f?!7bj3;>96s|33`94?4|V::h70=m:22`?!7bj3;>;6s|33c94?4|V::i70=m:22a?!7bj3;>46s|33;94?4|V::j70=m:22b?!7bj3;>56s|33:94?4|V::270=m:22:?!7bj3;>m6s|33594?4|V::370=m:22;?!7bj3;>n6s|33494?4|V::<70=m:224?!7bj3;>o6s|33794?4|V::=70=m:225?!7bj3;>h6s|33694?4|V::>70=m:226?!7bj3;>i6s|33194?4|V::?70=m:227?!7bj3;>j6s|33094?4|V::870=m:220?!7bj3;=<6s|33294?4|V:::70=m:222?!7bj3;=>6s|30d94?4|V::;70=m:223?!7bj3;=?6s|30g94?4|V;lm70=m:3de?!7bj3;=86s|30f94?4|V;ln70=m:3df?!7bj3;=96s|30a94?4|V;lo70=m:3dg?!7bj3;=:6s|30`94?4|V;lh70=m:3d`?!7bj3;=;6s|30c94?4|V;li70=m:3da?!7bj3;=46s|30;94?4|V;lj70=m:3db?!7bj3;=56s|30:94?4|V;l270=m:3d:?!7bj3;=m6s|30594?4|V;l370=m:3d;?!7bj3;=n6s|32494?4|V:;>70=m:236?!7bj3;=h6s|32794?4|V:;?70=m:237?!7bj3;=i6s|32694?4|V:;870=m:230?!7bj3;=j6s|32194?4|V:;970=m:231?!7bj3;<<6s|32094?4|V:;:70=m:232?!7bj3;<=6s|32394?4|V:;;70=m:233?!7bj3;<>6s|32294?4|V::o70=m:22g?!7bj3;<?6s|33a94?4|V::970=m:221?!7bj3;<86s|33394?4|V;l<70=m:3d4?!7bj3;<96s|30494?4|V;l=70=m:3d5?!7bj3;<:6srn24g>5<5sA;no6sa37g94?4|@8oh7p`<6g83>7}O9li0qc=80;296~N6mj1vb>9>:181M7bk2we?:<50;0xL4cd3td8;>4?:3yK5`e<ug9<87>52zJ2af=zf:=>6=4={I3fg>{i;><1<7<tH0g`?xh4?>0;6?uG1da8yk5003:1>vF>eb9~j61>2909wE?jc:m72g=838pD<kl;|l03g<72;qC=hm4}o14g?6=:rB:in5rn25g>5<5sA;no6sa36g94?4|@8oh7p`<7g83>7}O9li0qc=70;296~N6mj1vb>6>:181M7bk2we?5<50;0xL4cd3td84>4?:3yK5`e<ug9387>52zJ2af=zf:2>6=4={I3fg>{i;1<1<7<tH0g`?xh40>0;6?uG1da8yk5?03:1>vF>eb9~j6>>2909wE?jc:m7=g=838pD<kl;|l0<g<72;qC=hm4}o1;g?6=:rB:in5rn2:g>5<5sA;no6sa39g94?4|@8oh7p`<8g83>7}O9li0qc=60;296~N6mj1vb>7>:181M7bk2we?4<50;0xL4cd3td85>4?:3yK5`e<ug9287>52zJ2af=zf:3>6=4={I3fg>{i;0<1<7<tH0g`?xh41>0;6?uG1da8yk5>03:1>vF>eb9~j6?>2909wE?jc:m7<g=838pD<kl;|l0=g<72;qC=hm4}o1:g?6=:rB:in5rn2;g>5<5sA;no6sa38g94?4|@8oh7p`<9g83>7}O9li0qc=n0;296~N6mj1vb>o>:181M7bk2we?l<50;0xL4cd3td8m>4?:3yK5`e<ug9j87>52zJ2af=zf:k>6=4={I3fg>{i;h<1<7<tH0g`?xh4i>0;6?uG1da8yk5f03:1>vF>eb9~j6g>2909wE?jc:m7dg=838pD<kl;|l0eg<72;qC=hm4}o1bg?6=:rB:in5rn2cg>5<5sA;no6sa3`g94?4|@8oh7p`<ag83>7}O9li0qc=m0;296~N6mj1vb>l>:181M7bk2we?o<50;0xL4cd3td8n>4?:3yK5`e<ug9i87>52zJ2af=zf:h>6=4={I3fg>{i;k<1<7<tH0g`?xh4j>0;6?uG1da8yk5e03:1>vF>eb9~j6d>2909wE?jc:m7gg=838pD<kl;|l0fg<72;qC=hm4}o1ag?6=:rB:in5rn2`g>5<5sA;no6sa3cg94?4|@8oh7p`<bg83>7}O9li0qc=l0;296~N6mj1vb>m>:181M7bk2we?n<50;0xL4cd3td8o>4?:3yK5`e<ug9h87>52zJ2af=zf:i>6=4={I3fg>{i;j<1<7<tH0g`?xh4k>0;6?uG1da8yk5d03:1>vF>eb9~j6e>2909wE?jc:m7fg=838pD<kl;|l0gg<72;qC=hm4}o1`g?6=:rB:in5rn2ag>5<5sA;no6sa3bg94?4|@8oh7p`<cg83>7}O9li0qc=k0;296~N6mj1vb>j>:181M7bk2we?i<50;0xL4cd3td8h>4?:3yK5`e<ug9o87>52zJ2af=zf:n>6=4={I3fg>{i;m<1<7<tH0g`?xh4l>0;6?uG1da8yk5c03:1>vF>eb9~j6b>2909wE?jc:m7ag=838pD<kl;|l0`g<72;qC=hm4}o1gg?6=:rB:in5rn2fg>5<5sA;no6sa3eg94?4|@8oh7p`<dg83>7}O9li0qc=j0;296~N6mj1vb>k>:181M7bk2we?h<50;0xL4cd3td8i>4?:3yK5`e<ug9n87>52zJ2af=zf:o>6=4={I3fg>{i;l<1<7<tH0g`?xh4m>0;6?uG1da8yk5b03:1>vF>eb9~j6c>2909wE?jc:m7`g=838pD<kl;|l0ag<72;qC=hm4}o1fg?6=:rB:in5rn2gg>5<5sA;no6sa3dg94?4|@8oh7p`<eg83>7}O9li0qc=i0;296~N6mj1vb>h>:181M7bk2we?k<50;0xL4cd3td8j>4?:3yK5`e<ug9m87>52zJ2af=zf:l>6=4={I3fg>{i;o<1<7<tH0g`?xh4n>0;6?uG1da8yk5a03:1>vF>eb9~j6`>2909wE?jc:m7cg=838pD<kl;|l0bg<72;qC=hm4}o1eg?6=:rB:in5rn2dg>5<5sA;no6sa3gg94?4|@8oh7p`<fg83>7}O9li0qc:?0;296~N6mj1vb9>>:181M7bk2we8=<50;0xL4cd3td?<>4?:3yK5`e<ug>;87>52zJ2af=zf=:>6=4={I3fg>{i<9<1<7<tH0g`?xh5l;0;6<uG1da8yx{zHIIp8l<5a76;e5c4uIJIw=sO@Qy~DE \ No newline at end of file diff --git a/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vhd b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vhd new file mode 100644 index 0000000000000000000000000000000000000000..80684cd1bdaed3da7666fc0238802063f58576d5 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vhd @@ -0,0 +1,145 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- You must compile the wrapper file pattern_blk_mem.vhd when simulating +-- the core, pattern_blk_mem. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + +-- The synthesis directives "translate_off/translate_on" specified +-- below are supported by Xilinx, Mentor Graphics and Synplicity +-- synthesis tools. Ensure they are correct for your synthesis tool(s). + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +-- synthesis translate_off +Library XilinxCoreLib; +-- synthesis translate_on +ENTITY pattern_blk_mem IS + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +END pattern_blk_mem; + +ARCHITECTURE pattern_blk_mem_a OF pattern_blk_mem IS +-- synthesis translate_off +component wrapped_pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; + +-- Configuration specification + for all : wrapped_pattern_blk_mem use entity XilinxCoreLib.blk_mem_gen_v2_8(behavioral) + generic map( + c_has_regceb => 0, + c_has_regcea => 0, + c_mem_type => 2, + c_prim_type => 1, + c_sinita_val => "0", + c_read_width_b => 32, + c_family => "virtex4", + c_read_width_a => 32, + c_disable_warn_bhv_coll => 0, + c_write_mode_b => "NO_CHANGE", + c_init_file_name => "no_coe_file_loaded", + c_write_mode_a => "NO_CHANGE", + c_mux_pipeline_stages => 0, + c_has_mem_output_regs_b => 0, + c_load_init_file => 0, + c_xdevicefamily => "virtex4", + c_has_mem_output_regs_a => 0, + c_write_depth_b => 1024, + c_write_depth_a => 1024, + c_has_ssrb => 0, + c_has_mux_output_regs_b => 0, + c_has_ssra => 0, + c_has_mux_output_regs_a => 0, + c_addra_width => 10, + c_addrb_width => 10, + c_default_data => "0", + c_use_ecc => 0, + c_algorithm => 1, + c_disable_warn_bhv_range => 0, + c_write_width_b => 32, + c_write_width_a => 32, + c_read_depth_b => 1024, + c_read_depth_a => 1024, + c_byte_size => 9, + c_sim_collision_check => "ALL", + c_use_ramb16bwer_rst_bhv => 0, + c_common_clk => 0, + c_wea_width => 1, + c_has_enb => 1, + c_web_width => 1, + c_has_ena => 1, + c_sinitb_val => "0", + c_use_byte_web => 0, + c_use_byte_wea => 0, + c_use_default_data => 1); +-- synthesis translate_on +BEGIN +-- synthesis translate_off +U0 : wrapped_pattern_blk_mem + port map ( + clka => clka, + dina => dina, + addra => addra, + ena => ena, + wea => wea, + douta => douta, + clkb => clkb, + dinb => dinb, + addrb => addrb, + enb => enb, + web => web, + doutb => doutb); +-- synthesis translate_on + +END pattern_blk_mem_a; + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vho b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vho new file mode 100644 index 0000000000000000000000000000000000000000..6c359283052d21874b2a497576e7a99728645a64 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.vho @@ -0,0 +1,74 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- The following code must appear in the VHDL architecture header: + +------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG +component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; + +-- COMP_TAG_END ------ End COMPONENT Declaration ------------ + +-- The following code must appear in the VHDL architecture +-- body. Substitute your own instance name and net names. + +------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG +your_instance_name : pattern_blk_mem + port map ( + clka => clka, + dina => dina, + addra => addra, + ena => ena, + wea => wea, + douta => douta, + clkb => clkb, + dinb => dinb, + addrb => addrb, + enb => enb, + web => web, + doutb => doutb); +-- INST_TAG_END ------ End INSTANTIATION Template ------------ + +-- You must compile the wrapper file pattern_blk_mem.vhd when simulating +-- the core, pattern_blk_mem. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.xco-outdated b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.xco-outdated new file mode 100644 index 0000000000000000000000000000000000000000..ef82ce5d639c037d9e3bd2816d3096049c4474e7 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/pattern_blk_mem.xco-outdated @@ -0,0 +1,78 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Mon Aug 17 20:38:30 2009 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator family Xilinx,_Inc. 2.8 +# END Select +# BEGIN Parameters +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=false +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=pattern_blk_mem +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET enable_a=Use_ENA_Pin +CSET enable_b=Use_ENB_Pin +CSET fill_remaining_memory_locations=true +CSET load_init_file=false +CSET memory_type=True_Dual_Port_RAM +CSET operating_mode_a=NO_CHANGE +CSET operating_mode_b=NO_CHANGE +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET primitive=8kx2 +CSET read_width_a=32 +CSET read_width_b=32 +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET remaining_memory_locations=0 +CSET single_bit_ecc=false +CSET use_byte_write_enable=false +CSET use_ramb16bwer_reset_behavior=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_ssra_pin=false +CSET use_ssrb_pin=false +CSET write_depth_a=1024 +CSET write_width_a=32 +CSET write_width_b=32 +# END Parameters +GENERATE +# CRC: d212e058 + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/triggerfifo.xco b/rce/fw-hsio/modules/pixelcore/coregen/triggerfifo.xco new file mode 100644 index 0000000000000000000000000000000000000000..6c39c9eb30c402d4e04c64e8749f0e8dcdb499c1 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/triggerfifo.xco @@ -0,0 +1,82 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Sat Apr 24 17:20:17 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 4.4 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=triggerfifo +CSET data_count=true +CSET data_count_width=8 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=2 +CSET empty_threshold_negate_value=3 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET fifo_implementation=Common_Clock_Block_RAM +CSET full_flags_reset_value=1 +CSET full_threshold_assert_value=254 +CSET full_threshold_negate_value=253 +CSET input_data_width=1 +CSET input_depth=256 +CSET output_data_width=1 +CSET output_depth=256 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=8 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=8 +# END Parameters +GENERATE +# CRC: 77b25bef + diff --git a/rce/fw-hsio/modules/pixelcore/coregen/xil_cores.cgp b/rce/fw-hsio/modules/pixelcore/coregen/xil_cores.cgp new file mode 100644 index 0000000000000000000000000000000000000000..fb23f88b6efde20fa9fa19dbc6e5d217d8d3cf6c --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/coregen/xil_cores.cgp @@ -0,0 +1,19 @@ +# Date: Wed Jan 26 19:09:37 2011 + +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -11 +SET verilogsim = false +SET vhdlsim = true diff --git a/rce/fw-hsio/modules/pixelcore/hdl/BiphaseMarkEncoder.vhd b/rce/fw-hsio/modules/pixelcore/hdl/BiphaseMarkEncoder.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5c709552d1170a28fff51e8e456f20c7bc24770e --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/BiphaseMarkEncoder.vhd @@ -0,0 +1,41 @@ + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity bpmencoder is + port ( + clock : in std_logic; + rst : in std_logic; + clockx2 : in std_logic; + datain : in std_logic; + encode : in std_logic; + dataout : out std_logic + ); +end bpmencoder; + +architecture BPMENCODER of bpmencoder is + + signal bmp: std_logic; + +begin + + process(clockx2, rst) + begin + if(rst='1') then + bmp<='0'; + elsif(clockx2'event and clockx2='1') then + if(clock='1' or datain='1')then + bmp<=not bmp; + end if; + end if; + end process; + + with encode select + dataout<= datain when '0', + bmp when '1', + datain when others; + +end BPMENCODER; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/DisplayCharacters.vhd b/rce/fw-hsio/modules/pixelcore/hdl/DisplayCharacters.vhd new file mode 100755 index 0000000000000000000000000000000000000000..55e7e2521f4a993b392677789afd5dbaae14effa --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/DisplayCharacters.vhd @@ -0,0 +1,126 @@ +------------------------------------------------------------------------------- +-- Title : OSRAM SCDV5540 Display Controller Characters +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : DisplayCharacters.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 12/06/2007 +------------------------------------------------------------------------------- +-- Description: +-- Package for display chracter lookup table. +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 12/06/2007: created. +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package DisplayCharacters is + + -- Types For Character Lookup + subtype DISPCHAR is STD_LOGIC_VECTOR(24 downto 0); + type DISPTABLE is array ( NATURAL range <> ) of DISPCHAR; + + -- Constants For Charactors + constant DISPMAX : natural := 18; + constant DISPLOOKUP : DISPTABLE := ( + 0 => "01110" & -- Hex 0 + "10011" & + "10101" & + "11001" & + "01110", + 1 => "00100" & -- Hex 1 + "01100" & + "00100" & + "00100" & + "11111", + 2 => "11110" & -- Hex 2 + "00001" & + "00110" & + "01000" & + "11111", + 3 => "11110" & -- Hex 3 + "00001" & + "01110" & + "00001" & + "11110", + 4 => "00110" & -- Hex 4 + "01010" & + "11111" & + "00010" & + "00010", + 5 => "11111" & -- Hex 5 + "10000" & + "11110" & + "00001" & + "11110", + 6 => "00110" & -- Hex 6 + "01000" & + "11110" & + "10001" & + "01110", + 7 => "11111" & -- Hex 7 + "00010" & + "00100" & + "01000" & + "01000", + 8 => "01110" & -- Hex 8 + "10001" & + "01110" & + "10001" & + "01110", + 9 => "01110" & -- Hex 9 + "10001" & + "01111" & + "00010" & + "01100", + 10 => "00100" & -- Hex A + "01010" & + "11111" & + "10001" & + "10001", + 11 => "11110" & -- Hex B + "01001" & + "01110" & + "01001" & + "11110", + 12 => "01111" & -- Hex C + "10000" & + "10000" & + "10000" & + "11111", + 13 => "11110" & -- Hex D + "01001" & + "01001" & + "01001" & + "11110", + 14 => "11111" & -- Hex E + "10000" & + "11111" & + "10000" & + "11111", + 15 => "11111" & -- Hex F + "10000" & + "11110" & + "10000" & + "10000", + 16 => "11110" & -- State P = No PLL Lock + "10001" & + "11110" & + "10000" & + "10000", + 17 => "10001" & -- State N = No Link + "11001" & + "10101" & + "10011" & + "10001", + 18 => "10000" & -- State L = Link + "10000" & + "10000" & + "10000" & + "11111" + ); + +end DisplayCharacters; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/DisplayControl.vhd b/rce/fw-hsio/modules/pixelcore/hdl/DisplayControl.vhd new file mode 100755 index 0000000000000000000000000000000000000000..693ab82426bde4945f9e50da7ca91b98c4d642bb --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/DisplayControl.vhd @@ -0,0 +1,260 @@ +------------------------------------------------------------------------------- +-- Title : OSRAM SCDV5540 Display Controller +-- Project : General Purpose Core +------------------------------------------------------------------------------- +-- File : DisplayControl.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 12/06/2007 +------------------------------------------------------------------------------- +-- Description: +-- Source code for display controller for OSRAM SCDV5540 4-digit LED +-- display. An 8-bit input value is input for each of the 4 digits on the +-- LED display. This 8-bit value is used to lookup a charactor from a defined +-- table of charactors. +-- See DisplayCharacters file for character definitions. +------------------------------------------------------------------------------- +-- Copyright (c) 2007 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 12/06/2007: created. +-- 03/06/2008: Fixed reset of shiftValue +------------------------------------------------------------------------------- +LIBRARY ieee; +Library Unisim; +USE ieee.std_logic_1164.ALL; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +USE work.ALL; +use work.DisplayCharacters.all; + +entity DisplayControl is + port ( + + -- Master Clock & reset + sysClk : in std_logic; + sysRst : in std_logic; + + -- Display timing strobe. 200ns min period. + dispStrobe : in std_logic; + + -- Update display + dispUpdate : in std_logic; + + -- Display rotation, 0=0, 1=90, 2=180, 3=270 + dispRotate : in std_logic_vector(1 downto 0); + + -- Index value for charactor digits + dispDigitA : in std_logic_vector(7 downto 0); + dispDigitB : in std_logic_vector(7 downto 0); + dispDigitC : in std_logic_vector(7 downto 0); + dispDigitD : in std_logic_vector(7 downto 0); + + -- Outputs to display device + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic; + dispRstL : out std_logic + ); + + -- Keep from combinging output clocks + attribute syn_preserve : boolean; + attribute syn_preserve of dispClk: signal is true; + +end DisplayControl; + + +-- Define architecture for first level module +architecture DisplayControl of DisplayControl is + + -- Local signals + signal intLoad : std_logic; + signal intData : std_logic; + signal charCount : std_logic_vector(1 downto 0); + signal wordCount : std_logic_vector(2 downto 0); + signal bitCount : std_logic_vector(3 downto 0); + signal shiftCount : std_logic_vector(6 downto 0); + signal shiftValue : std_logic_vector(39 downto 0); + signal newShift : std_logic_vector(39 downto 0); + signal lookupValue : std_logic_vector(24 downto 0); + signal newDigit : std_logic_vector(7 downto 0); + signal strobeDelay : std_logic; + signal strobeEdge : std_logic; + signal shiftEn : std_logic; + + -- Keep from combinging output clocks + attribute syn_preserve of strobeDelay: signal is true; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Output Control Lines + process ( sysClk, sysRst ) begin + if sysRst = '1' then + dispLoadL <= '1' after tpd; + dispRstL <= '0' after tpd; + dispClk <= '0' after tpd; + dispDat <= '0' after tpd; + elsif rising_edge(sysClk) then + dispLoadL <= not intLoad after tpd; + dispRstL <= '1' after tpd; + dispClk <= not dispStrobe after tpd; + dispDat <= intData after tpd; + end if; + end process; + + + -- Strobe edge detection + strobeEdge <= dispStrobe and not strobeDelay; + + -- Shift sequence control and counters + process ( sysClk, sysRst ) begin + if sysRst = '1' then + charCount <= (others=>'0') after tpd; + wordCount <= (others=>'0') after tpd; + shiftCount <= (others=>'0') after tpd; + bitCount <= (others=>'0') after tpd; + shiftEn <= '0' after tpd; + intLoad <= '0' after tpd; + intData <= '0' after tpd; + strobeDelay <= '0' after tpd; + shiftValue <= (others=>'0') after tpd; + elsif rising_edge(sysClk) then + + -- Delayed copy of shift + strobeDelay <= dispStrobe after tpd; + + -- Sequnce is not running + if shiftEn = '0' then + charCount <= (others=>'0') after tpd; + wordCount <= (others=>'0') after tpd; + shiftCount <= (others=>'0') after tpd; + bitCount <= (others=>'0') after tpd; + shiftEn <= dispUpdate after tpd; + intLoad <= '0' after tpd; + intData <= '0' after tpd; + + -- Sequence Is Running + elsif strobeEdge = '1' then + + -- Bit Counter For 8-bit word plus 3-bit space + if bitCount = 12 then + bitCount <= (others=>'0') after tpd; + else + bitCount <= bitCount + 1 after tpd; + end if; + + -- Word Counter, Digit address, followed by 4 Rows + if bitCount = 12 then + if wordCount = 5 then + wordCount <= (others=>'0') after tpd; + else + wordCount <= wordCount + 1 after tpd; + end if; + end if; + + -- Char Counter, 4 Characters + if bitCount = 12 and wordCount = 5 then + if charCount = 3 then + charCount <= (others=>'0') after tpd; + shiftEn <= '0' after tpd; + else + charCount <= charCount + 1 after tpd; + end if; + end if; + + -- Shift Bit Counter, Shift Output for words 1-5 + if wordCount = 0 then + shiftCount <= (others=>'0') after tpd; + shiftValue <= newShift after tpd; + elsif bitCount < 8 then + shiftCount <= shiftCount + 1 after tpd; + end if; + + -- Character address is first word + if wordCount = 0 then + case bitCount is + when "0000" => intData <= charCount(0) after tpd; + when "0001" => intData <= charCount(1) after tpd; + when "0010" => intData <= '0' after tpd; + when "0011" => intData <= '0' after tpd; + when "0100" => intData <= '0' after tpd; + when "0101" => intData <= '1' after tpd; + when "0110" => intData <= '0' after tpd; + when "0111" => intData <= '1' after tpd; + when others => intData <= '0' after tpd; + end case; + + -- Shift out digit values for words 1-5 + else + intData <= shiftValue(conv_integer(shiftCount)) after tpd; + end if; + + -- Load Strobe asserted for bits 0-7 + if bitCount < 8 then + intLoad <= '1' after tpd; + else + intLoad <= '0' after tpd; + end if; + end if; + end if; + end process; + + + -- Select Digit For Display + newDigit <= dispDigitA when charCount = 0 else + dispDigitB when charCount = 1 else + dispDigitC when charCount = 2 else + dispDigitD; + + -- Get Raw Lookup Value + lookupValue <= (others=>'0') when newDigit > DISPMAX else DISPLOOKUP(conv_integer(newDigit)); + + -- Determine rotation of display digit and add row addresses + newShift <= + + -- No Rotation + "000" & lookupValue(24 downto 20) & + "001" & lookupValue(19 downto 15) & + "010" & lookupValue(14 downto 10) & + "011" & lookupValue(9 downto 5) & + "100" & lookupValue(4 downto 0) when dispRotate = 0 else + + -- 90 Deg Rotation + "000" & lookupValue(4) & lookupValue(9) & + lookupValue(14) & lookupValue(19) & lookupValue(24) & + "001" & lookupValue(3) & lookupValue(8) & + lookupValue(13) & lookupValue(18) & lookupValue(23) & + "010" & lookupValue(2) & lookupValue(7) & + lookupValue(12) & lookupValue(17) & lookupValue(22) & + "011" & lookupValue(1) & lookupValue(6) & + lookupValue(11) & lookupValue(16) & lookupValue(21) & + "100" & lookupValue(0) & lookupValue(5) & + lookupValue(10) & lookupValue(15) & lookupValue(20) when dispRotate = 1 else + + -- 180 Deg Rotation + "000" & lookupValue(0) & lookupValue(1) & + lookupValue(2) & lookupValue(3) & lookupValue(4) & + "001" & lookupValue(5) & lookupValue(6) & + lookupValue(7) & lookupValue(8) & lookupValue(9) & + "010" & lookupValue(10) & lookupValue(11) & + lookupValue(12) & lookupValue(13) & lookupValue(14) & + "011" & lookupValue(15) & lookupValue(16) & + lookupValue(17) & lookupValue(18) & lookupValue(19) & + "100" & lookupValue(20) & lookupValue(21) & + lookupValue(22) & lookupValue(23) & lookupValue(24) when dispRotate = 2 else + + -- 270 Deg Rotation + "000" & lookupValue(20) & lookupValue(15) & + lookupValue(10) & lookupValue(5) & lookupValue(0) & + "001" & lookupValue(21) & lookupValue(16) & + lookupValue(11) & lookupValue(6) & lookupValue(1) & + "010" & lookupValue(22) & lookupValue(17) & + lookupValue(12) & lookupValue(7) & lookupValue(2) & + "011" & lookupValue(23) & lookupValue(18) & + lookupValue(13) & lookupValue(8) & lookupValue(3) & + "100" & lookupValue(24) & lookupValue(19) & + lookupValue(14) & lookupValue(9) & lookupValue(4); + +end DisplayControl; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/HsioPixelCore.vhd b/rce/fw-hsio/modules/pixelcore/hdl/HsioPixelCore.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d5a9542540895e340ddba33e220a4dc62e55cddf --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/HsioPixelCore.vhd @@ -0,0 +1,1826 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA Core +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : BnlAsicCore.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use work.arraytype.all; +use work.Version.all; +use work.StdRtlPkg.all; + +entity HsioPixelCore is + generic ( + framedFirstChannel : integer := 0; --First framed channel + framedLastChannel : integer := 7; --Last framed channel + rawFirstChannel : integer := 11; --First raw channel + rawLastChannel : integer := 14; -- Last raw channel + buffersizefe : integer := 8192; --FIFO size + buffersizetdc : integer := 8192; --FIFO size + fixed160 : std_logic := '0';-- fixed 160 or choice 40/160 + encodingDefault : std_logic_vector(1 downto 0) := "00"; --BPM or Manchester or nothing on startup + hitbusreadout : std_logic := '0' -- hitbus configuration + ); + port ( + + -- Master system clock, 250Mhz, 125Mhz + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + + -- PGP Clocks + refClock : in std_logic; + pgpClk : in std_logic; + pgpClk90 : in std_logic; + pgpReset : in std_logic; + + pgpClkUnbuf : in std_logic; + pgpClk90Unbuf: in std_logic; + sysClkUnbuf : in std_logic; + + clk320 : in std_logic; + -- reload firmware + reload : out std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + + -- Reset out to PGP Clock generation + resetOut : out std_logic; + + -- Input from trigger logic + l1a : in std_logic; + latchtriggerword: in std_logic_vector(7 downto 0); + tcounter1 : in std_logic_vector(31 downto 0); + tcounter2 : in std_logic_vector(31 downto 0); + busy : in std_logic; + eudaqdone : in std_logic; + eudaqtrgword : in std_logic_vector(14 downto 0); + + -- Output to trigger logic + present : out std_logic; + calibmodeout : out std_logic_vector(1 downto 0); + startmeas : out std_logic; + pausedout : out std_logic; + trgenabledout : out std_logic; + rstFromCore : out std_logic; + fifothresh : out std_logic; + triggermask : out std_logic_vector(15 downto 0); + discop : out std_logic_vector(15 downto 0); + period : out std_logic_vector(31 downto 0); + telescopeop : out std_logic_vector(2 downto 0); + + resetdelay : out std_logic; + incrementdelay: out std_logic_vector(4 downto 0); + sbusy : out std_logic; --serbusy + tdcbusy : out std_logic; + phaseclksel : out std_logic; + hitbus : out std_logic; + + -- Debug + debug : out std_logic_vector(7 downto 0); + exttriggero : out std_logic; + extrsto : out std_logic; + + doricreset : out std_logic; + phasebusyEn : out std_logic; + phasebusySel : out std_logic_vector(1 downto 0); + + dispDigitA : out std_logic_vector(7 downto 0); + dispDigitB : out std_logic_vector(7 downto 0); + dispDigitC : out std_logic_vector(7 downto 0); + dispDigitD : out std_logic_vector(7 downto 0); + dispDigitE : out std_logic_vector(7 downto 0); + dispDigitF : out std_logic_vector(7 downto 0); + dispDigitG : out std_logic_vector(7 downto 0); + dispDigitH : out std_logic_vector(7 downto 0); + trigAdc : out sl:='0'; + sendAdcData : in sl; + adcData : in Slv16Array(11 downto 0) + + ); +end HsioPixelCore; + + +-- Define architecture +architecture HsioPixelCore of HsioPixelCore is + + component decode_8b10b_wrapper + port ( + CLK : in STD_LOGIC; + DIN : in STD_LOGIC_VECTOR(9 downto 0); + DOUT : out STD_LOGIC_VECTOR(7 downto 0); + KOUT : out STD_LOGIC; + + CE : in STD_LOGIC; + SINIT : in STD_LOGIC; + CODE_ERR : out STD_LOGIC; + ND : out STD_LOGIC + ); + end component; + + component datafifo + generic ( + buffersize : integer :=8192 -- FIFO size + ); + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + component datafifo8192 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + COMPONENT datafifo16384 + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(17 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(17 DOWNTO 0); + full : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + underflow : OUT STD_LOGIC; + prog_full : OUT STD_LOGIC + ); + END COMPONENT; + + component datafifo1024 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + + component wordswapper + port ( + rst : in std_logic; + clk : in std_logic; + wordin : in std_logic_vector(15 downto 0); + eofin : in std_logic; + eeofin : in std_logic; + sofin : in std_logic; + validin : in std_logic; + wordout : out std_logic_vector(15 downto 0); + eofout : out std_logic; + eeofout : out std_logic; + sofout : out std_logic; + validout : out std_logic + ); + end component; + +component fifo8b10b + port ( + din: IN std_logic_VECTOR(9 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + almost_empty: OUT std_logic; + dout: OUT std_logic_VECTOR(9 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + underflow: OUT std_logic); +end component; +component fifo8b10bnew + port ( + rst: IN std_logic; + wr_clk: IN std_logic; + rd_clk: IN std_logic; + din: IN std_logic_VECTOR(9 downto 0); + wr_en: IN std_logic; + rd_en: IN std_logic; + dout: OUT std_logic_VECTOR(9 downto 0); + full: OUT std_logic; + empty: OUT std_logic; + almost_empty: OUT std_logic; + valid: OUT std_logic); +end component; + +component noframefifo + port ( + rst: IN std_logic; + wr_clk: IN std_logic; + rd_clk: IN std_logic; + din: IN std_logic_VECTOR(17 downto 0); + wr_en: IN std_logic; + rd_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + full: OUT std_logic; + empty: OUT std_logic; + almost_empty: OUT std_logic; + valid: OUT std_logic); +end component; + + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + -- PGP Front End Wrapper + + component BUFGMUX port (O: out std_logic; I0: in std_logic; I1: in std_logic; S: in std_logic); end component; + + component ila + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); + + end component; + component icon + PORT ( + CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); + + end component; + component ODDR port ( + Q : out std_logic; + CE : in std_logic; + C : in std_logic; + D1 : in std_logic; + D2 : in std_logic; + R : in std_logic; + S : in std_logic + ); + end component; + + --attribute syn_noprune : boolean; + --attribute syn_noprune of chipscope : label is true; + --attribute syn_noprune of chipscopeicon : label is true; + + + component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); + end component; + + -- Local Signals + signal cmdEn : std_logic; + signal cmdOpCode : std_logic_vector(7 downto 0); + signal cmdCtxOut : std_logic_vector(23 downto 0); + signal readDataValid : std_logic; + signal readDataSOF : std_logic; + signal readDataEOF : std_logic; + signal readDataEOFE : std_logic; + signal readData : std_logic_vector(15 downto 0); + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal regReq : std_logic; + signal regOp : std_logic; + signal regAck : std_logic; + signal regFail : std_logic; + signal regAddr : std_logic_vector(23 downto 0); + signal regDataOut : std_logic_vector(31 downto 0); + signal regDataIn : std_logic_vector(31 downto 0); + signal ack : std_logic; + signal err : std_logic; + signal eof : std_logic; + signal sof : std_logic; + signal vvalid : std_logic; + signal req : std_logic; + signal frameRxValid : std_logic; + signal frameRxReady : std_logic; + signal frameRxSOF : std_logic; + signal frameRxEOF : std_logic; + signal frameRxEOFE : std_logic; + signal frameRxData : std_logic_vector(15 downto 0); + signal regInp : std_logic; + signal blockdata : std_logic_vector(17 downto 0); + signal configdataout : std_logic_vector(17 downto 0); + signal blockcounter : std_logic_vector(2 downto 0); + signal handshake : std_logic; + signal replynow : std_logic; + signal readword : std_logic; + signal swapsof : std_logic; + signal swappedeof : std_logic; + signal oldswappedeof : std_logic; + signal gocounter : std_logic_vector(3 downto 0); + signal swapvalid : std_logic; + signal readvalid : std_logic; + signal counter1 : std_logic_vector(3 downto 0); + signal counter2 : std_logic_vector(3 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + signal daddr : std_logic_vector (6 downto 0); + signal denphase : std_logic; + signal phaseclk : std_logic; + signal phaseclk90 : std_logic; + signal phaseclk180 : std_logic; + signal phaseclk270 : std_logic; + signal o01 : std_logic; + signal o23 : std_logic; + signal clockselect : std_logic_vector(1 downto 0); + signal fxclock : std_logic; + signal serclk : std_logic; + signal drdy : std_logic; + signal drdy2 : std_logic; + signal lockedfx : std_logic; + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal lockedphase : std_logic; + signal lockednophase : std_logic; + signal reqclkphase : std_logic; + signal oldreqclkphase : std_logic; + signal clkenaphase : std_logic; + signal holdrst : std_logic; + signal phaserst : std_logic; + signal clockrst : std_logic; + signal clockrst2 : std_logic; + signal idctrlrst : std_logic; + signal clkdata : std_logic_vector(15 downto 0); + signal holdctr : std_logic_vector(24 downto 0); + signal clockidctrl : std_logic; + signal dreset : std_logic_vector(23 downto 16); + signal ena : std_logic; + signal cout : std_logic; + signal enaold : std_logic; + signal pgpEnaOld : std_logic; + signal countclk : std_logic; + signal clockcountv : std_logic_vector(16 downto 0); + signal starttdcreadout : std_logic; + signal resettdc : std_logic; + signal counterout1 : std_logic_vector(31 downto 0); + signal counterout2 : std_logic_vector(31 downto 0); + signal oldl1a : std_logic; + signal l1amod : std_logic; + signal stop : std_logic; + signal oldstop : std_logic; + signal go : std_logic; + signal qout : std_logic_vector(15 downto 0); + signal tdcdata : std_logic_vector(17 downto 0); + signal tdcld : std_logic; + signal datawaiting : std_logic_vector(31 downto 0); + signal moredatawaiting : std_logic_vector(31 downto 0); + signal indatavalid : std_logic_vector(31 downto 0); + signal chanld : std_logic_vector(31 downto 0); + signal datain : dataarray; + signal channeldata : dataarray; + signal dataout : std_logic_vector(31 downto 0); + signal eofout : std_logic; + signal sofout : std_logic; + signal datavalid : std_logic; + signal reqdata : std_logic_vector(31 downto 0); + signal dfifothresh : std_logic_vector(31 downto 0); + signal andr : std_logic_vector(31 downto 0); + signal empty : std_logic; + signal full : std_logic; + signal configfull : std_logic; + signal bufoverflow : std_logic_vector(31 downto 0); + signal overflow : std_logic_vector(31 downto 0); + signal underflow : std_logic_vector(31 downto 0); + signal prog_full : std_logic; + signal emptyv : std_logic_vector(31 downto 0); + signal fullv : std_logic_vector(31 downto 0); + signal overflowv : std_logic_vector(31 downto 0); + signal underflowv : std_logic_vector(31 downto 0); + signal prog_fullv : std_logic_vector(31 downto 0); + signal isrunning : std_logic_vector(31 downto 0); + signal startdc : std_logic; + signal rst : std_logic; + signal softrst : std_logic; + signal trigenabled : std_logic; + signal exttrgclkeu : std_logic; + signal waitfordata : std_logic; + signal marker : std_logic; + signal mxdata : std_logic_vector(15 downto 0); + signal mxvalid : std_logic; + signal mxeof : std_logic; + signal mxsof : std_logic; + signal ldser : std_logic; + signal configoverflow : std_logic; + signal configunderflow : std_logic; + signal d_out : std_logic; + signal serbusy : std_logic; + signal trgbusy : std_logic; + signal stdc : std_logic; + signal calibmode : std_logic_vector(1 downto 0); + signal edge1 : std_logic; + signal edge2 : std_logic; + signal startrun : std_logic; + signal paused : std_logic; + signal nobackpressure : std_logic; + signal nobackpress : std_logic; + signal reg : std_logic_vector(31 downto 0); + signal backprescounter : std_logic_vector(3 downto 0); + signal counter4 : std_logic_vector(31 downto 0); + signal counter10 : std_logic_vector(31 downto 0); + signal counter10e : std_logic_vector(31 downto 0); + signal tdccounter : std_logic_vector(15 downto 0); + signal counter4m : std_logic_vector(31 downto 0); + signal counter10m : std_logic_vector(31 downto 0); + signal frameTxAFull : std_logic; + signal channelmask : std_logic_vector(31 downto 0); + signal channeloutmask : std_logic_vector(31 downto 0); + signal enablereadout : std_logic_vector(31 downto 0); + signal phases : std_logic_vector(31 downto 0); + signal status : std_logic_vector(31 downto 0); + signal statusd : std_logic_vector(31 downto 0); + signal trgtime : std_logic_vector(63 downto 0); + signal trgtimel : std_logic_vector(63 downto 0); + signal deadtime : std_logic_vector(63 downto 0); + signal deadtimel : std_logic_vector(63 downto 0); + signal l1count : std_logic_vector(3 downto 0); + signal l1countlong : std_logic_vector(31 downto 0); + signal l1countl : std_logic_vector(3 downto 0); + signal rstl1count : std_logic; + signal starttdccount : std_logic_vector(3 downto 0); + signal trgdelay : std_logic_vector(7 downto 0); + signal markercounter : std_logic_vector(9 downto 0); + signal conftrg : std_logic; + signal ld8b10b : std_logic_vector(15 downto 0); + signal ldout8b10b : std_logic_vector(15 downto 0); + signal data8b10b : array10b; + signal dout8b10b : array10b; + signal ldfei4 : std_logic_vector(15 downto 0); + signal ldfifo : std_logic_vector(15 downto 0); + signal dnextvalid : std_logic_vector(15 downto 0); + signal dvalid : std_logic_vector(15 downto 0); + signal frameoverflow : std_logic_vector(15 downto 0); + signal fei4data : fei4array; + signal fifodata : fei4array; + signal dnext : fei4array; + signal aligned : std_logic_vector(15 downto 0); + signal alignout : std_logic_vector(15 downto 0); + signal receiveclock : std_logic; + signal receiveclock90 : std_logic; + signal serdesclock : std_logic; + signal recdata : std_logic_vector(15 downto 0); + signal read8b10bfifo : std_logic_vector(15 downto 0); + signal fifo8b10bempty : std_logic_vector(15 downto 0); + signal valid8b10b : std_logic_vector(15 downto 0); + signal pgpencdatain : array10b; + signal selfei4clk : std_logic_vector(1 downto 0); + signal trgcount : std_logic_vector(15 downto 0); + signal trgcountdown : std_logic_vector(15 downto 0); + + signal encoding : std_logic_vector(1 downto 0); + signal oldbpm : std_logic; + signal doriccounter : std_logic_vector(15 downto 0); + signal doricresetb : std_logic; + signal trgin : std_logic; + signal setdeadtime : std_logic_vector(15 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal setfifothresh : std_logic_vector(15 downto 0); + + signal phaseConfig : std_logic; + + signal hitbusa : std_logic; + signal hitbusb : std_logic; + signal hitbusop : std_logic_vector(15 downto 0); + signal hitbusin : std_logic_vector(5 downto 0); + signal hitbusword : hitbusoutput; + signal hitbusdepth : std_logic_vector(4 downto 0); + signal tdcreadoutdelay: std_logic_vector(4 downto 0); + + signal flatch: std_logic_vector(7 downto 0); + signal ofprotection : std_logic; + + signal phaseClkUnbuf : std_logic; + signal phaseClk90Unbuf : std_logic; + signal phaseClk180Unbuf : std_logic; + signal phaseClk270Unbuf : std_logic; + + signal writemem: std_logic; + signal maxmem: std_logic_vector(9 downto 0); + signal ld32: std_logic; + signal oldld32: std_logic; + signal serdata32: std_logic_vector(31 downto 0); + signal readpointer: std_logic_vector(9 downto 0); + signal memout : std_logic; + signal stop32: std_logic; + signal go32 : std_logic; + signal going32: std_logic; + signal l1route: std_logic; + signal l1modin: std_logic; + signal l1memin: std_logic; + signal readmem: std_logic; + signal bpl: std_logic; + signal multiplicity: std_logic_vector(63 downto 0); + signal tdcfifothresh: std_logic_vector(7 downto 0); + signal oldtdcbusy: std_logic; + signal tdcbusys: std_logic; + + signal adccounter: slv(31 downto 0):=x"00000000"; + signal adcperiod : slv(31 downto 0):=x"02625a00"; + signal oldadcperiod : slv(31 downto 0):=x"02625a00"; + signal enableAdcReadout: sl; + + signal oldbackpressure: sl:='1'; + signal olddft: sl:='1'; + signal maxlength: natural range 0 to 16383; + signal oldindatav: sl; + signal oldindata: slv(23 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + type DELAR is array (0 to 15) of integer; + constant setting: DELAR := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + --attribute syn_noprune : boolean; + constant maxchannel : integer := maximum(framedLastChannel, rawLastChannel); + constant ackchannel : integer:=31; + constant tdcchannel: integer:=30; + constant adcchannel: integer:=29; + + function vectorize(s: std_logic) return std_logic_vector is + variable v: std_logic_vector(0 downto 0); + begin + v(0) := s; + return v; + end; + + function vectorize(v: std_logic_vector) return std_logic_vector is + begin + return v; + end; + +begin + + + -- PGP Front End + U_PgpFrontEnd: entity work.PgpFrontEnd port map ( + pgpRefClk1 => refClock, pgpRefClk2 => '0', + mgtRxRecClk => open, pgpClk => pgpClk, + pgpReset => pgpReset, pgpDispA => pgpDispA, + pgpDispB => pgpDispB, resetOut => resetOut, + locClk => sysClk125, locReset => sysRst125, + cmdEn => cmdEn, cmdOpCode => cmdOpCode, + cmdCtxOut => cmdCtxOut, regReq => regReq, + regInp => regInp, + regOp => regOp, regAck => regAck, + regFail => regFail, regAddr => regAddr, + regDataOut => regDataOut, regDataIn => regDataIn, + frameTxEnable => readDataValid, frameTxSOF => readDataSOF, + frameTxEOF => readDataEOF, frameTxEOFE => readDataEOFE, + frameTxData => readData, frameTxAFull => frameTxAFull, + frameRxValid => frameRxValid, + frameRxReady => frameRxReady, frameRxSOF => frameRxSOF, + frameRxEOF => frameRxEOF, frameRxEOFE => frameRxEOFE, + frameRxData => frameRxData, valid => vvalid, + eof => eof, sof => sof, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, mgtCombusIn => (others=>'0'), + mgtCombusOut => open + ); + + pausedout<=paused; + trgenabledout<=trigenabled; + calibmodeout<=calibmode; + andr<= channeloutmask and dfifothresh; + fifothresh<=andr(0) or andr(1) or andr(2) or andr(3) or andr(4) + or andr(5) or andr(6) or andr(7) or andr(8) + or andr(9) or andr(10) or andr(11) or andr(12) + or andr(13) or andr(14) or andr(15) or andr(16) + or andr(17) or andr(18) or andr(19) or andr(20) + or andr(21) or andr(22) or andr(23) or andr(24) + or andr(25) or andr(26) or andr(27) or andr(28) + or andr(30); + + dispDigitA<=pgpDispA; + dispDigitB<=pgpDispB; +-- dispDigitC(7 downto 1)<="000000"&bpl; +-- dispDigitC(0)<=flatch(7) or flatch(6) or flatch(5) or flatch(4) or flatch(3) or flatch(2) or flatch(1) or flatch(0); + dispDigitC(7 downto 2)<=(others => '0'); + dispDigitD<=x"0"&FpgaVersion(3 downto 0); + dispDigitE<=x"00"; + dispDigitF<=x"00"; + dispDigitG<=x"00"; + dispDigitH<=x"00"; + + dispdigitC(0)<=dfifothresh(0); + dispdigitC(1)<=frameTxAFull; + --process(sysRst125, sysClk125) begin + -- if(sysRst125='1')then + -- dispDigitC(0)<='0'; + -- dispDigitC(1)<='0'; + -- elsif(rising_edge(sysClk125))then + -- olddft<=overflowv(0); + -- oldbackpressure<=frameTxAFull; + -- if(overflowv(0)='1' and olddft='0')then + -- dispDigitC(0)<='1'; + -- end if; + -- if(frameTxAFull='1' and oldbackpressure='0')then + -- dispDigitC(1)<='1'; + -- end if; + -- end if; + --end process; + + nobackpressure<= not frameTxAFull; + --blockdata(15 downto 0) <= frameRxData; + blockdata(17 downto 16) <= "00"; + frameRxReady <= not configfull; + vvalid<='0'; + readDataEOFE<='0'; + --readData<=(others=>'0'); + regAck<= drdy2 or ack; + regFail<= '0'; + req<='1' when regReq='1' and regAddr(8 downto 7) = "00" else '0'; + reqclkphase <='1' when regReq='1' and (regAddr(8 downto 4) = "11000" or regAddr(8 downto 4) = "11001" or regAddr(8 downto 4) = "11010") else '0'; + + U_phaseshift: entity work.phaseshift port map( + CLKIN_IN => sysClk125, + DADDR_IN => daddr, + DCLK_IN => sysClk125, + DEN_IN => denphase, + DI_IN => regDataOut(15 downto 0), + DWE_IN => regOp, + RST_IN => clockrst2, + CLK0_OUT => phaseclk, + CLK90_OUT => phaseclk90, + CLK180_OUT => phaseclk180, + CLK270_OUT => phaseclk270, + CLKFX_OUT => open, + CLK2X_OUT => open, + DRDY_OUT => drdy2, + LOCKED_OUT=> lockedphase, + pclkUnbuf => phaseClkUnbuf, + pclk90Unbuf => phaseClk90Unbuf, + pclk180Unbuf => phaseClk180Unbuf, + pclk270Unbuf => phaseClk270Unbuf + ); + + clockrst2<=phaserst; + + + with regAddr(8 downto 4) select + daddr<="1010101" when "11000", + "0010001" when "11001", + "0000000" when others; + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + elsif(sysClk125'event and sysClk125='1') then + if (holdctr=x"000000"&'0') then + phaserst<='0'; + else + if (holdctr(24)='0') then + phaserst<='1'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + if (reqclkphase='1' and oldreqclkphase='0') then + clkenaphase<='1'; + else + clkenaphase<='0'; + end if; + denphase<=clkenaphase; + oldreqclkphase<=reqclkphase; + end if; + end process; + + process(sysClk125,sysRst125) -- test for tdc + begin + if(sysRst125='1')then + ena<='0'; + enaold<='0'; + pgpEnaOld<='0'; + clockselect<="00"; + trgcount<=x"0000"; + calibmode<="00"; + resetdelay<='0'; + incrementdelay<="00000"; + conftrg<='0'; + trgdelay<=x"02"; + triggermask<=x"0000"; + period<=x"00000000"; + reg<=x"00000000"; + setdeadtime<=x"0007"; + channelmask<=(others => '0'); + channeloutmask<=(ackchannel => '1', others => '0'); + phases <= (others =>'0'); + encoding<=encodingDefault; + hitbusop<=x"0000"; + discop<=x"0000"; + telescopeop<="000"; + setfifothresh<=x"efff"; + ofprotection<='0'; + writemem<='0'; + maxmem<="0000000000"; + l1route<='0'; + hitbusdepth<="00000"; + tdcreadoutdelay<="00000"; + multiplicity<=x"0000000000000000"; + maxlength<=100; + phasebusyEn<='0'; + phasebusySel<="00"; + elsif(rising_edge(sysClk125))then + if(req='1' and pgpEnaOld='0')then + ena<='1'; + case regOp is + when '1' => -- Write + case regAddr(7 downto 0) is + when x"01" => -- Start TDC measurement when in calib mode + startmeas<='1'; + when x"02" => -- Clock select for calib + clockselect<=regDataOut(1 downto 0); + when x"03" => -- Select calib mode + calibmode<= regDataOut(1 downto 0); + -- 0 is normal + -- 1 is tdc calib + -- 2 is eudaq + when x"00" => -- Set channelmask + channelmask<=regDataOut; + when x"04" => -- Switch TDC/Trigger data on and off + channeloutmask(tdcchannel)<=regDataOut(0); + when x"05" => -- Increment disc delays + incrementdelay<=regDataOut(4 downto 0); + when x"06" => + discop<=regDataOut(15 downto 0); + when x"07" => -- reset input delays + resetdelay<='1'; + when x"08" => -- Set trigger delay + conftrg<='1'; + if(unsigned(regDataOut(7 downto 0))<2)then + trgdelay<=x"02"; + else + trgdelay<=regDataOut(7 downto 0); + end if; + when x"09" => -- Set cyclic trigger period + period<=regDataOut; + when x"0a" => -- Clock select for receive clock + selfei4clk<=regDataOut(1 downto 0); + when x"0d" => -- enable data output + channeloutmask(28 downto 0)<=regDataOut(28 downto 0); + channeloutmask(ackchannel)<='1'; + when x"0b" => -- Set trigger mask -1 is scintillator + -- 2 is cyclic + -- 4 is external + -- 8 is external (HSIO) + -- 16 is hitbus + triggermask<=regDataOut(15 downto 0); + when x"0e" => + trgcount<=regDataOut(15 downto 0); + when x"0f" => + setdeadtime<=regDataOut(15 downto 0); + when x"11" => + phases<=regDataOut; + when x"12" => -- write a word into the command stream buffer + writemem<='1'; + when x"13" => -- clear the command stream buffer + maxmem<="0000000000"; + when x"14" => + encoding<=regDataOut(1 downto 0); + when x"15" => + hitbusop<=regDataOut(15 downto 0); + when x"16" => + multiplicity(31 downto 0)<=regDataOut; + when x"17" => + multiplicity(63 downto 32)<=regDataOut; + when x"19" => + setfifothresh<=regDataOut(15 downto 0); + when x"1a" => + ofprotection<=regDataOut(0); + when x"1b" => + l1route<=regDataOut(0); + when x"1c" => + hitbusdepth <= regDataOut(4 downto 0); + when x"1d" => + tdcreadoutdelay <= regDataOut(4 downto 0); + when x"1e" => + telescopeop<=regDataOut(2 downto 0); + when x"1f" => + adcperiod<=regDataOut; + when x"20" => + channeloutmask(adcchannel)<=regDataOut(0); + when x"21" => + maxlength<=conv_integer(unsigned(regDataOut(13 downto 0))); + when x"22" => + phasebusyEn<=regDataOut(0); + phasebusySel<=regDataOut(2 downto 1); + when others => + + end case; + when '0' => -- Read + startmeas<='0'; + case regAddr(3 downto 0) is + when "0000" => + regDataIn<=tcounter1; + when "0001" => + regDataIn<=tcounter2; + when "0011" => + regDataIn<=status; + when "0100" => + regDataIn<=statusd; + when "0101" => + regDataIn<=trgtimel(63 downto 32); + when "0110" => + regDataIn<=trgtimel(31 downto 0); + when "0111" => + regDataIn<=deadtimel(63 downto 32); + when "1000" => + regDataIn<=deadtimel(31 downto 0); + when "1001" => + regDataIn<=counter4; + when "1010" => + regDataIn<=counter10; + when "1011" => + regDataIn<=l1countlong; + when "1100" => + regDataIn<=counter4m; + when "1101" => + regDataIn<=FpgaVersion; + when "1110" => + regDataIn<=reg; + when "1111" => + regDataIn<=channeloutmask; + when others => + end case; + when others => + end case; + else + if(writemem='1')then + maxmem<=unsigned(maxmem)+1; + writemem<='0'; + end if; + startmeas<='0'; + resettdc<='0'; + ena<='0'; + incrementdelay<="00000"; + resetdelay<='0'; + conftrg<='0'; + extrsto<='0'; + end if; + pgpEnaOld<=req; + enaold<=ena; + ack<=enaold; + err<='0'; + end if; + end process; + process (sysRst125, sysClk125) begin + if(sysRst125='1')then + startrun<='0'; + softrst<='0'; + present<='0'; + trigenabled<='0'; + rstl1count<='0'; + marker<='0'; + reload <='1'; + markercounter<="0000000000"; + phaseConfig <='0'; + elsif rising_edge(sysClk125) then + if(cmdEn='1')then + if(cmdOpCode=x"03")then -- start run + softrst<='1'; + startrun<='1'; + trgcountdown<=trgcount; -- for runs with a finite number of events. + elsif(cmdOpCode=x"04")then -- pause run + trigenabled<='0'; + paused<='1'; + elsif(cmdOpCode=x"05")then -- stop run + trigenabled<='0'; + paused<='0'; + present<='0'; + elsif(cmdOpCode=x"06")then -- resume run + trigenabled<='1'; + paused<='0'; + elsif(cmdOpCode=x"07")then -- resume run and set marker after delay + markercounter<="1111111111"; + elsif(cmdOpCode=x"08")then -- Reboot + reload<='0'; + elsif(cmdOpCode=x"09")then -- soft reset + softrst<='1'; + elsif(cmdOpCode=x"10")then -- FS: Write new phase configuration from phase recognition + phaseConfig <= '1'; + elsif(cmdOpCode=x"11")then -- Tell HSIO that this core is active. + present <= '1'; + elsif(cmdOpCode=x"12")then -- Tell HSIO that this core is not active. + present <= '0'; + end if; + elsif(startrun='1')then + softrst<='0'; + startrun<='0'; + trigenabled<='1'; + paused<='0'; + elsif(softrst='1')then + softrst<='0'; + elsif(trgcountdown=x"0001")then -- stop run + trigenabled<='0'; + paused<='0'; + elsif(markercounter="0000000011")then + softrst<='1'; + elsif(markercounter="0000000001")then + marker<='1'; + trigenabled<='1'; + paused<='0'; + rstl1count<='1'; + else + marker<='0'; + rstl1count<='0'; + phaseConfig<='0'; + end if; + if(markercounter/="0000000000")then + markercounter<=unsigned(markercounter)-1; + end if; + if(l1a='1' and trgcountdown/=x"0000")then + trgcountdown<=unsigned(trgcountdown)-1; + end if; + end if; + end process; + rst<= sysRst125 or softrst; + rstFromCore<= rst; + + process begin + wait until rising_edge(sysClk125); + oldadcperiod<=adcperiod; + if(adccounter=adcperiod)then + adccounter<=(others => '0'); + trigAdc <= '1'; + elsif (adcperiod/=oldadcperiod)then + adccounter<=(others => '0'); + trigAdc <= '0'; + else + adccounter<=unsigned(adccounter)+1; + trigAdc <='0'; + end if; + end process; + + doricreset<=doricresetb; + process(sysClk125, sysRst125) -- reset logic for DORIC + begin + if(sysRst125='1') then + doricresetb<='1'; + doriccounter<=x"0000"; + oldbpm<='0'; + elsif(sysClk125'event and sysClk125='1') then + oldbpm<=encoding(0); + if(encoding(0)='1' and oldbpm='0')then + doricresetb<='0'; + doriccounter<=x"ffff"; + elsif(doriccounter/=x"0000")then + doriccounter<=unsigned(doriccounter)-1; + end if; + if(doriccounter=x"0001")then + doricresetb<='1'; + end if; + end if; + end process; + + process(sysClk125,rst) begin + if(rst='1')then + counter4<=(others=>'0'); + counter10<=(others=>'0'); + counter4m<=(others=>'0'); + counter10m<=(others=>'0'); + elsif(rising_edge(sysClk125))then + if(mxsof='1' and mxvalid='1')then + counter4<=unsigned(counter4)+1; + end if; + if(mxeof='1' and mxvalid='1')then + counter10<=unsigned(counter10)+1; + end if; + if(mxsof='1')then + counter4m<=unsigned(counter4m)+1; + end if; + if(mxvalid='1' and mxeof='1')then + counter10m<=unsigned(counter10m)+1; + end if; + end if; + end process; + process (rst, sysClk125) begin + if(rst='1')then + status<=x"00000000"; + statusd<=x"00000000"; + l1count<=x"1"; + l1countlong<=x"00000000"; + starttdccount<=x"1"; + l1countl<=x"1"; + trgtime<=x"0000000000000000"; + trgtimel<=x"0000000000000000"; + deadtime<=x"0000000000000000"; + deadtimel<=x"0000000000000000"; + elsif (rising_edge(sysClk125)) then + oldl1a<=l1a; + if(trigenabled='1' or paused='1')then + trgtime<=unsigned(trgtime)+1; + end if; + if(busy='1' or paused='1')then + deadtime<=unsigned(deadtime)+1; + end if; + if(rstl1count='1')then + l1count<=x"1"; + elsif(l1a='1')then + l1countl<=l1count; + l1count<=unsigned(l1count)+1; + if(oldl1a='0')then + l1countlong<=unsigned(l1countlong)+1; + end if; + trgtimel<=trgtime; + deadtimel<=deadtime; + end if; + status(10 downto 0)<= dfifothresh(10 downto 0); + status(11)<= paused; + status(12)<= frameTxAFull; + + --statusd(10 downto 0)<= statusd(10 downto 0) or underflow; + statusd(3 downto 0) <= l1count; + statusd(7 downto 4) <= starttdccount; + statusd(10 downto 9) <=(others=>'0'); + statusd(21 downto 11)<= statusd(21 downto 11) or overflow(10 downto 0); + statusd(22)<=statusd(22) or configunderflow; + statusd(23)<=statusd(23) or configoverflow; + statusd(24)<=busy; + --statusd(26)<=extbusy; + statusd(26)<='0'; + end if; + end process; + + --B01: BUFGMUX + -- port map( + -- O=> o01, + -- I0 => phaseclkUnbuf, + -- I1 => phaseclk90Unbuf, + -- S => clockselect(0) + -- ); + --B02: BUFGMUX + -- port map( + -- O=> o23, + -- I0 => phaseclk180Unbuf, + -- I1 => phaseclk270Unbuf, + -- S => clockselect(0) + -- ); + --B04: BUFGMUX + -- port map( + -- O=> phaseclksel, + -- I0 => o01, + -- I1 => o23, + -- S => clockselect(1) + -- ); + phaseclksel<='0'; + + sbusy<=trgbusy or going32; + l1modin<=l1a and not l1route; + l1memin<=l1a and l1route; + trgpipeline: entity work.triggerpipeline + port map( + rst=> sysRst125, + clk=> sysClk125, + L1Ain=> l1modin, -- was l1a + L1Aout=> l1amod, + configure=> conftrg, + delay => trgdelay, + busy => trgbusy, + deadtime => setdeadtime + ); + + with hitbusop(3) select + hitbusa<= (hitbusin(0) and hitbusop(0)) or (hitbusin(1) and hitbusop(1)) or (hitbusin(2) and hitbusop(2)) when '0', + (hitbusin(0) or not hitbusop(0)) and (hitbusin(1) or not hitbusop(1)) and (hitbusin(2) or not hitbusop(2)) + and (hitbusop(0) or hitbusop(1) or hitbusop(2)) when '1', + '0' when others; + with hitbusop(7) select + hitbusb<= (hitbusin(3) and hitbusop(4)) or (hitbusin(4) and hitbusop(5)) or (hitbusin(5) and hitbusop(6)) when '0', + (hitbusin(3) or not hitbusop(4)) and (hitbusin(4) or not hitbusop(5)) and (hitbusin(5) or not hitbusop(6)) + and (hitbusop(4) or hitbusop(5) or hitbusop(6)) when '1', + '0' when others; + with hitbusop(8) select + hitbus <= hitbusa or hitbusb when '0', + hitbusa and hitbusb when '1', + '0' when others; + + hr1: if(hitbusreadout='1') generate + counterout1<=hitbusword(0); + counterout2<=hitbusword(1); + end generate hr1; + hr2: if(hitbusreadout='0') generate + counterout1<=tcounter1; + counterout2<=tcounter2; + end generate hr2; + -- Filter out the message header. The only interesting thing is the handshake + process (rst,sysClk125) begin + if(rst='1')then + blockcounter<="000"; + readword<='0'; + handshake<='0'; + swapsof<='0'; + gocounter<=x"0"; + oldswappedeof<='0'; + elsif rising_edge(sysClk125) then + if(frameRxValid='1' and frameRxSOF='1')then + blockcounter<="111"; + elsif(blockcounter /= "000")then + blockcounter<=unsigned(blockcounter)-1; + if(blockcounter="110")then + handshake<=frameRxData(0); + elsif(blockcounter="001")then + readword<='1'; + swapsof<='1'; + end if; + elsif(frameRxEOF='1')then + swapsof<='0'; + readword<='0'; + else + swapsof<='0'; + end if; + oldswappedeof<=swappedeof; + if(swappedeof='1' and oldswappedeof='0') then + if(stop='0')then + go<='1'; + else + gocounter<=x"4"; + end if; + elsif(gocounter/=x"0")then + gocounter<=unsigned(gocounter)-1; + if(gocounter=x"1")then + go<='1'; + end if; + else + go<='0'; + end if; + end if; + end process; + readvalid<=readword and frameRxValid; + process (sysClk125,sysRst125) begin + if(sysRst125='1')then + oldstop<='0'; + elsif rising_edge(sysClk125) then + oldstop<=stop; + if (stop='1' and oldstop='0')then + replynow<=handshake; + else + replynow<='0'; + end if; + end if; + end process; + swapconfig: wordswapper + port map( + rst=>rst, + clk=>sysClk125, + wordin=>frameRxData, + eofin=>frameRxEOF, + eeofin=>'0', + sofin=>swapsof, + validin=>readvalid, + wordout=>blockdata(15 downto 0), + eofout=>swappedeof, + eeofout=>open, + sofout=>open, + validout=>swapvalid + ); + theconfigfifo: datafifo8192 + port map ( + din => blockdata, + rd_clk => sysClk125, + rd_en => ldser, + rst => sysRst125, + wr_clk => sysClk125, + wr_en => swapvalid, + dout => configdataout, + empty => stop, + full => configfull, + overflow => configoverflow, + prog_full => open, + underflow => open); + theser: entity work.ser + port map( + clk=>sysClk125, + ld=>ldser, +-- l1a=>l1a, + l1a=>l1amod, + go=>go, + busy=>serbusy, + stop=>stop, + rst=>rst, + d_in=>configdataout(15 downto 0), + d_out=>d_out + ); + + process (sysClk125, sysRst125) begin + if(sysRst125='1')then + oldld32<='0'; + stop32<='1'; + readpointer<="0000000000"; + elsif rising_edge(sysClk125)then + oldld32<=ld32 or l1memin; + if(l1memin='1' and going32 ='0' and maxmem/="0000000000")then -- serialize trigger sequence + stop32<='0'; + end if; + if(going32='1')then + if(oldld32='1' and ld32='0' )then + if(readpointer=unsigned(maxmem)-1)then + stop32<='1'; + readpointer<="0000000000"; + else + readpointer<=unsigned(readpointer)+1; + end if; + end if; + end if; + end if; + end process; + + readmem<=ld32 or l1memin; + configmem : pattern_blk_mem + port map ( + clka => sysClk125, + dina => regDataOut, + addra => maxmem, + ena => writemem, + wea => vectorize('1'), + douta => open, + clkb => sysClk125, + dinb => (others=>'0'), + addrb => readpointer, + enb => readmem, + web => vectorize('0'), + doutb => serdata32); + + theser32: entity work.ser32 + port map( + clk => sysClk125, + ld => ld32, + go => l1memin, + busy => going32, + stop => stop32, + rst => sysRst125, + d_in => serdata32, + d_out => memout); + + + fanout: for I in 0 to maxchannel generate + bpmenc: entity work.outputencoder + port map( + clock=>sysClk125, + rst=>sysRst125, + clockx2=>sysClk250, + datain=>serialoutb(I), + encode=>encoding, + dataout=>serialout(I)); + serialoutb(I)<= (d_out or memout) when channelmask(I)='1' and doricresetb='1' else '0'; + end generate fanout; + + pgpack: entity work.deser + generic map( CHANNEL=>toSlv(ackchannel, 8) ) + port map ( + clk => sysClk125, + rst => sysRst125, + d_in => '0', + enabled => channeloutmask(ackchannel), + replynow => replynow, + marker =>'0', + d_out => channeldata(ackchannel)(15 downto 0), + ld => chanld(ackchannel), + sof => channeldata(ackchannel)(16), + eof => channeldata(ackchannel)(17) + ); + pgpackfifo : datafifo1024 + port map ( + din => channeldata(ackchannel), + rd_clk => sysClk125, + rd_en => reqdata(ackchannel), + rst => rst, + wr_clk => sysClk125, + wr_en => chanld(ackchannel), + dout => datain(ackchannel), + empty => open, + full => open, + overflow => overflow(ackchannel), + prog_full => dfifothresh(ackchannel), + valid => indatavalid(ackchannel), + underflow => underflow(ackchannel)); + pgpackdataflag: entity work.dataflag + port map( + eofin=>channeldata(ackchannel)(17), + eofout=>datain(ackchannel)(17), + datawaiting=> datawaiting(ackchannel), + clk=>sysClk125, + rst=>rst, + counter=>open + ); + moredatawaiting(ackchannel)<='0'; + + enableAdcReadout<=not dfifothresh(adcchannel) and channeloutmask(adcchannel) and trigenabled; + adcreadout_inst: entity work.adcreadout + generic map( CHANNEL=>toSlv(adcchannel, 8) ) + port map ( + clk => sysClk125, + rst => rst, + d_in => AdcData, + enabled => enableAdcReadout, + go => sendAdcData, + d_out => channeldata(adcchannel)(15 downto 0), + ld => chanld(adcchannel), + sof => channeldata(adcchannel)(16), + eof => channeldata(adcchannel)(17) + ); + adcfifo: datafifo1024 + port map ( + rd_clk => sysClk125, + wr_clk => sysClk125, + rst => rst, + din => channeldata(adcchannel), + rd_en => reqdata(adcchannel), + wr_en => chanld(adcchannel), + dout => datain(adcchannel), + empty => open, + full => open, + overflow => overflow(adcchannel), + prog_full => dfifothresh(adcchannel), + valid => indatavalid(adcchannel), + underflow => underflow(adcchannel)); + adcdataflag: entity work.dataflag + port map( + eofin=>channeldata(adcchannel)(17), + eofout=>datain(adcchannel)(17), + datawaiting=> datawaiting(adcchannel), + clk=>sysClk125, + rst=>rst, + counter => open + ); + + CHANNELREADOUT: + for I in rawFirstChannel to rawLastChannel generate + enablereadout(I)<=channeloutmask(I) and ((trigenabled and not ofprotection) or not dfifothresh(I)); + channelreadout: entity work.deser + generic map( CHANNEL=> std_logic_vector(conv_unsigned(I,4))) + port map ( + clk => sysClk125, + rst => sysRst125, + d_in => serialin(I), + enabled => enablereadout(I), + replynow => '0', + marker => marker, + d_out => channeldata(I)(15 downto 0), + ld => chanld(I), + sof => channeldata(I)(16), + eof => channeldata(I)(17) + ); + channelfifo : datafifo8192 + port map ( + din => channeldata(I), + rd_clk => sysClk125, + rd_en => reqdata(I), + rst => rst, + wr_clk => sysClk125, + wr_en => chanld(I), + dout => datain(I), + empty => open, + full => open, + overflow => overflow(I), + prog_full => dfifothresh(I), + valid => indatavalid(I), + underflow => underflow(I)); + channeldataflag: entity work.dataflagnew + port map( + eofin=>channeldata(I)(17), + eofout=>datain(I)(17), + datawaiting=> datawaiting(I), + moredatawaiting=> moredatawaiting(I), + clkin=>sysClk125, + clkout=>sysClk125, + rst=>rst + ); + end generate CHANNELREADOUT; + + starttdcreadout<=l1a and channeloutmask(tdcchannel); + + process(rst, pgpClk) begin + if(rst='1')then + oldtdcbusy<='0'; + elsif(rising_edge(pgpClk))then + if(tdcbusys='0' and oldtdcbusy='1') then --tdc readout is done + tdcfifothresh<=(others => '0'); + elsif(andr(10) ='1')then + tdcfifothresh(7)<=andr(10); + elsif(andr(6) ='1')then + tdcfifothresh(6)<=andr(6); + elsif(andr(5) ='1')then + tdcfifothresh(5)<=andr(5); + elsif(andr(4) ='1')then + tdcfifothresh(4)<=andr(4); + elsif(andr(3) ='1')then + tdcfifothresh(3)<=andr(3); + elsif(andr(2) ='1')then + tdcfifothresh(2)<=andr(2); + elsif(andr(1) ='1')then + tdcfifothresh(1)<=andr(1); + elsif(andr(0) ='1')then + tdcfifothresh(0)<=andr(0); + end if; + oldtdcbusy<=tdcbusys; + end if; + end process; + tdcbusy<=tdcbusys; + thereeadout: entity work.tdcreadout + generic map(CHANNEL=>toSlv(tdcchannel, 8)) + port map( + clk=>pgpClk, + slowclock=>sysClk125, + rst=>rst, + go=>starttdcreadout, + delay=>tdcreadoutdelay, + counter1=>counterout1, + counter2=>counterout2, + trgtime=>trgtimel, + deadtime=>deadtimel, + status=>status(14 downto 0), + marker=>marker, + l1count=>l1countl, + bxid=>trgtimel(7 downto 0), + d_out=>tdcdata(15 downto 0), + ld=>tdcld, + busy=>tdcbusys, + sof=>tdcdata(16), + eof=>tdcdata(17), + runmode => calibmode, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + fifothresh => tdcfifothresh, + triggerword => latchtriggerword + ); + tdcfifo : datafifo + generic map( buffersize => buffersizetdc) + port map ( + din => tdcdata, + rd_clk => sysClk125, + rd_en => reqdata(tdcchannel), + rst => rst, + wr_clk => pgpClk, + wr_en => tdcld, + dout => datain(tdcchannel), + empty => empty, + full => full, + overflow => overflow(tdcchannel), + prog_full => dfifothresh(tdcchannel), + valid => indatavalid(tdcchannel), + underflow => underflow(tdcchannel)); + tdcdataflag: entity work.dataflagnew + port map( + eofin=>tdcdata(17), + eofout=>datain(tdcchannel)(17), + datawaiting=>datawaiting(tdcchannel), + moredatawaiting=>moredatawaiting(tdcchannel), + clkin=>pgpClk, + clkout=>sysClk125, + rst=>rst); + + multiplexer: entity work.multiplexdata + generic map ( + maxchannel => maxchannel + ) + port map( + clk=>sysClk125, + rst=>rst, + enabled=>nobackpressure, + channelmask=>channeloutmask, + datawaiting=>datawaiting, + moredatawaiting=>moredatawaiting, + indatavalid => indatavalid, + datain=>datain, + dataout=>mxdata, + eofout=>mxeof, + sofout=>mxsof, + datavalid=>mxvalid, + reqdata=>reqdata, + multiplicity => multiplicity, + counter4=>open, + counter10b=>counter10e, + counter10=>open + ); + swapdata: wordswapper + port map( + rst=>rst, + clk=>sysClk125, + wordin=>mxdata, + eofin=>mxeof, + eeofin=>'0', + sofin=>mxsof, + validin=>mxvalid, + wordout=>readData, + eofout=>readDataEOF, + eeofout=>open, + sofout=>readDataSOF, + validout=>readDataValid + ); + + FULLDISPLAY: + for I in 0 to 7 generate + process (rst, dfifothresh(I)) begin + if(rst='1')then + flatch(I)<='0'; + elsif(rising_edge(dfifothresh(I)))then + flatch(I)<='1'; + end if; + end process; + end generate FULLDISPLAY; + process (rst, frameTxAFull) begin + if(rst='1')then + bpl<='0'; + elsif(rising_edge(frameTxAFull))then + bpl<='1'; + end if; + end process; + + bgmf: if(fixed160='1') generate + receiveclock<=pgpClk; + receiveclock90<=pgpClk90; + end generate bgmf; + bgmv: if(fixed160='0') generate + CLKFEI4: BUFGMUX + port map( + O=> receiveclock, + I0 => phaseclkUnbuf, + I1 => pgpClkUnbuf, + S => selfei4clk(1) + ); + CLKFEI490: BUFGMUX + port map( + O=> receiveclock90, + I0 => phaseclk90Unbuf, + I1 => pgpClk90Unbuf, + S => selfei4clk(1) + ); + end generate bgmv; + FRAMEDCHANNELREADOUT: + for I in framedFirstChannel to framedLastChannel generate + receivedata: entity work.syncdatac + port map( + phaseConfig => phaseConfig, + clk => receiveclock, + clk90 => receiveclock90, + rdatain => serialin(I), + rst => sysRst125, + useaout => open, + usebout => open, + usecout => open, + usedout => open, + sdataout => recdata(I)); + FE_CHANNEL: if ((I/=3 and I/=7) or hitbusreadout='0') generate + alignframe: entity work.framealign + port map( + clk => receiveclock, + rst => rst, + d_in => recdata(I), + d_out => alignout(I), + aligned => aligned(I) + ); + deser8b10b: entity work.deser10b + port map( + clk => receiveclock, + rst => rst, + d_in => alignout(I), + align => aligned(I), + d_out => data8b10b(I), + ld => ld8b10b(I) + ); + decoder8b10b: decode_8b10b_wrapper + port map( + CLK => receiveclock, + DIN => data8b10b(I), + DOUT => dout8b10b(I)(7 downto 0), + KOUT => dout8b10b(I)(8), + CE => ld8b10b(I), + SINIT => rst, + CODE_ERR =>dout8b10b(I)(9), + ND =>ldout8b10b(I) + ); + enablereadout(I)<=channeloutmask(I) and ((trigenabled and not ofprotection) or not dfifothresh(I)); + decode: entity work.decodefei4record + port map(clk => receiveclock, + rst => rst, + enabled => enablereadout(I), + isrunning => isrunning(I), + d_in => dout8b10b(I)(7 downto 0), + k_in => dout8b10b(I)(8), + err_in => dout8b10b(I)(9), + d_out => fei4data(I), + ldin => ldout8b10b(I), + ldout => ldfei4(I), + overflow => bufoverflow(I) + ); + fei4fifo : entity work.lookaheadfifo + generic map( buffersize => buffersizefe) + port map ( + din => fei4data(I), + rd_clk => sysClk125, + rd_en => ldfifo(I), + rst => rst, + wr_clk => receiveclock, + wr_en => ldfei4(I), + dout => fifodata(I), + dnext => dnext(I), + dnextvalid => dnextvalid(I), + empty => emptyv(I), + full => fullv(I), + overflow => overflowv(I), + prog_full => dfifothresh(I), + valid => dvalid(I), + underflow => underflowv(I)); + fei4dataflag: entity work.dataflagff + port map( + eofin=>fei4data(I)(24), + ldin => ldfei4(I), + eofout=>dnext(I)(24), + ldout => ldfifo(I), + datawaiting=>datawaiting(I), + moredatawaiting=>moredatawaiting(I), + clkin=>receiveclock, + clkinrate=>selfei4clk(1), + clkout=>sysClk125, + rst=>rst); + encode: entity work.encodepgp24bit + generic map( CHANNEL=> std_logic_vector(conv_unsigned(I,4))) + port map(clk => sysClk125, + rst => rst, + enabled =>channeloutmask(I), + maxlength => maxlength, + isrunning => open, + d_in => fifodata(I), + d_next => dnext(I), + marker => marker, + d_out => datain(I), + ldin => reqdata(I), + ldout => ldfifo(I), + dnextvalid => dnextvalid(I), + dvalid => dvalid(I), + datawaiting=> datawaiting(I), + moredatawaiting=> moredatawaiting(I), + overflow => frameoverflow(I), + valid => indatavalid(I) +); + end generate FE_CHANNEL; + HITBUS_CHANNEL: if (hitbusreadout='1' and (I=3 or I=7)) generate + dfifothresh(I)<='0'; + alignframe: entity work.framealignhitbus + port map( + clk => receiveclock, + rst => rst, + d_in => recdata(I), + d_out => alignout(I), + aligned => aligned(I) + ); + deserhitbus: entity work.deser4b + port map( + clk => receiveclock, + rst => rst, + d_in => alignout(I), + align => aligned(I), + d_out => data8b10b(I)(3 downto 0), + ld => ld8b10b(I) + ); + hitbusin(I/4*3)<=data8b10b(I)(2); + hitbusin(I/4*3+1)<=data8b10b(I)(1); + hitbusin(I/4*3+2)<=data8b10b(I)(0); + thehitbuspipeline: entity work.hitbuspipeline + port map( + rst => rst, + clk => receiveclock, + ld => ld8b10b(I), + depth => hitbusdepth, + wordin => data8b10b(I)(2 downto 0), + wordout => hitbusword(I/4) + ); + end generate HITBUS_CHANNEL; + end generate FRAMEDCHANNELREADOUT; + hbin: if framedfirstchannel>7 or framedlastchannel<7 or hitbusreadout='0' generate + hitbusin(3)<='0'; + hitbusin(4)<='0'; + hitbusin(5)<='0'; + end generate hbin; + hbin2: if framedfirstchannel>3 or framedlastchannel<3 or hitbusreadout='0' generate + hitbusin(0)<='0'; + hitbusin(1)<='0'; + hitbusin(2)<='0'; + end generate hbin2; + dfifothresh(6 downto framedlastchannel+1)<=(others => '0'); + debug(0)<=recdata(7); + debug(1)<=alignout(7); + debug(2)<=aligned(7); + debug(3)<=data8b10b(7)(3); + debug(4)<=ld8b10b(7); + debug(5)<=hitbusin(3); + debug(6)<=hitbusin(5); + --debug(7)<=hitbus; + + + --process (rst, sysClk125) begin + -- if(rst='1')then + -- ctrig(0)<='0'; + -- oldindatav<='0'; + -- oldindata<=x"000000"; + -- elsif rising_edge(sysClk125) then + -- oldindatav<=ldfifo(1); + -- oldindata<=fifodata(1)(23 downto 0); + -- if(ldfifo(1)='1' and fifodata(1)(23 downto 0)=x"02211f" and + -- oldindatav='1' and oldindata=x"02211f")then + -- ctrig(0)<='1'; + -- else + -- ctrig(0)<='0'; + -- end if; + -- end if; + --end process; +-- cdata(9 downto 0)<=dout8b10b(0); + +ctrig(0)<=dnextvalid(1); +cdata(23 downto 0)<=dnext(1)(23 downto 0); +cdata(24)<=fei4data(1)(24); +cdata(25)<=dnext(1)(24); +cdata(26)<=ldfei4(1); +cdata(30)<=dnextvalid(1); +cdata(28)<=datawaiting(1); +cdata(29)<=moredatawaiting(1); +cdata(27)<=ldfifo(1); +cdata(31)<=indatavalid(1); +--cdata(8)<=alignout(2); +--cdata(9)<=aligned(2); +--cdata(11 downto 10)<=dout8b10b(2)(9 downto 8); + +--cdata(12)<=alignout(3); +--cdata(13)<=aligned(3); +--cdata(15 downto 14)<=dout8b10b(3)(9 downto 8); + +--cdata(16)<=alignout(0); +--cdata(17)<=aligned(0); +--cdata(18)<=datawaiting(0); +--cdata(28 downto 19)<=dout8b10b(0); + +--cdata(29)<=alignout(5); +--cdata(30)<=aligned(5); +--cdata(31)<=dout8b10b(5)(9); + + +--chipscope : ila + --port map ( + --CONTROL => ccontrol, + --CLK => sysClk125, + --DATA => cdata, + --TRIG0 => ctrig); +--chipscopeicon : icon + --port map ( + --CONTROL0 => ccontrol); + -- +end HsioPixelCore; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/I2cMaster.vhd b/rce/fw-hsio/modules/pixelcore/hdl/I2cMaster.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a49cb314d9ec1152a25201b0485adfee5d24f2f9 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/I2cMaster.vhd @@ -0,0 +1,369 @@ +------------------------------------------------------------------------------ +-- This file is a part of the GRLIB VHDL IP LIBRARY +-- Copyright (C) 2003 - 2008, Gaisler Research +-- Copyright (C) 2008 - 2012, Aeroflex Gaisler +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +------------------------------------------------------------------------------- +-- Entity: I2cMaster +-- File: I2cMaster.vhd +-- Author: Jan Andersson - Gaisler Research +-- Contact: support@gaisler.com +-- Description: +-- +-- Generic interface to OpenCores I2C-master. This is a wrapper +-- that instantiates the byte- and bit-controller of the OpenCores I2C +-- master (OC core developed by Richard Herveille, richard@asics.ws). +-- +-- Modifications: +-- 10/2012 - Ben Reese <bareese@slac.stanford.edu> +-- Removed AMBA bus register based interfaced and replaced with generic +-- IO interface for use anywhere within a firmware design. +-- Interface based on transactions consisting of a i2c device address +-- followed by up to 4 byte-reads or 4 byte-writes. +-- +-- Dynamic filter and bus speed adjustment have been left in as features, +-- though they will probably be rarely used. + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.StdRtlPkg.all; +use work.I2cPkg.all; + +entity I2cMaster is + generic ( + TPD_G : time := 1 ns; -- Simulated propagation delay + OUTPUT_EN_POLARITY_G : integer range 0 to 1 := 0; -- output enable polarity + FILTER_G : integer range 2 to 512 := 126; -- filter bit size + DYNAMIC_FILTER_G : integer range 0 to 1 := 0); + port ( + clk : in sl; + srst : in sl := '0'; + arst : in sl := '0'; + -- Front End + i2cMasterIn : in I2cMasterInType; + i2cMasterOut : out I2cMasterOutType; + + -- I2C signals + i2ci : in i2c_in_type; + i2co : out i2c_out_type + ); +end entity I2cMaster; + +architecture rtl of I2cMaster is + ----------------------------------------------------------------------------- + -- Constants + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Types + ----------------------------------------------------------------------------- + -- i2c_master_byte_ctrl IO + type ByteCtrlInType is record + start : sl; + stop : sl; + read : sl; + write : sl; + ackIn : sl; + din : slv(7 downto 0); + end record; + + type ByteCtrlOutType is record + cmdAck : sl; + ackOut : sl; + al : sl; + busy : sl; + dout : slv(7 downto 0); + end record; + + type StateType is (WAIT_TXN_REQ_S, + ADDR_S, + WAIT_ADDR_ACK_S, + READ_S, + WAIT_READ_DATA_S, + WRITE_S, + WAIT_WRITE_ACK_S); + + -- Module Registers + type RegType is record + byteCtrlIn : ByteCtrlInType; + state : StateType; + tenbit : sl; + i2cMasterOut : I2cMasterOutType; + end record RegType; + + constant REG_INIT_C : RegType := ( + byteCtrlIn => ( + start => '0', + stop => '0', + read => '0', + write => '0', + ackIn => '0', + din => (others => '0')), + state => WAIT_TXN_REQ_S, + tenbit => '0', + i2cMasterOut => ( + txnError => '0', + wrAck => '0', + rdValid => '0', + rdData => (others => '0'))); + + + -------------------------------------------------------------------------------------------------- + -- Signals + -------------------------------------------------------------------------------------------------- + -- Register interface + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + -- Outputs from byte_ctrl block + signal byteCtrlOut : ByteCtrlOutType; + signal iSclOEn : sl; -- Internal SCL output enable + signal iSdaOEn : sl; -- Internal SDA output enablee + signal filter : slv((FILTER_G-1)*DYNAMIC_FILTER_G downto 0); -- filt input to byte_ctrl + signal arstL : sl; + +begin + + arstL <= not arst; + + -- Byte Controller from OpenCores I2C master, + -- by Richard Herveille (richard@asics.ws). The asynchronous + -- reset is tied to '1'. Only the synchronous reset is used. + -- OC I2C logic has active high reset. + byte_ctrl : i2c_master_byte_ctrl + generic map ( + filter => FILTER_G, + dynfilt => DYNAMIC_FILTER_G) + port map ( + clk => clk, + rst => srst, + nReset => arstL, + ena => i2cMasterIn.enable, + clk_cnt => i2cMasterIn.prescale, + start => r.byteCtrlIn.start, + stop => r.byteCtrlIn.stop, + read => r.byteCtrlIn.read, + write => r.byteCtrlIn.write, + ack_in => r.byteCtrlIn.ackIn, + din => r.byteCtrlIn.din, + filt => filter, + cmd_ack => byteCtrlOut.cmdAck, + ack_out => byteCtrlOut.ackOut, + i2c_busy => byteCtrlOut.busy, + i2c_al => byteCtrlOut.al, + dout => byteCtrlOut.dout, + scl_i => i2ci.scl, + scl_o => i2co.scl, + scl_oen => iscloen, + sda_i => i2ci.sda, + sda_o => i2co.sda, + sda_oen => isdaoen); + + i2co.enable <= i2cMasterIn.enable; + + -- Fix output enable polarity + soepol0 : if OUTPUT_EN_POLARITY_G = 0 generate + i2co.scloen <= iscloen; + i2co.sdaoen <= isdaoen; + end generate soepol0; + soepol1 : if OUTPUT_EN_POLARITY_G /= 0 generate + i2co.scloen <= not iscloen; + i2co.sdaoen <= not isdaoen; + end generate soepol1; + + + + + comb : process (r, byteCtrlOut, i2cMasterIn, srst) + variable v : RegType; + variable indexVar : integer; + begin -- process comb + v := r; + + -- byteCtrl commands default to zero + -- unless overridden in a state below + v.byteCtrlIn.start := '0'; + v.byteCtrlIn.stop := '0'; + v.byteCtrlIn.read := '0'; + v.byteCtrlIn.write := '0'; + v.byteCtrlIn.ackIn := '0'; + + v.i2cMasterOut.wrAck := '0'; -- pulsed + + if (i2cMasterIn.rdAck = '1') then + v.i2cMasterOut.rdValid := '0'; + v.i2cMasterOut.txnError := '0'; + end if; + + case (r.state) is + when WAIT_TXN_REQ_S => + -- Reset front end outputs + v.i2cMasterOut.rdData := (others => '0'); -- Necessary? + -- If new request and any previous rdData has been acked. + if (i2cMasterIn.txnReq = '1' and r.i2cMasterOut.rdValid = '0') then + v.state := ADDR_S; + v.tenbit := i2cMasterIn.tenbit; + end if; + + when ADDR_S => + v.byteCtrlIn.start := '1'; + v.byteCtrlIn.write := '1'; + if (r.tenbit = '0') then + if (i2cMasterIn.tenbit = '0') then + -- Send normal 7 bit address + v.byteCtrlIn.din(7 downto 1) := i2cMasterIn.addr(6 downto 0); + v.byteCtrlIn.din(0) := not i2cMasterIn.op; + else + -- Send second half of 10 bit address + v.byteCtrlIn.din := i2cMasterIn.addr(7 downto 0); + end if; + else + -- Send first half of 10 bit address + v.byteCtrlIn.din(7 downto 3) := "00000"; + v.byteCtrlIn.din(2 downto 1) := i2cMasterIn.addr(9 downto 8); + v.byteCtrlIn.din(0) := not i2cMasterIn.op; + end if; + v.state := WAIT_ADDR_ACK_S; + + + when WAIT_ADDR_ACK_S => + if (byteCtrlOut.cmdAck = '1') then -- Master sent the command + if (byteCtrlOut.ackOut = '0') then -- Slave ack'd the transfer + if (r.tenbit = '1') then -- Must send second half of addr if tenbit set + v.tenbit := '0'; + v.state := ADDR_S; + else + -- Do read or write depending on op + if (i2cMasterIn.op = '0') then + v.state := READ_S; + else + v.state := WRITE_S; + end if; + end if; + else + -- Slave did not ack the transfer, fail the txn + v.i2cMasterOut.txnError := '1'; + v.i2cMasterOut.rdValid := '1'; + v.i2cMasterOut.rdData := I2C_INVALID_ADDR_ERROR_C; + v.state := WAIT_TXN_REQ_S; + end if; + end if; + + + when READ_S => + if (r.i2cMasterOut.rdValid = '0') then -- Previous byte has been ack'd + v.byteCtrlIn.read := '1'; + -- If last byte of txn send nack. + -- Send stop on last byte if enabled (else repeated start will occur on next txn). + v.byteCtrlIn.ackIn := not i2cMasterIn.txnReq; + v.byteCtrlIn.stop := not i2cMasterIn.txnReq and i2cMasterIn.stop; + v.state := WAIT_READ_DATA_S; + end if; + + + when WAIT_READ_DATA_S => + v.byteCtrlIn.stop := r.byteCtrlIn.stop; -- Hold stop or it wont get seen + v.byteCtrlIn.ackIn := r.byteCtrlIn.ackIn; -- This too + if (byteCtrlOut.cmdAck = '1') then -- Master sent the command + v.byteCtrlIn.stop := '0'; -- Drop stop asap or it will be repeated + v.byteCtrlIn.ackIn := '0'; + v.i2cMasterOut.rdData := byteCtrlOut.dout; + v.i2cMasterOut.rdValid := '1'; + if (i2cMasterIn.txnReq = '0') then -- Last byte of txn + v.i2cMasterOut.txnError := '0'; -- Necessary? Should already be 0 + v.state := WAIT_TXN_REQ_S; + else + -- If not last byte, read another. + v.state := READ_S; + end if; + end if; + + when WRITE_S => + -- Write the next byte + if (i2cMasterIn.wrValid = '1' and r.i2cMasterOut.wrAck = '0') then + v.byteCtrlIn.write := '1'; + -- Send stop on last byte if enabled (else repeated start will occur on next txn). + v.byteCtrlIn.stop := not i2cMasterIn.txnReq and i2cMasterIn.stop; + v.byteCtrlIn.din := i2cMasterIn.wrData; + v.state := WAIT_WRITE_ACK_S; + end if; + + when WAIT_WRITE_ACK_S => + v.byteCtrlIn.stop := r.byteCtrlIn.stop; + if (byteCtrlOut.cmdAck = '1') then -- Master sent the command + if (byteCtrlOut.ackOut = '0') then -- Slave ack'd the transfer + v.byteCtrlIn.stop := '0'; + v.i2cMasterOut.wrAck := '1'; -- Pass wr ack to front end + if (i2cMasterIn.txnReq = '0') then -- Last byte of txn + v.i2cMasterOut.txnError := '0'; -- Necessary, should already be 0? + v.state := WAIT_TXN_REQ_S; + else + -- If not last byte, write nother + v.state := WRITE_S; + end if; + else + -- Slave did not ack the transfer, fail the txn + v.i2cMasterOut.txnError := '1'; + v.i2cMasterOut.rdValid := '1'; + v.i2cMasterOut.rdData := I2C_WRITE_ACK_ERROR_C; + v.state := WAIT_TXN_REQ_S; + end if; + end if; + + when others => v.state := WAIT_TXN_REQ_S; + end case; + + -- Must always monitor for arbitration loss + if (byteCtrlOut.al = '1') then + -- Retry the entire TXN. Nothing done has been valid if arbitration is lost. + -- Should probably have a retry limit. + v.state := WAIT_TXN_REQ_S; + v.i2cMasterOut.txnError := '1'; + v.i2cMasterOut.rdValid := '1'; + v.i2cMasterOut.rdData := I2C_ARBITRATION_LOST_ERROR_C; + end if; + + ------------------------------------------------------------------------------------------------ + -- Synchronous Reset + ------------------------------------------------------------------------------------------------ + if (srst = '1') then + v := REG_INIT_C; + end if; + + ------------------------------------------------------------------------------------------------ + -- Signal Assignments + ------------------------------------------------------------------------------------------------ + -- Update registers + rin <= v; + + -- Assign outputs + i2cMasterOut <= r.i2cMasterOut; + + end process comb; + filter <= i2cMasterIn.filter when DYNAMIC_FILTER_G = 1 else (others => '0'); + + reg : process (clk, arst) + begin + if (arst = '1') then + r <= REG_INIT_C after TPD_G; + elsif rising_edge(clk) then + r <= rin after TPD_G; + end if; + end process reg; + + +end architecture rtl; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/I2cPkg.vhd b/rce/fw-hsio/modules/pixelcore/hdl/I2cPkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..95db89a004b4da8333f4f7eb9ba6d5d866b27561 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/I2cPkg.vhd @@ -0,0 +1,199 @@ +------------------------------------------------------------------------------ +-- This file is a part of the GRLIB VHDL IP LIBRARY +-- Copyright (C) 2003 - 2008, Gaisler Research +-- Copyright (C) 2008 - 2012, Aeroflex Gaisler +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +----------------------------------------------------------------------------- +-- Package: i2c +-- File: i2c.vhd +-- Author: Jiri Gaisler - Gaisler Research +-- Description: I2C interface package +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use work.StdRtlPkg.all; + +package I2cPkg is + + type i2c_in_type is record + scl : std_ulogic; + sda : std_ulogic; + end record; + + type i2c_in_array is array (natural range <>) of i2c_in_type; + + type i2c_out_type is record + scl : std_ulogic; + scloen : std_ulogic; + sda : std_ulogic; + sdaoen : std_ulogic; + enable : std_ulogic; + end record; + + type i2c_out_array is array (natural range <>) of i2c_out_type; + + -------------------------------------------------------------------------------------------------- + constant I2C_INVALID_ADDR_ERROR_C : slv(7 downto 0) := X"01"; + constant I2C_WRITE_ACK_ERROR_C : slv(7 downto 0) := X"02"; + constant I2C_ARBITRATION_LOST_ERROR_C : slv(7 downto 0) := X"03"; + + type I2cMasterInType is record + enable : sl; -- Enable the master + prescale : slv(15 downto 0); -- Determines i2c clock speed + filter : slv(15 downto 0); -- Dynamic filter value + txnReq : sl; -- Execute a transaction + stop : sl; -- Set STOP when done + op : sl; -- 1 for write, 0 for read + addr : slv(9 downto 0); -- i2c device address + tenbit : sl; -- use 10 bit addressing + wrValid : sl; + wrData : slv(7 downto 0); -- Data sent during write txn + rdAck : sl; + end record; + + type I2cMasterOutType is record + txnError : sl; -- An error occured during the txn + wrAck : sl; + rdValid : sl; + rdData : slv(7 downto 0); -- Data received during read txn + end record; + -------------------------------------------------------------------------------------------------- + type I2cRegMasterInType is record + i2cAddr : slv(9 downto 0); + tenbit : sl; + regAddr : slv(31 downto 0); + regWrData : slv(31 downto 0); + regOp : sl; + regAddrSize : slv(1 downto 0); + regDataSize : slv(1 downto 0); + regReq : sl; + endianness : sl; + end record; + + constant I2C_REG_MASTER_IN_INIT_C : I2cRegMasterInType := ( + i2cAddr => (others => '0'), + tenbit => '0', + regAddr => (others => '0'), + regWrData => (others => '0'), + regOp => '0', -- 1 for write, 0 for read + regAddrSize => (others => '0'), + regDataSize => (others => '0'), + regReq => '0', + endianness => '0'); + + type I2cRegMasterInArray is array (natural range <>) of I2cRegMasterInType; + + type I2cRegMasterOutType is record + regAck : sl; + regFail : sl; + regFailCode : slv(7 downto 0); + regRdData : slv(31 downto 0); + end record; + + constant I2C_REG_MASTER_OUT_INIT_C : I2cRegMasterOutType := ( + regAck => '0', + regFail => '0', + regFailCode => (others => '0'), + regRdData => (others => '0')); + + type I2cRegMasterOutArray is array (natural range <>) of I2cRegMasterOutType; + + -------------------------------------------------------------------------------------------------- + type I2cSlaveInType is record + enable : sl; + txValid : sl; + txData : slv(7 downto 0); + rxAck : sl; + end record I2cSlaveInType; + + constant I2C_SLAVE_IN_INIT_C : I2cSlaveInType := ( + enable => '0', + txValid => '0', + txData => (others => '0'), + rxAck => '0'); + + type I2cSlaveOutType is record + rxActive : sl; + rxValid : sl; + rxData : slv(7 downto 0); + txActive : sl; + txAck : sl; + nack : sl; + end record I2cSlaveOutType; + + constant I2C_SLAVE_OUT_INIT_C : I2cSlaveOutType := ( + rxActive => '0', + rxValid => '0', + rxData => (others => '0'), + txActive => '0', + txAck => '0', + nack => '0'); + + ------------------------------------------------------------------------------------------------- + -- AXI Bridge Generic Type, stick here for now + ------------------------------------------------------------------------------------------------- + type I2cAxiLiteDevType is record + i2cAddress : slv(9 downto 0); + i2cTenbit : sl; + dataSize : integer; + endianness : sl; + end record I2cAxiLiteDevType; + + type I2cAxiLiteDevArray is array (natural range <>) of I2cAxiLiteDevType; + + -------------------------------------------------------------------------------------------------- + -- Opencores i2c + component i2c_master_byte_ctrl is + generic (filter : integer; dynfilt : integer); + port ( + clk : in std_logic; + rst : in std_logic; -- active high reset + nReset : in std_logic; -- asynchornous active low reset + -- (not used in GRLIB) + ena : in std_logic; -- core enable signal + + clk_cnt : in std_logic_vector(15 downto 0); -- 4x SCL + + -- input signals + start, + stop, + read, + write, + ack_in : std_logic; + din : in std_logic_vector(7 downto 0); + filt : in std_logic_vector((filter-1)*dynfilt downto 0); + + -- output signals + cmd_ack : out std_logic; + ack_out : out std_logic; + i2c_busy : out std_logic; + i2c_al : out std_logic; + dout : out std_logic_vector(7 downto 0); + + -- i2c lines + scl_i : in std_logic; -- i2c clock line input + scl_o : out std_logic; -- i2c clock line output + scl_oen : out std_logic; -- i2c clock line output enable, active low + sda_i : in std_logic; -- i2c data line input + sda_o : out std_logic; -- i2c data line output + sda_oen : out std_logic -- i2c data line output enable, active low + ); + end component i2c_master_byte_ctrl; + + + +end; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/I2cRegMaster.vhd b/rce/fw-hsio/modules/pixelcore/hdl/I2cRegMaster.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1cdfbb615385c75551789d41cb4e44d49bc83b85 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/I2cRegMaster.vhd @@ -0,0 +1,261 @@ +------------------------------------------------------------------------------- +-- Title : +------------------------------------------------------------------------------- +-- File : I2cRegMaster.vhd +-- Author : Benjamin Reese <bareese@slac.stanford.edu> +-- Company : SLAC National Accelerator Laboratory +-- Created : 2013-01-22 +-- Last update: 2014-09-09 +-- Platform : +-- Standard : VHDL'93/02 +------------------------------------------------------------------------------- +-- Description: +-- PRESCALE_G = (clk_freq / (5 * i2c_freq)) - 1 +-- FILTER_G = (min_pulse_time / clk_period) + 1 +------------------------------------------------------------------------------- +-- Copyright (c) 2013 SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.StdRtlPkg.all; +use work.I2cPkg.all; + +entity I2cRegMaster is + + generic ( + TPD_G : time := 1 ns; + OUTPUT_EN_POLARITY_G : integer range 0 to 1 := 0; + FILTER_G : integer range 2 to 512 := 8; + PRESCALE_G : integer range 0 to 655535 := 62); + port ( + clk : in sl; + srst : in sl := '0'; + arst : in sl := '0'; + regIn : in I2cRegMasterInType; + regOut : out I2cRegMasterOutType; + i2ci : in i2c_in_type; + i2co : out i2c_out_type); + +end entity I2cRegMaster; + +architecture rtl of I2cRegMaster is + + type StateType is (WAIT_REQ_S, ADDR_S, WRITE_S, READ_TXN_S, READ_S, REG_ACK_S); + + type RegType is record + state : StateType; + byteCount : unsigned(1 downto 0); + regOut : I2cRegMasterOutType; + i2cMasterIn : I2cMasterInType; + end record RegType; + + constant REG_INIT_C : RegType := ( + state => WAIT_REQ_S, + byteCount => (others => '0'), + regOut => ( + regAck => '0', + regFail => '0', + regFailCode => (others => '0'), + regRdData => (others => '0')), + i2cMasterIn => ( + enable => '0', + prescale => (others => '0'), + filter => (others => '0'), + txnReq => '0', + stop => '0', + op => '0', + addr => (others => '0'), + tenbit => '0', + wrValid => '0', + wrData => (others => '0'), + rdAck => '0')); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + signal i2cMasterIn : I2cMasterInType; + signal i2cMasterOut : I2cMasterOutType; + + function getIndex ( + endianness : sl; + byteCount : unsigned; + totalBytes : unsigned) + return integer is + begin + if (endianness = '0') then + -- little endian + return to_integer(byteCount)*8; + else + -- big endian + return (to_integer(totalBytes)-to_integer(byteCount))*8; + end if; + end function getIndex; + +begin + + i2cMaster_1 : entity work.I2cMaster + generic map ( + TPD_G => TPD_G, + OUTPUT_EN_POLARITY_G => OUTPUT_EN_POLARITY_G, + FILTER_G => FILTER_G, + DYNAMIC_FILTER_G => 0) + port map ( + clk => clk, + srst => srst, + arst => arst, + i2cMasterIn => i2cMasterIn, + i2cMasterOut => i2cMasterOut, + i2ci => i2ci, + i2co => i2co); + + comb : process (regIn, i2cMasterOut, r, srst) is + variable v : RegType; + variable addrIndexVar : integer; + variable dataIndexVar : integer; + begin + v := r; + + addrIndexVar := getIndex(regIn.endianness, r.byteCount, unsigned(regIn.regAddrSize)); + dataIndexVar := getIndex(regIn.endianness, r.byteCount, unsigned(regIn.regDataSize)); + + v.regOut.regAck := '0'; + v.regOut.regFail := '0'; + + v.i2cMasterIn.rdAck := '0'; + + case r.state is + when WAIT_REQ_S => + v.byteCount := (others => '0'); + if (regIn.regReq = '1') then + v.regOut.regRdData := (others => '0'); + v.i2cMasterIn.txnReq := '1'; + v.i2cMasterIn.op := '1'; -- Write address bytes + v.i2cMasterIn.stop := '1'; --regIn.regOp; -- no i2c stop after addr when reg read + v.state := ADDR_S; + end if; + + when ADDR_S => + -- When a new register access request is seen, + -- Write the register address out on the bus first + -- One byte at a time, order determined by endianness input + v.i2cMasterIn.wrData := regIn.regAddr(addrIndexVar+7 downto addrIndexVar); + v.i2cMasterIn.wrValid := '1'; + -- Must drop txnReq as last byte is sent if reading + v.i2cMasterIn.txnReq := not toSl(slv(r.byteCount) = regIn.regAddrSize and regIn.regOp = '0'); + + if (i2cMasterOut.wrAck = '1') then + v.byteCount := r.byteCount + 1; + v.i2cMasterIn.wrValid := '0'; + if (slv(r.byteCount) = regIn.regAddrSize) then + -- Done sending addr + v.byteCount := (others => '0'); + if (regIn.regOp = '1') then + v.state := WRITE_S; + else + v.state := READ_TXN_S; + end if; + end if; + end if; + + when WRITE_S => + -- Txn started in WAIT_REQ_S still active + -- Put wrData on the bus one byte at a time + v.i2cMasterIn.wrData := regIn.regWrData(dataIndexVar+7 downto dataIndexVar); + v.i2cMasterIn.wrValid := '1'; + v.i2cMasterIn.txnReq := not toSl(slv(r.byteCount) = regIn.regDataSize); + v.i2cMasterIn.stop := '1'; -- Send stop when done writing all bytes + if (i2cMasterOut.wrAck = '1') then + v.byteCount := r.byteCount + 1; + v.i2cMasterIn.wrValid := '0'; + if (slv(r.byteCount) = regIn.regDataSize) then -- could use rxnReq = 0 + v.state := REG_ACK_S; + end if; + end if; + + + when READ_TXN_S => + -- Start new txn to read data bytes + v.i2cMasterIn.txnReq := '1'; + v.i2cMasterIn.op := '0'; + v.i2cMasterIn.stop := '1'; -- i2c stop after all bytes are read + v.state := READ_S; + + when READ_S => + -- Drop txnReq on last byte + v.i2cMasterIn.txnReq := not toSl(slv(r.byteCount) = regIn.regDataSize); + -- Read data bytes as they arrive + if (i2cMasterOut.rdValid = '1' and r.i2cMasterIn.rdAck = '0') then + v.byteCount := r.byteCount + 1; + v.regOut.regRdData(dataIndexVar+7 downto dataIndexVar) := i2cMasterOut.rdData; + v.i2cMasterIn.rdAck := '1'; + if (slv(r.byteCount) = regIn.regDataSize) then + -- Done + v.state := REG_ACK_S; + end if; + end if; + + when REG_ACK_S => + -- Req done. Ack the req. + -- Might have failed so hold regFail (would be set to 0 otherwise). + v.regOut.regAck := '1'; + v.regOut.regFail := r.regOut.regFail; + if (regIn.regReq = '0') then +-- v.regOut.regAck := '0'; Might want this back. + v.state := WAIT_REQ_S; + end if; + + end case; + + -- Always check for errors an cancel the txn if they happen + if (i2cMasterOut.txnError = '1' and i2cMasterOut.rdValid = '1') then + v.regOut.regFail := '1'; + v.regOut.regFailCode := i2cMasterOut.rdData; + v.i2cMasterIn.txnReq := '0'; + v.i2cMasterIn.rdAck := '1'; + v.state := REG_ACK_S; + end if; + + ------------------------------------------------------------------------------------------------ + -- Synchronous Reset + ------------------------------------------------------------------------------------------------ + if (srst = '1') then + v := REG_INIT_C; + end if; + + ------------------------------------------------------------------------------------------------ + -- Signal Assignments + ------------------------------------------------------------------------------------------------ + -- Update registers + rin <= v; + + -- Internal signals + i2cMasterIn.enable <= '1'; + i2cMasterIn.prescale <= slv(to_unsigned(PRESCALE_G, 16)); + i2cMasterIn.filter <= (others => '0'); -- Not using dynamic filtering + i2cMasterIn.addr <= regIn.i2cAddr; + i2cMasterIn.tenbit <= regIn.tenbit; + i2cMasterIn.txnReq <= r.i2cMasterIn.txnReq; + i2cMasterIn.stop <= r.i2cMasterIn.stop; + i2cMasterIn.op <= r.i2cMasterIn.op; + i2cMasterIn.wrValid <= r.i2cMasterIn.wrValid; + i2cMasterIn.wrData <= r.i2cMasterIn.wrData; + i2cMasterIn.rdAck <= r.i2cMasterIn.rdAck; + + -- Outputs + regOut <= r.regOut; + + end process comb; + + seq : process (clk, arst) is + begin + if (arst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(clk)) then + r <= rin after TPD_G; + end if; + end process seq; + + + +end architecture rtl; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/OutputEncoder.vhd b/rce/fw-hsio/modules/pixelcore/hdl/OutputEncoder.vhd new file mode 100644 index 0000000000000000000000000000000000000000..961f323fea1c516b6e8a14005d710eb379bda6a7 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/OutputEncoder.vhd @@ -0,0 +1,56 @@ + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity outputencoder is + port ( + clock : in std_logic; + rst : in std_logic; + clockx2 : in std_logic; + datain : in std_logic; + encode : in std_logic_vector(1 downto 0); + dataout : out std_logic + ); +end outputencoder; + +architecture OUTPUTENCODER of outputencoder is + + signal bmp: std_logic; + signal man: std_logic; + +begin + + process(clockx2, rst) + begin + if(rst='1') then + bmp<='0'; + elsif(clockx2'event and clockx2='1') then + if(clock='1' or datain='1')then + bmp<=not bmp; + end if; + end if; + end process; + + process(clockx2, rst) + begin + if(rst='1') then + man<='0'; + elsif(clockx2'event and clockx2='1') then + if(clock='1')then + man<= datain; + else + man<=not datain; + end if; + end if; + end process; + + with encode select + dataout<= datain when "00", + bmp when "01", + man when "10", + datain when others; + +end OUTPUTENCODER; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/StdRtlPkg.vhd b/rce/fw-hsio/modules/pixelcore/hdl/StdRtlPkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..c26b8eb9536f1023a34f829349efb343572827e2 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/StdRtlPkg.vhd @@ -0,0 +1,1267 @@ +------------------------------------------------------------------------------- +-- Title : Standard RTL Package +------------------------------------------------------------------------------- +-- File : StdRtlPkg.vhd +-- Author : Benjamin Reese +-- Standard : VHDL'93/02, Math Packages +------------------------------------------------------------------------------- +-- Description: This package defines "sl" and "slv" shorthand subtypes for +-- std_logic and std_logic_vector receptively. It also defines +-- many handy utility functions. Nearly every .vhd file should +-- use this package. +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +use ieee.math_real.all; + +package StdRtlPkg is + + -- Typing std_logic(_vector) is annoying + subtype sl is std_logic; + subtype slv is std_logic_vector; + + -- Declare arrays of built in types + --type SlvArray is array (natural range <>) of slv; -- not supported in VCS yet (14APRIL2014 -- LLR) + type IntegerArray is array (natural range <>) of integer; + type NaturalArray is array (natural range <>) of natural; + type PositiveArray is array (natural range <>) of positive; + type RealArray is array (natural range <>) of real; + type TimeArray is array (natural range <>) of time; + type BooleanArray is array (natural range <>) of boolean; + + -- Declare vector arrays of built in types + --type SlvVectorArray is array (natural range<>, natural range<>) of slv; -- not supported in VCS yet (14APRIL2014 -- LLR) + type IntegerVectorArray is array (natural range<>, natural range<>) of integer; + type NaturalVectorArray is array (natural range<>, natural range<>) of natural; + type PositiveVectorArray is array (natural range<>, natural range<>) of positive; + type RealVectorArray is array (natural range<>, natural range<>) of real; + type TimeVectorArray is array (natural range<>, natural range<>) of time; + type BooleanVectorArray is array (natural range<>, natural range<>) of boolean; + + -- Create an arbitrary sized slv with all bits set high or low + function slvAll (size : positive; value : sl) return slv; + function slvZero (size : positive) return slv; + function slvOne (size : positive) return slv; + + -- Very useful functions + function isPowerOf2 (number : natural) return boolean; + function isPowerOf2 (vector : slv) return boolean; + function log2 (constant number : positive) return natural; + function bitSize (constant number : natural) return positive; + function bitReverse (a : slv) return slv; + + -- Similar to python's range() function + function list (constant start, size, step : integer) return IntegerArray; + + -- Simple decoder and mux functions + function decode(v : slv) return slv; + function genmux(s, v : slv) return sl; + + -- This should be unnecessary in VHDL 2008 + function toBoolean (logic : sl) return boolean; + function toSl (bool : boolean) return sl; + function toString (bool : boolean) return string; + function toBoolean (str : string) return boolean; + + -- Unary reduction operators, also unnecessary in VHDL 2008 + function uOr (vec : slv) return sl; + function uAnd (vec : slv) return sl; + function uXor (vec : slv) return sl; + + -- Test if all bits in a vector are set to a given logic value + function allBits (vec : slv; test : sl) return boolean; + function noBits (vec : slv; test : sl) return boolean; + + -- These just use uXor to calculate parity + -- Output is parity bit value needed to achieve that parity given vec. + function evenParity (vec : slv) return sl; + function oddParity (vec : slv) return sl; + + -- Functions for counting the number of '1' in a slv bus + function onesCount (vec : slv) return unsigned; + function onesCount (vec : slv) return slv; + + -- Gray Code functions + function grayEncode (vec : unsigned) return unsigned; + function grayEncode (vec : slv) return slv; + function grayDecode (vec : unsigned) return unsigned; + function grayDecode (vec : slv) return slv; + + -- Linear Feedback Shift Register function + function lfsrShift (lfsr : slv; constant taps : NaturalArray; input : sl := '0') return slv; + + function maximum (left, right : integer) return integer; + function minimum (left, right : integer) return integer; + + -- One line if-then-else functions. Useful for assigning constants based on generics. + function ite(i : boolean; t : boolean; e : boolean) return boolean; + function ite(i : boolean; t : sl; e : sl) return sl; + function ite(i : boolean; t : slv; e : slv) return slv; + function ite(i : boolean; t : bit_vector; e : bit_vector) return bit_vector; + function ite(i : boolean; t : character; e : character) return character; + function ite(i : boolean; t : string; e : string) return string; + function ite(i : boolean; t : integer; e : integer) return integer; + function ite(i : boolean; t : real; e : real) return real; + function ite(i : boolean; t : time; e : time) return time; + + -- conv_std_logic_vector functions + function toSlv(ARG : integer; SIZE : integer) return slv; + + -- gets real multiplication + function getRealMult (A, B : real) return real; + function getRealMult (A : integer; B : real) return real; + function getRealMult (A : real; B : integer) return real; + + -- gets real division + function getRealDiv (A, B : real) return real; + function getRealDiv (A : integer; B : real) return real; + function getRealDiv (A : real; B : integer) return real; + + function adcConversion (ain : real; low : real; high : real; bits : positive; twosComp : boolean) return slv; + + --gets a time ratio + function getTimeRatio (T1, T2 : time) return natural; --not supported by Vivado + function getTimeRatio (T1, T2 : real) return natural; + + procedure assignSlv (i : inout integer; vector : inout slv; value : in slv); + procedure assignSlv (i : inout integer; vector : inout slv; value : in sl); + procedure assignRecord (i : inout integer; vector : in slv; value : inout slv); + procedure assignRecord (i : inout integer; vector : in slv; value : inout sl); + + -- Resize an SLV, either by trimming or padding upper bits + function resizeSlv ( vector : slv; newSize : integer) return slv; + + -- Some synthesis tools wont accept unit types + -- pragma translate_off + type frequency is range 0 to 2147483647 + units + Hz; + kHz = 1000 Hz; + MHz = 1000 kHz; + GHz = 1000 MHz; + end units; + + function toTime(f : frequency) return time; + -- pragma translate_on + + -- Add more slv array sizes here as they become needed + type Slv256Array is array (natural range <>) of slv(255 downto 0); + type Slv255Array is array (natural range <>) of slv(254 downto 0); + type Slv254Array is array (natural range <>) of slv(253 downto 0); + type Slv253Array is array (natural range <>) of slv(252 downto 0); + type Slv252Array is array (natural range <>) of slv(251 downto 0); + type Slv251Array is array (natural range <>) of slv(250 downto 0); + type Slv250Array is array (natural range <>) of slv(249 downto 0); + type Slv249Array is array (natural range <>) of slv(248 downto 0); + type Slv248Array is array (natural range <>) of slv(247 downto 0); + type Slv247Array is array (natural range <>) of slv(246 downto 0); + type Slv246Array is array (natural range <>) of slv(245 downto 0); + type Slv245Array is array (natural range <>) of slv(244 downto 0); + type Slv244Array is array (natural range <>) of slv(243 downto 0); + type Slv243Array is array (natural range <>) of slv(242 downto 0); + type Slv242Array is array (natural range <>) of slv(241 downto 0); + type Slv241Array is array (natural range <>) of slv(240 downto 0); + type Slv240Array is array (natural range <>) of slv(239 downto 0); + type Slv239Array is array (natural range <>) of slv(238 downto 0); + type Slv238Array is array (natural range <>) of slv(237 downto 0); + type Slv237Array is array (natural range <>) of slv(236 downto 0); + type Slv236Array is array (natural range <>) of slv(235 downto 0); + type Slv235Array is array (natural range <>) of slv(234 downto 0); + type Slv234Array is array (natural range <>) of slv(233 downto 0); + type Slv233Array is array (natural range <>) of slv(232 downto 0); + type Slv232Array is array (natural range <>) of slv(231 downto 0); + type Slv231Array is array (natural range <>) of slv(230 downto 0); + type Slv230Array is array (natural range <>) of slv(229 downto 0); + type Slv229Array is array (natural range <>) of slv(228 downto 0); + type Slv228Array is array (natural range <>) of slv(227 downto 0); + type Slv227Array is array (natural range <>) of slv(226 downto 0); + type Slv226Array is array (natural range <>) of slv(225 downto 0); + type Slv225Array is array (natural range <>) of slv(224 downto 0); + type Slv224Array is array (natural range <>) of slv(223 downto 0); + type Slv223Array is array (natural range <>) of slv(222 downto 0); + type Slv222Array is array (natural range <>) of slv(221 downto 0); + type Slv221Array is array (natural range <>) of slv(220 downto 0); + type Slv220Array is array (natural range <>) of slv(219 downto 0); + type Slv219Array is array (natural range <>) of slv(218 downto 0); + type Slv218Array is array (natural range <>) of slv(217 downto 0); + type Slv217Array is array (natural range <>) of slv(216 downto 0); + type Slv216Array is array (natural range <>) of slv(215 downto 0); + type Slv215Array is array (natural range <>) of slv(214 downto 0); + type Slv214Array is array (natural range <>) of slv(213 downto 0); + type Slv213Array is array (natural range <>) of slv(212 downto 0); + type Slv212Array is array (natural range <>) of slv(211 downto 0); + type Slv211Array is array (natural range <>) of slv(210 downto 0); + type Slv210Array is array (natural range <>) of slv(209 downto 0); + type Slv209Array is array (natural range <>) of slv(208 downto 0); + type Slv208Array is array (natural range <>) of slv(207 downto 0); + type Slv207Array is array (natural range <>) of slv(206 downto 0); + type Slv206Array is array (natural range <>) of slv(205 downto 0); + type Slv205Array is array (natural range <>) of slv(204 downto 0); + type Slv204Array is array (natural range <>) of slv(203 downto 0); + type Slv203Array is array (natural range <>) of slv(202 downto 0); + type Slv202Array is array (natural range <>) of slv(201 downto 0); + type Slv201Array is array (natural range <>) of slv(200 downto 0); + type Slv200Array is array (natural range <>) of slv(199 downto 0); + type Slv199Array is array (natural range <>) of slv(198 downto 0); + type Slv198Array is array (natural range <>) of slv(197 downto 0); + type Slv197Array is array (natural range <>) of slv(196 downto 0); + type Slv196Array is array (natural range <>) of slv(195 downto 0); + type Slv195Array is array (natural range <>) of slv(194 downto 0); + type Slv194Array is array (natural range <>) of slv(193 downto 0); + type Slv193Array is array (natural range <>) of slv(192 downto 0); + type Slv192Array is array (natural range <>) of slv(191 downto 0); + type Slv191Array is array (natural range <>) of slv(190 downto 0); + type Slv190Array is array (natural range <>) of slv(189 downto 0); + type Slv189Array is array (natural range <>) of slv(188 downto 0); + type Slv188Array is array (natural range <>) of slv(187 downto 0); + type Slv187Array is array (natural range <>) of slv(186 downto 0); + type Slv186Array is array (natural range <>) of slv(185 downto 0); + type Slv185Array is array (natural range <>) of slv(184 downto 0); + type Slv184Array is array (natural range <>) of slv(183 downto 0); + type Slv183Array is array (natural range <>) of slv(182 downto 0); + type Slv182Array is array (natural range <>) of slv(181 downto 0); + type Slv181Array is array (natural range <>) of slv(180 downto 0); + type Slv180Array is array (natural range <>) of slv(179 downto 0); + type Slv179Array is array (natural range <>) of slv(178 downto 0); + type Slv178Array is array (natural range <>) of slv(177 downto 0); + type Slv177Array is array (natural range <>) of slv(176 downto 0); + type Slv176Array is array (natural range <>) of slv(175 downto 0); + type Slv175Array is array (natural range <>) of slv(174 downto 0); + type Slv174Array is array (natural range <>) of slv(173 downto 0); + type Slv173Array is array (natural range <>) of slv(172 downto 0); + type Slv172Array is array (natural range <>) of slv(171 downto 0); + type Slv171Array is array (natural range <>) of slv(170 downto 0); + type Slv170Array is array (natural range <>) of slv(169 downto 0); + type Slv169Array is array (natural range <>) of slv(168 downto 0); + type Slv168Array is array (natural range <>) of slv(167 downto 0); + type Slv167Array is array (natural range <>) of slv(166 downto 0); + type Slv166Array is array (natural range <>) of slv(165 downto 0); + type Slv165Array is array (natural range <>) of slv(164 downto 0); + type Slv164Array is array (natural range <>) of slv(163 downto 0); + type Slv163Array is array (natural range <>) of slv(162 downto 0); + type Slv162Array is array (natural range <>) of slv(161 downto 0); + type Slv161Array is array (natural range <>) of slv(160 downto 0); + type Slv160Array is array (natural range <>) of slv(159 downto 0); + type Slv159Array is array (natural range <>) of slv(158 downto 0); + type Slv158Array is array (natural range <>) of slv(157 downto 0); + type Slv157Array is array (natural range <>) of slv(156 downto 0); + type Slv156Array is array (natural range <>) of slv(155 downto 0); + type Slv155Array is array (natural range <>) of slv(154 downto 0); + type Slv154Array is array (natural range <>) of slv(153 downto 0); + type Slv153Array is array (natural range <>) of slv(152 downto 0); + type Slv152Array is array (natural range <>) of slv(151 downto 0); + type Slv151Array is array (natural range <>) of slv(150 downto 0); + type Slv150Array is array (natural range <>) of slv(149 downto 0); + type Slv149Array is array (natural range <>) of slv(148 downto 0); + type Slv148Array is array (natural range <>) of slv(147 downto 0); + type Slv147Array is array (natural range <>) of slv(146 downto 0); + type Slv146Array is array (natural range <>) of slv(145 downto 0); + type Slv145Array is array (natural range <>) of slv(144 downto 0); + type Slv144Array is array (natural range <>) of slv(143 downto 0); + type Slv143Array is array (natural range <>) of slv(142 downto 0); + type Slv142Array is array (natural range <>) of slv(141 downto 0); + type Slv141Array is array (natural range <>) of slv(140 downto 0); + type Slv140Array is array (natural range <>) of slv(139 downto 0); + type Slv139Array is array (natural range <>) of slv(138 downto 0); + type Slv138Array is array (natural range <>) of slv(137 downto 0); + type Slv137Array is array (natural range <>) of slv(136 downto 0); + type Slv136Array is array (natural range <>) of slv(135 downto 0); + type Slv135Array is array (natural range <>) of slv(134 downto 0); + type Slv134Array is array (natural range <>) of slv(133 downto 0); + type Slv133Array is array (natural range <>) of slv(132 downto 0); + type Slv132Array is array (natural range <>) of slv(131 downto 0); + type Slv131Array is array (natural range <>) of slv(130 downto 0); + type Slv130Array is array (natural range <>) of slv(129 downto 0); + type Slv129Array is array (natural range <>) of slv(128 downto 0); + type Slv128Array is array (natural range <>) of slv(127 downto 0); + type Slv127Array is array (natural range <>) of slv(126 downto 0); + type Slv126Array is array (natural range <>) of slv(125 downto 0); + type Slv125Array is array (natural range <>) of slv(124 downto 0); + type Slv124Array is array (natural range <>) of slv(123 downto 0); + type Slv123Array is array (natural range <>) of slv(122 downto 0); + type Slv122Array is array (natural range <>) of slv(121 downto 0); + type Slv121Array is array (natural range <>) of slv(120 downto 0); + type Slv120Array is array (natural range <>) of slv(119 downto 0); + type Slv119Array is array (natural range <>) of slv(118 downto 0); + type Slv118Array is array (natural range <>) of slv(117 downto 0); + type Slv117Array is array (natural range <>) of slv(116 downto 0); + type Slv116Array is array (natural range <>) of slv(115 downto 0); + type Slv115Array is array (natural range <>) of slv(114 downto 0); + type Slv114Array is array (natural range <>) of slv(113 downto 0); + type Slv113Array is array (natural range <>) of slv(112 downto 0); + type Slv112Array is array (natural range <>) of slv(111 downto 0); + type Slv111Array is array (natural range <>) of slv(110 downto 0); + type Slv110Array is array (natural range <>) of slv(109 downto 0); + type Slv109Array is array (natural range <>) of slv(108 downto 0); + type Slv108Array is array (natural range <>) of slv(107 downto 0); + type Slv107Array is array (natural range <>) of slv(106 downto 0); + type Slv106Array is array (natural range <>) of slv(105 downto 0); + type Slv105Array is array (natural range <>) of slv(104 downto 0); + type Slv104Array is array (natural range <>) of slv(103 downto 0); + type Slv103Array is array (natural range <>) of slv(102 downto 0); + type Slv102Array is array (natural range <>) of slv(101 downto 0); + type Slv101Array is array (natural range <>) of slv(100 downto 0); + type Slv100Array is array (natural range <>) of slv(99 downto 0); + type Slv99Array is array (natural range <>) of slv(98 downto 0); + type Slv98Array is array (natural range <>) of slv(97 downto 0); + type Slv97Array is array (natural range <>) of slv(96 downto 0); + type Slv96Array is array (natural range <>) of slv(95 downto 0); + type Slv95Array is array (natural range <>) of slv(94 downto 0); + type Slv94Array is array (natural range <>) of slv(93 downto 0); + type Slv93Array is array (natural range <>) of slv(92 downto 0); + type Slv92Array is array (natural range <>) of slv(91 downto 0); + type Slv91Array is array (natural range <>) of slv(90 downto 0); + type Slv90Array is array (natural range <>) of slv(89 downto 0); + type Slv89Array is array (natural range <>) of slv(88 downto 0); + type Slv88Array is array (natural range <>) of slv(87 downto 0); + type Slv87Array is array (natural range <>) of slv(86 downto 0); + type Slv86Array is array (natural range <>) of slv(85 downto 0); + type Slv85Array is array (natural range <>) of slv(84 downto 0); + type Slv84Array is array (natural range <>) of slv(83 downto 0); + type Slv83Array is array (natural range <>) of slv(82 downto 0); + type Slv82Array is array (natural range <>) of slv(81 downto 0); + type Slv81Array is array (natural range <>) of slv(80 downto 0); + type Slv80Array is array (natural range <>) of slv(79 downto 0); + type Slv79Array is array (natural range <>) of slv(78 downto 0); + type Slv78Array is array (natural range <>) of slv(77 downto 0); + type Slv77Array is array (natural range <>) of slv(76 downto 0); + type Slv76Array is array (natural range <>) of slv(75 downto 0); + type Slv75Array is array (natural range <>) of slv(74 downto 0); + type Slv74Array is array (natural range <>) of slv(73 downto 0); + type Slv73Array is array (natural range <>) of slv(72 downto 0); + type Slv72Array is array (natural range <>) of slv(71 downto 0); + type Slv71Array is array (natural range <>) of slv(70 downto 0); + type Slv70Array is array (natural range <>) of slv(69 downto 0); + type Slv69Array is array (natural range <>) of slv(68 downto 0); + type Slv68Array is array (natural range <>) of slv(67 downto 0); + type Slv67Array is array (natural range <>) of slv(66 downto 0); + type Slv66Array is array (natural range <>) of slv(65 downto 0); + type Slv65Array is array (natural range <>) of slv(64 downto 0); + type Slv64Array is array (natural range <>) of slv(63 downto 0); + type Slv63Array is array (natural range <>) of slv(62 downto 0); + type Slv62Array is array (natural range <>) of slv(61 downto 0); + type Slv61Array is array (natural range <>) of slv(60 downto 0); + type Slv60Array is array (natural range <>) of slv(59 downto 0); + type Slv59Array is array (natural range <>) of slv(58 downto 0); + type Slv58Array is array (natural range <>) of slv(57 downto 0); + type Slv57Array is array (natural range <>) of slv(56 downto 0); + type Slv56Array is array (natural range <>) of slv(55 downto 0); + type Slv55Array is array (natural range <>) of slv(54 downto 0); + type Slv54Array is array (natural range <>) of slv(53 downto 0); + type Slv53Array is array (natural range <>) of slv(52 downto 0); + type Slv52Array is array (natural range <>) of slv(51 downto 0); + type Slv51Array is array (natural range <>) of slv(50 downto 0); + type Slv50Array is array (natural range <>) of slv(49 downto 0); + type Slv49Array is array (natural range <>) of slv(48 downto 0); + type Slv48Array is array (natural range <>) of slv(47 downto 0); + type Slv47Array is array (natural range <>) of slv(46 downto 0); + type Slv46Array is array (natural range <>) of slv(45 downto 0); + type Slv45Array is array (natural range <>) of slv(44 downto 0); + type Slv44Array is array (natural range <>) of slv(43 downto 0); + type Slv43Array is array (natural range <>) of slv(42 downto 0); + type Slv42Array is array (natural range <>) of slv(41 downto 0); + type Slv41Array is array (natural range <>) of slv(40 downto 0); + type Slv40Array is array (natural range <>) of slv(39 downto 0); + type Slv39Array is array (natural range <>) of slv(38 downto 0); + type Slv38Array is array (natural range <>) of slv(37 downto 0); + type Slv37Array is array (natural range <>) of slv(36 downto 0); + type Slv36Array is array (natural range <>) of slv(35 downto 0); + type Slv35Array is array (natural range <>) of slv(34 downto 0); + type Slv34Array is array (natural range <>) of slv(33 downto 0); + type Slv33Array is array (natural range <>) of slv(32 downto 0); + type Slv32Array is array (natural range <>) of slv(31 downto 0); + type Slv31Array is array (natural range <>) of slv(30 downto 0); + type Slv30Array is array (natural range <>) of slv(29 downto 0); + type Slv29Array is array (natural range <>) of slv(28 downto 0); + type Slv28Array is array (natural range <>) of slv(27 downto 0); + type Slv27Array is array (natural range <>) of slv(26 downto 0); + type Slv26Array is array (natural range <>) of slv(25 downto 0); + type Slv25Array is array (natural range <>) of slv(24 downto 0); + type Slv24Array is array (natural range <>) of slv(23 downto 0); + type Slv23Array is array (natural range <>) of slv(22 downto 0); + type Slv22Array is array (natural range <>) of slv(21 downto 0); + type Slv21Array is array (natural range <>) of slv(20 downto 0); + type Slv20Array is array (natural range <>) of slv(19 downto 0); + type Slv19Array is array (natural range <>) of slv(18 downto 0); + type Slv18Array is array (natural range <>) of slv(17 downto 0); + type Slv17Array is array (natural range <>) of slv(16 downto 0); + type Slv16Array is array (natural range <>) of slv(15 downto 0); + type Slv15Array is array (natural range <>) of slv(14 downto 0); + type Slv14Array is array (natural range <>) of slv(13 downto 0); + type Slv13Array is array (natural range <>) of slv(12 downto 0); + type Slv12Array is array (natural range <>) of slv(11 downto 0); + type Slv11Array is array (natural range <>) of slv(10 downto 0); + type Slv10Array is array (natural range <>) of slv(9 downto 0); + type Slv9Array is array (natural range <>) of slv(8 downto 0); + type Slv8Array is array (natural range <>) of slv(7 downto 0); + type Slv7Array is array (natural range <>) of slv(6 downto 0); + type Slv6Array is array (natural range <>) of slv(5 downto 0); + type Slv5Array is array (natural range <>) of slv(4 downto 0); + type Slv4Array is array (natural range <>) of slv(3 downto 0); + type Slv3Array is array (natural range <>) of slv(2 downto 0); + type Slv2Array is array (natural range <>) of slv(1 downto 0); + type Slv1Array is array (natural range <>) of slv(0 downto 0); + + -- Add more slv vector array sizes here as they become needed + type Slv256VectorArray is array (natural range<>, natural range<>) of slv(255 downto 0); + type Slv255VectorArray is array (natural range<>, natural range<>) of slv(254 downto 0); + type Slv254VectorArray is array (natural range<>, natural range<>) of slv(253 downto 0); + type Slv253VectorArray is array (natural range<>, natural range<>) of slv(252 downto 0); + type Slv252VectorArray is array (natural range<>, natural range<>) of slv(251 downto 0); + type Slv251VectorArray is array (natural range<>, natural range<>) of slv(250 downto 0); + type Slv250VectorArray is array (natural range<>, natural range<>) of slv(249 downto 0); + type Slv249VectorArray is array (natural range<>, natural range<>) of slv(248 downto 0); + type Slv248VectorArray is array (natural range<>, natural range<>) of slv(247 downto 0); + type Slv247VectorArray is array (natural range<>, natural range<>) of slv(246 downto 0); + type Slv246VectorArray is array (natural range<>, natural range<>) of slv(245 downto 0); + type Slv245VectorArray is array (natural range<>, natural range<>) of slv(244 downto 0); + type Slv244VectorArray is array (natural range<>, natural range<>) of slv(243 downto 0); + type Slv243VectorArray is array (natural range<>, natural range<>) of slv(242 downto 0); + type Slv242VectorArray is array (natural range<>, natural range<>) of slv(241 downto 0); + type Slv241VectorArray is array (natural range<>, natural range<>) of slv(240 downto 0); + type Slv240VectorArray is array (natural range<>, natural range<>) of slv(239 downto 0); + type Slv239VectorArray is array (natural range<>, natural range<>) of slv(238 downto 0); + type Slv238VectorArray is array (natural range<>, natural range<>) of slv(237 downto 0); + type Slv237VectorArray is array (natural range<>, natural range<>) of slv(236 downto 0); + type Slv236VectorArray is array (natural range<>, natural range<>) of slv(235 downto 0); + type Slv235VectorArray is array (natural range<>, natural range<>) of slv(234 downto 0); + type Slv234VectorArray is array (natural range<>, natural range<>) of slv(233 downto 0); + type Slv233VectorArray is array (natural range<>, natural range<>) of slv(232 downto 0); + type Slv232VectorArray is array (natural range<>, natural range<>) of slv(231 downto 0); + type Slv231VectorArray is array (natural range<>, natural range<>) of slv(230 downto 0); + type Slv230VectorArray is array (natural range<>, natural range<>) of slv(229 downto 0); + type Slv229VectorArray is array (natural range<>, natural range<>) of slv(228 downto 0); + type Slv228VectorArray is array (natural range<>, natural range<>) of slv(227 downto 0); + type Slv227VectorArray is array (natural range<>, natural range<>) of slv(226 downto 0); + type Slv226VectorArray is array (natural range<>, natural range<>) of slv(225 downto 0); + type Slv225VectorArray is array (natural range<>, natural range<>) of slv(224 downto 0); + type Slv224VectorArray is array (natural range<>, natural range<>) of slv(223 downto 0); + type Slv223VectorArray is array (natural range<>, natural range<>) of slv(222 downto 0); + type Slv222VectorArray is array (natural range<>, natural range<>) of slv(221 downto 0); + type Slv221VectorArray is array (natural range<>, natural range<>) of slv(220 downto 0); + type Slv220VectorArray is array (natural range<>, natural range<>) of slv(219 downto 0); + type Slv219VectorArray is array (natural range<>, natural range<>) of slv(218 downto 0); + type Slv218VectorArray is array (natural range<>, natural range<>) of slv(217 downto 0); + type Slv217VectorArray is array (natural range<>, natural range<>) of slv(216 downto 0); + type Slv216VectorArray is array (natural range<>, natural range<>) of slv(215 downto 0); + type Slv215VectorArray is array (natural range<>, natural range<>) of slv(214 downto 0); + type Slv214VectorArray is array (natural range<>, natural range<>) of slv(213 downto 0); + type Slv213VectorArray is array (natural range<>, natural range<>) of slv(212 downto 0); + type Slv212VectorArray is array (natural range<>, natural range<>) of slv(211 downto 0); + type Slv211VectorArray is array (natural range<>, natural range<>) of slv(210 downto 0); + type Slv210VectorArray is array (natural range<>, natural range<>) of slv(209 downto 0); + type Slv209VectorArray is array (natural range<>, natural range<>) of slv(208 downto 0); + type Slv208VectorArray is array (natural range<>, natural range<>) of slv(207 downto 0); + type Slv207VectorArray is array (natural range<>, natural range<>) of slv(206 downto 0); + type Slv206VectorArray is array (natural range<>, natural range<>) of slv(205 downto 0); + type Slv205VectorArray is array (natural range<>, natural range<>) of slv(204 downto 0); + type Slv204VectorArray is array (natural range<>, natural range<>) of slv(203 downto 0); + type Slv203VectorArray is array (natural range<>, natural range<>) of slv(202 downto 0); + type Slv202VectorArray is array (natural range<>, natural range<>) of slv(201 downto 0); + type Slv201VectorArray is array (natural range<>, natural range<>) of slv(200 downto 0); + type Slv200VectorArray is array (natural range<>, natural range<>) of slv(199 downto 0); + type Slv199VectorArray is array (natural range<>, natural range<>) of slv(198 downto 0); + type Slv198VectorArray is array (natural range<>, natural range<>) of slv(197 downto 0); + type Slv197VectorArray is array (natural range<>, natural range<>) of slv(196 downto 0); + type Slv196VectorArray is array (natural range<>, natural range<>) of slv(195 downto 0); + type Slv195VectorArray is array (natural range<>, natural range<>) of slv(194 downto 0); + type Slv194VectorArray is array (natural range<>, natural range<>) of slv(193 downto 0); + type Slv193VectorArray is array (natural range<>, natural range<>) of slv(192 downto 0); + type Slv192VectorArray is array (natural range<>, natural range<>) of slv(191 downto 0); + type Slv191VectorArray is array (natural range<>, natural range<>) of slv(190 downto 0); + type Slv190VectorArray is array (natural range<>, natural range<>) of slv(189 downto 0); + type Slv189VectorArray is array (natural range<>, natural range<>) of slv(188 downto 0); + type Slv188VectorArray is array (natural range<>, natural range<>) of slv(187 downto 0); + type Slv187VectorArray is array (natural range<>, natural range<>) of slv(186 downto 0); + type Slv186VectorArray is array (natural range<>, natural range<>) of slv(185 downto 0); + type Slv185VectorArray is array (natural range<>, natural range<>) of slv(184 downto 0); + type Slv184VectorArray is array (natural range<>, natural range<>) of slv(183 downto 0); + type Slv183VectorArray is array (natural range<>, natural range<>) of slv(182 downto 0); + type Slv182VectorArray is array (natural range<>, natural range<>) of slv(181 downto 0); + type Slv181VectorArray is array (natural range<>, natural range<>) of slv(180 downto 0); + type Slv180VectorArray is array (natural range<>, natural range<>) of slv(179 downto 0); + type Slv179VectorArray is array (natural range<>, natural range<>) of slv(178 downto 0); + type Slv178VectorArray is array (natural range<>, natural range<>) of slv(177 downto 0); + type Slv177VectorArray is array (natural range<>, natural range<>) of slv(176 downto 0); + type Slv176VectorArray is array (natural range<>, natural range<>) of slv(175 downto 0); + type Slv175VectorArray is array (natural range<>, natural range<>) of slv(174 downto 0); + type Slv174VectorArray is array (natural range<>, natural range<>) of slv(173 downto 0); + type Slv173VectorArray is array (natural range<>, natural range<>) of slv(172 downto 0); + type Slv172VectorArray is array (natural range<>, natural range<>) of slv(171 downto 0); + type Slv171VectorArray is array (natural range<>, natural range<>) of slv(170 downto 0); + type Slv170VectorArray is array (natural range<>, natural range<>) of slv(169 downto 0); + type Slv169VectorArray is array (natural range<>, natural range<>) of slv(168 downto 0); + type Slv168VectorArray is array (natural range<>, natural range<>) of slv(167 downto 0); + type Slv167VectorArray is array (natural range<>, natural range<>) of slv(166 downto 0); + type Slv166VectorArray is array (natural range<>, natural range<>) of slv(165 downto 0); + type Slv165VectorArray is array (natural range<>, natural range<>) of slv(164 downto 0); + type Slv164VectorArray is array (natural range<>, natural range<>) of slv(163 downto 0); + type Slv163VectorArray is array (natural range<>, natural range<>) of slv(162 downto 0); + type Slv162VectorArray is array (natural range<>, natural range<>) of slv(161 downto 0); + type Slv161VectorArray is array (natural range<>, natural range<>) of slv(160 downto 0); + type Slv160VectorArray is array (natural range<>, natural range<>) of slv(159 downto 0); + type Slv159VectorArray is array (natural range<>, natural range<>) of slv(158 downto 0); + type Slv158VectorArray is array (natural range<>, natural range<>) of slv(157 downto 0); + type Slv157VectorArray is array (natural range<>, natural range<>) of slv(156 downto 0); + type Slv156VectorArray is array (natural range<>, natural range<>) of slv(155 downto 0); + type Slv155VectorArray is array (natural range<>, natural range<>) of slv(154 downto 0); + type Slv154VectorArray is array (natural range<>, natural range<>) of slv(153 downto 0); + type Slv153VectorArray is array (natural range<>, natural range<>) of slv(152 downto 0); + type Slv152VectorArray is array (natural range<>, natural range<>) of slv(151 downto 0); + type Slv151VectorArray is array (natural range<>, natural range<>) of slv(150 downto 0); + type Slv150VectorArray is array (natural range<>, natural range<>) of slv(149 downto 0); + type Slv149VectorArray is array (natural range<>, natural range<>) of slv(148 downto 0); + type Slv148VectorArray is array (natural range<>, natural range<>) of slv(147 downto 0); + type Slv147VectorArray is array (natural range<>, natural range<>) of slv(146 downto 0); + type Slv146VectorArray is array (natural range<>, natural range<>) of slv(145 downto 0); + type Slv145VectorArray is array (natural range<>, natural range<>) of slv(144 downto 0); + type Slv144VectorArray is array (natural range<>, natural range<>) of slv(143 downto 0); + type Slv143VectorArray is array (natural range<>, natural range<>) of slv(142 downto 0); + type Slv142VectorArray is array (natural range<>, natural range<>) of slv(141 downto 0); + type Slv141VectorArray is array (natural range<>, natural range<>) of slv(140 downto 0); + type Slv140VectorArray is array (natural range<>, natural range<>) of slv(139 downto 0); + type Slv139VectorArray is array (natural range<>, natural range<>) of slv(138 downto 0); + type Slv138VectorArray is array (natural range<>, natural range<>) of slv(137 downto 0); + type Slv137VectorArray is array (natural range<>, natural range<>) of slv(136 downto 0); + type Slv136VectorArray is array (natural range<>, natural range<>) of slv(135 downto 0); + type Slv135VectorArray is array (natural range<>, natural range<>) of slv(134 downto 0); + type Slv134VectorArray is array (natural range<>, natural range<>) of slv(133 downto 0); + type Slv133VectorArray is array (natural range<>, natural range<>) of slv(132 downto 0); + type Slv132VectorArray is array (natural range<>, natural range<>) of slv(131 downto 0); + type Slv131VectorArray is array (natural range<>, natural range<>) of slv(130 downto 0); + type Slv130VectorArray is array (natural range<>, natural range<>) of slv(129 downto 0); + type Slv129VectorArray is array (natural range<>, natural range<>) of slv(128 downto 0); + type Slv128VectorArray is array (natural range<>, natural range<>) of slv(127 downto 0); + type Slv127VectorArray is array (natural range<>, natural range<>) of slv(126 downto 0); + type Slv126VectorArray is array (natural range<>, natural range<>) of slv(125 downto 0); + type Slv125VectorArray is array (natural range<>, natural range<>) of slv(124 downto 0); + type Slv124VectorArray is array (natural range<>, natural range<>) of slv(123 downto 0); + type Slv123VectorArray is array (natural range<>, natural range<>) of slv(122 downto 0); + type Slv122VectorArray is array (natural range<>, natural range<>) of slv(121 downto 0); + type Slv121VectorArray is array (natural range<>, natural range<>) of slv(120 downto 0); + type Slv120VectorArray is array (natural range<>, natural range<>) of slv(119 downto 0); + type Slv119VectorArray is array (natural range<>, natural range<>) of slv(118 downto 0); + type Slv118VectorArray is array (natural range<>, natural range<>) of slv(117 downto 0); + type Slv117VectorArray is array (natural range<>, natural range<>) of slv(116 downto 0); + type Slv116VectorArray is array (natural range<>, natural range<>) of slv(115 downto 0); + type Slv115VectorArray is array (natural range<>, natural range<>) of slv(114 downto 0); + type Slv114VectorArray is array (natural range<>, natural range<>) of slv(113 downto 0); + type Slv113VectorArray is array (natural range<>, natural range<>) of slv(112 downto 0); + type Slv112VectorArray is array (natural range<>, natural range<>) of slv(111 downto 0); + type Slv111VectorArray is array (natural range<>, natural range<>) of slv(110 downto 0); + type Slv110VectorArray is array (natural range<>, natural range<>) of slv(109 downto 0); + type Slv109VectorArray is array (natural range<>, natural range<>) of slv(108 downto 0); + type Slv108VectorArray is array (natural range<>, natural range<>) of slv(107 downto 0); + type Slv107VectorArray is array (natural range<>, natural range<>) of slv(106 downto 0); + type Slv106VectorArray is array (natural range<>, natural range<>) of slv(105 downto 0); + type Slv105VectorArray is array (natural range<>, natural range<>) of slv(104 downto 0); + type Slv104VectorArray is array (natural range<>, natural range<>) of slv(103 downto 0); + type Slv103VectorArray is array (natural range<>, natural range<>) of slv(102 downto 0); + type Slv102VectorArray is array (natural range<>, natural range<>) of slv(101 downto 0); + type Slv101VectorArray is array (natural range<>, natural range<>) of slv(100 downto 0); + type Slv100VectorArray is array (natural range<>, natural range<>) of slv(99 downto 0); + type Slv99VectorArray is array (natural range<>, natural range<>) of slv(98 downto 0); + type Slv98VectorArray is array (natural range<>, natural range<>) of slv(97 downto 0); + type Slv97VectorArray is array (natural range<>, natural range<>) of slv(96 downto 0); + type Slv96VectorArray is array (natural range<>, natural range<>) of slv(95 downto 0); + type Slv95VectorArray is array (natural range<>, natural range<>) of slv(94 downto 0); + type Slv94VectorArray is array (natural range<>, natural range<>) of slv(93 downto 0); + type Slv93VectorArray is array (natural range<>, natural range<>) of slv(92 downto 0); + type Slv92VectorArray is array (natural range<>, natural range<>) of slv(91 downto 0); + type Slv91VectorArray is array (natural range<>, natural range<>) of slv(90 downto 0); + type Slv90VectorArray is array (natural range<>, natural range<>) of slv(89 downto 0); + type Slv89VectorArray is array (natural range<>, natural range<>) of slv(88 downto 0); + type Slv88VectorArray is array (natural range<>, natural range<>) of slv(87 downto 0); + type Slv87VectorArray is array (natural range<>, natural range<>) of slv(86 downto 0); + type Slv86VectorArray is array (natural range<>, natural range<>) of slv(85 downto 0); + type Slv85VectorArray is array (natural range<>, natural range<>) of slv(84 downto 0); + type Slv84VectorArray is array (natural range<>, natural range<>) of slv(83 downto 0); + type Slv83VectorArray is array (natural range<>, natural range<>) of slv(82 downto 0); + type Slv82VectorArray is array (natural range<>, natural range<>) of slv(81 downto 0); + type Slv81VectorArray is array (natural range<>, natural range<>) of slv(80 downto 0); + type Slv80VectorArray is array (natural range<>, natural range<>) of slv(79 downto 0); + type Slv79VectorArray is array (natural range<>, natural range<>) of slv(78 downto 0); + type Slv78VectorArray is array (natural range<>, natural range<>) of slv(77 downto 0); + type Slv77VectorArray is array (natural range<>, natural range<>) of slv(76 downto 0); + type Slv76VectorArray is array (natural range<>, natural range<>) of slv(75 downto 0); + type Slv75VectorArray is array (natural range<>, natural range<>) of slv(74 downto 0); + type Slv74VectorArray is array (natural range<>, natural range<>) of slv(73 downto 0); + type Slv73VectorArray is array (natural range<>, natural range<>) of slv(72 downto 0); + type Slv72VectorArray is array (natural range<>, natural range<>) of slv(71 downto 0); + type Slv71VectorArray is array (natural range<>, natural range<>) of slv(70 downto 0); + type Slv70VectorArray is array (natural range<>, natural range<>) of slv(69 downto 0); + type Slv69VectorArray is array (natural range<>, natural range<>) of slv(68 downto 0); + type Slv68VectorArray is array (natural range<>, natural range<>) of slv(67 downto 0); + type Slv67VectorArray is array (natural range<>, natural range<>) of slv(66 downto 0); + type Slv66VectorArray is array (natural range<>, natural range<>) of slv(65 downto 0); + type Slv65VectorArray is array (natural range<>, natural range<>) of slv(64 downto 0); + type Slv64VectorArray is array (natural range<>, natural range<>) of slv(63 downto 0); + type Slv63VectorArray is array (natural range<>, natural range<>) of slv(62 downto 0); + type Slv62VectorArray is array (natural range<>, natural range<>) of slv(61 downto 0); + type Slv61VectorArray is array (natural range<>, natural range<>) of slv(60 downto 0); + type Slv60VectorArray is array (natural range<>, natural range<>) of slv(59 downto 0); + type Slv59VectorArray is array (natural range<>, natural range<>) of slv(58 downto 0); + type Slv58VectorArray is array (natural range<>, natural range<>) of slv(57 downto 0); + type Slv57VectorArray is array (natural range<>, natural range<>) of slv(56 downto 0); + type Slv56VectorArray is array (natural range<>, natural range<>) of slv(55 downto 0); + type Slv55VectorArray is array (natural range<>, natural range<>) of slv(54 downto 0); + type Slv54VectorArray is array (natural range<>, natural range<>) of slv(53 downto 0); + type Slv53VectorArray is array (natural range<>, natural range<>) of slv(52 downto 0); + type Slv52VectorArray is array (natural range<>, natural range<>) of slv(51 downto 0); + type Slv51VectorArray is array (natural range<>, natural range<>) of slv(50 downto 0); + type Slv50VectorArray is array (natural range<>, natural range<>) of slv(49 downto 0); + type Slv49VectorArray is array (natural range<>, natural range<>) of slv(48 downto 0); + type Slv48VectorArray is array (natural range<>, natural range<>) of slv(47 downto 0); + type Slv47VectorArray is array (natural range<>, natural range<>) of slv(46 downto 0); + type Slv46VectorArray is array (natural range<>, natural range<>) of slv(45 downto 0); + type Slv45VectorArray is array (natural range<>, natural range<>) of slv(44 downto 0); + type Slv44VectorArray is array (natural range<>, natural range<>) of slv(43 downto 0); + type Slv43VectorArray is array (natural range<>, natural range<>) of slv(42 downto 0); + type Slv42VectorArray is array (natural range<>, natural range<>) of slv(41 downto 0); + type Slv41VectorArray is array (natural range<>, natural range<>) of slv(40 downto 0); + type Slv40VectorArray is array (natural range<>, natural range<>) of slv(39 downto 0); + type Slv39VectorArray is array (natural range<>, natural range<>) of slv(38 downto 0); + type Slv38VectorArray is array (natural range<>, natural range<>) of slv(37 downto 0); + type Slv37VectorArray is array (natural range<>, natural range<>) of slv(36 downto 0); + type Slv36VectorArray is array (natural range<>, natural range<>) of slv(35 downto 0); + type Slv35VectorArray is array (natural range<>, natural range<>) of slv(34 downto 0); + type Slv34VectorArray is array (natural range<>, natural range<>) of slv(33 downto 0); + type Slv33VectorArray is array (natural range<>, natural range<>) of slv(32 downto 0); + type Slv32VectorArray is array (natural range<>, natural range<>) of slv(31 downto 0); + type Slv31VectorArray is array (natural range<>, natural range<>) of slv(30 downto 0); + type Slv30VectorArray is array (natural range<>, natural range<>) of slv(29 downto 0); + type Slv29VectorArray is array (natural range<>, natural range<>) of slv(28 downto 0); + type Slv28VectorArray is array (natural range<>, natural range<>) of slv(27 downto 0); + type Slv27VectorArray is array (natural range<>, natural range<>) of slv(26 downto 0); + type Slv26VectorArray is array (natural range<>, natural range<>) of slv(25 downto 0); + type Slv25VectorArray is array (natural range<>, natural range<>) of slv(24 downto 0); + type Slv24VectorArray is array (natural range<>, natural range<>) of slv(23 downto 0); + type Slv23VectorArray is array (natural range<>, natural range<>) of slv(22 downto 0); + type Slv22VectorArray is array (natural range<>, natural range<>) of slv(21 downto 0); + type Slv21VectorArray is array (natural range<>, natural range<>) of slv(20 downto 0); + type Slv20VectorArray is array (natural range<>, natural range<>) of slv(19 downto 0); + type Slv19VectorArray is array (natural range<>, natural range<>) of slv(18 downto 0); + type Slv18VectorArray is array (natural range<>, natural range<>) of slv(17 downto 0); + type Slv17VectorArray is array (natural range<>, natural range<>) of slv(16 downto 0); + type Slv16VectorArray is array (natural range<>, natural range<>) of slv(15 downto 0); + type Slv15VectorArray is array (natural range<>, natural range<>) of slv(14 downto 0); + type Slv14VectorArray is array (natural range<>, natural range<>) of slv(13 downto 0); + type Slv13VectorArray is array (natural range<>, natural range<>) of slv(12 downto 0); + type Slv12VectorArray is array (natural range<>, natural range<>) of slv(11 downto 0); + type Slv11VectorArray is array (natural range<>, natural range<>) of slv(10 downto 0); + type Slv10VectorArray is array (natural range<>, natural range<>) of slv(9 downto 0); + type Slv9VectorArray is array (natural range<>, natural range<>) of slv(8 downto 0); + type Slv8VectorArray is array (natural range<>, natural range<>) of slv(7 downto 0); + type Slv7VectorArray is array (natural range<>, natural range<>) of slv(6 downto 0); + type Slv6VectorArray is array (natural range<>, natural range<>) of slv(5 downto 0); + type Slv5VectorArray is array (natural range<>, natural range<>) of slv(4 downto 0); + type Slv4VectorArray is array (natural range<>, natural range<>) of slv(3 downto 0); + type Slv3VectorArray is array (natural range<>, natural range<>) of slv(2 downto 0); + type Slv2VectorArray is array (natural range<>, natural range<>) of slv(1 downto 0); + type Slv1VectorArray is array (natural range<>, natural range<>) of slv(0 downto 0); + type SlVectorArray is array (natural range<>, natural range<>) of sl; + + -- Mux a SlVectorArray into an SLV + function muxSlVectorArray (vec : SlVectorArray; addr : natural; allowOutOfRange : boolean := false) return slv; + +end StdRtlPkg; + +package body StdRtlPkg is + + function slvAll (size : positive; value : sl) return slv is + variable retVar : slv(size-1 downto 0) := (others => value); + begin + return retVar; + end function slvAll; + + function slvZero (size : positive) return slv is + begin + return slvAll(size, '0'); + end function; + + function slvOne (size : positive) return slv is + begin + return slvAll(size, '1'); + end function; + + function isPowerOf2 (number : natural) return boolean is + begin + return isPowerOf2(toSlv(number, 32)); + end function isPowerOf2; + + function isPowerOf2 (vector : slv) return boolean is + begin + return (unsigned(vector) /= 0) and + (unsigned(unsigned(vector) and (unsigned(vector)-1)) = 0); + end function isPowerOf2; + + --------------------------------------------------------------------------------------------------------------------- + -- Function: log2 + -- Purpose: Finds the log base 2 of an integer + -- Input is rounded up to nearest power of two. + -- Therefore log2(5) = log2(8) = 3. + -- Arg: number - integer to find log2 of + -- Returns: Integer containing log base two of input. + --------------------------------------------------------------------------------------------------------------------- + function log2(constant number : positive) return natural is + begin + return integer(ceil(ieee.math_real.log2(real(number)))); + end function; + + -- Find number of bits needed to store a number + function bitSize (constant number : natural ) return positive is + begin + if (number = 0 or number = 1) then + return 1; + else + if (isPowerOf2(number)) then + return log2(number) + 1; + else + return log2(number); + end if; + end if; + end function; + + -- NOTE: XST will crap its pants if you try to pass a constant to this function + function bitReverse (a : slv) return slv is + variable resultVar : slv(a'range); + alias aa : slv(a'reverse_range) is a; + begin + for i in aa'range loop + resultVar(i) := aa(i); + end loop; + return resultVar; + end; + + function list (constant start, size, step : integer) return IntegerArray is + variable retVar : IntegerArray(0 to size-1); + begin + for i in retVar'range loop + retVar(i) := start + (i * step); + end loop; + return retVar; + end function list; + + function toBoolean (logic : sl) return boolean is + begin -- function toBoolean + return logic = '1'; + end function toBoolean; + + function toSl (bool : boolean) return sl is + begin + if (bool) then + return '1'; + else + return '0'; + end if; + end function toSl; + + function toString (bool : boolean) return string is + begin + if (bool) then + return "TRUE"; + else + return "FALSE"; + end if; + end function toString; + + function toBoolean (str : string) return boolean is + begin + if (str = "TRUE" or str = "true") then + return true; + else + return false; + end if; + end function toBoolean; + + -------------------------------------------------------------------------------------------------- + -- Decode and genmux + -------------------------------------------------------------------------------------------------- + -- generic decoder + function decode(v : slv) return slv is + variable res : slv((2**v'length)-1 downto 0); + variable i : integer range res'range; + begin + res := (others => '0'); + i := 0; + i := to_integer(unsigned(v)); + res(i) := '1'; + return res; + end; + + -- generic multiplexer + function genmux(s, v : slv) return sl is + variable res : slv(v'length-1 downto 0); + variable i : integer range res'range; + begin + res := v; + i := 0; + i := to_integer(unsigned(s)); + return res(i); + end; + + --------------------------------------------------------------------------------------------------------------------- + -- Unary reduction operators + --------------------------------------------------------------------------------------------------------------------- + function uOr (vec : slv) return sl is + variable retvar: sl:='0'; + begin + retvar:='0'; + for i in vec'range loop + if (vec(i) = '1') then + retvar:= '1'; + end if; + end loop; + return retvar; + end function uOr; + + function uAnd (vec : slv) return sl is + variable retvar: sl:='1'; + begin + retvar:='1'; + for i in vec'range loop + if (vec(i) = '0') then + retvar:='0'; + end if; + end loop; + return retvar; + end function uAnd; + + function uXor (vec : slv) return sl is + variable intVar : sl; + begin + for i in vec'range loop + if (i = vec'left) then + intVar := vec(i); + else + intVar := intVar xor vec(i); + end if; + end loop; + return intVar; + end function uXor; + + function allBits (vec : slv; test : sl) return boolean is + begin + for i in vec'range loop + if (vec(i) /= test) then + return false; + end if; + end loop; + return true; + end function; + + function noBits (vec : slv; test : sl) return boolean is + begin + for i in vec'range loop + if (vec(i) = test) then + return false; + end if; + end loop; + return true; + end function; + + ----------------------------------------------------------------------------- + -- Functions to determine parity of arbitrary sized slv + ----------------------------------------------------------------------------- + -- returns '1' if vec has even parity + function evenParity (vec : slv) + return sl is + begin + return not uXor(vec); + end function; + + -- return '1' if vec has odd parity + function oddParity (vec : slv) + return sl is + begin + return uXor(vec); + end function; + + ----------------------------------------------------------------------------- + -- Functions for counting the number of '1' in a slv bus + ----------------------------------------------------------------------------- + -- New Non-recursive onesCount Function + function onesCount (vec : slv) + return unsigned is + variable retVar : unsigned((bitSize(vec'length)-1) downto 0) := to_unsigned(0,bitSize(vec'length)); + begin + for i in vec'range loop + if vec(i) = '1' then + retVar := retVar + 1; + end if; + end loop; + return retVar; + end function; + + -- -- Old Recursive onesCount Function + -- function onesCount (vec : slv) return unsigned is + -- variable topVar : slv(vec'high downto vec'low+(vec'length/2)); + -- variable bottomVar : slv(topVar'low-1 downto vec'low); + -- variable tmpVar : slv(2 downto 0); + -- begin + -- if (vec'length = 1) then + -- return '0' & unsigned(vec); + -- end if; + + -- if (vec'length = 2) then + -- return uAnd(vec) & uXor(vec); + -- end if; + + -- if (vec'length = 3) then + -- tmpVar := vec; + -- case tmpVar is + -- when "000" => return "00"; + -- when "001" => return "01"; + -- when "010" => return "01"; + -- when "011" => return "10"; + -- when "100" => return "01"; + -- when "101" => return "10"; + -- when "110" => return "10"; + -- when "111" => return "11"; + -- when others => return "00"; + -- end case; + -- end if; + + -- topVar := vec(vec'high downto (vec'high+1)-((vec'length+1)/2)); + -- bottomVar := vec(vec'high-((vec'length+1)/2) downto vec'low); + + -- return ('0' & onesCount(topVar)) + ('0' & onesCount(bottomVar)); + -- end function; + + -- SLV variant + function onesCount (vec : slv) + return slv is + variable retVar : slv((bitSize(vec'length)-1) downto 0); + variable cntVar : unsigned((bitSize(vec'length)-1) downto 0); + begin + cntVar := onesCount(vec); + retVar := slv(cntVar); + return retVar; + end function; + + ----------------------------------------------------------------------------- + -- Functions for encoding and decoding grey codes + ----------------------------------------------------------------------------- + -- Get next gray code given binary vector + function grayEncode (vec : unsigned) + return unsigned is + begin + return vec xor shift_right(vec, 1); + end function; + + -- SLV variant + function grayEncode (vec : slv) + return slv is + begin + return slv(grayEncode(unsigned(vec))); + end function; + + -- Get the binary equivalent of a Gray code created with gray_encode. + function grayDecode (vec : unsigned) + return unsigned is + variable retVar : unsigned(vec'range) := (others => '0'); + begin + for i in vec'range loop + if (i = vec'left) then + retVar(i) := vec(i); + else + if (vec'ascending) then + retVar(i) := retVar(i-1) xor vec(i); + else + retVar(i) := retVar(i+1) xor vec(i); + end if; + end if; + end loop; + return retVar; + end function; + + -- SLV variant + function grayDecode (vec : slv) + return slv is + variable retVar : slv(vec'range) := (others => '0'); + begin + return slv(grayDecode(unsigned(vec))); + end function; + + ------------------------------------------------------------------------------------------------- + -- Implements an N tap linear feedback shift operation + -- Size of LFSR is variable and determined by length of lfsr parameter + -- Number of taps is variable and determined by length of taps array parameter + -- An input parameter is also available for use in scramblers + -- Output is new lfsr value after one shift operation + -- The lfsr param can be indexed ascending or decending + -- The shift is in the direction of increasing index (left shift for decending, right for ascending) + ------------------------------------------------------------------------------------------------- + function lfsrShift (lfsr : slv; constant taps : NaturalArray; input : sl := '0') return slv is + variable retVar : slv(lfsr'range) := (others => '0'); + begin + if (lfsr'ascending) then + retVar := input & lfsr(lfsr'left to lfsr'right-1); + else + retVar := lfsr(lfsr'left-1 downto lfsr'right) & input; + end if; + + for i in taps'range loop + assert (taps(i) <= lfsr'high) report "lfsrShift() - Tap value exceedes lfsr range" severity failure; + retVar(lfsr'low) := retVar(lfsr'low) xor lfsr(taps(i)); + end loop; + + return retVar; + end function; + + ------------------------------------------------------------------------------------------------- + -- One line if-then-else functions. + ------------------------------------------------------------------------------------------------- + + function ite (i : boolean; t : boolean; e : boolean) return boolean is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : sl; e : sl) return sl is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : slv; e : slv) return slv is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : bit_vector; e : bit_vector) return bit_vector is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : character; e : character) return character is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : string; e : string) return string is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : integer; e : integer) return integer is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : real; e : real) return real is + begin + if (i) then return t; else return e; end if; + end function ite; + + function ite (i : boolean; t : time; e : time) return time is + begin + if (i) then return t; else return e; end if; + end function ite; + + ----------------------------- + -- Min and Max + ----------------------------- + function maximum (left, right : integer) return integer is + begin + if left > right then return left; + else return right; + end if; + end maximum; + + function minimum (left, right : integer) return integer is + begin + if left < right then return left; + else return right; + end if; + end minimum; + + ----------------------------- + -- conv_std_logic_vector functions + -- without calling the STD_LOGIC_ARITH library + ----------------------------- + + -- convert an integer to an STD_LOGIC_VECTOR + function toSlv(ARG : integer; SIZE : integer) return slv is + begin + return slv(to_unsigned(ARG, SIZE)); + end; + + ----------------------------- + -- gets real multiplication + ----------------------------- + function getRealMult (A, B : real) return real is + begin + return real(A*B); + end function; + + function getRealMult (A : integer; B : real) return real is + begin + return real(real(A)*B); + end function; + + function getRealMult (A : real; B : integer) return real is + begin + return real(A*real(B)); + end function; + + ----------------------------- + -- gets real division + ----------------------------- + function getRealDiv (A, B : real) return real is + begin + return real(A/B); + end function; + + function getRealDiv (A : integer; B : real) return real is + begin + return real(real(A)/B); + end function; + + function getRealDiv (A : real; B : integer) return real is + begin + return real(A/real(B)); + end function; + + ------------------------------------------------------------------------------------------------- + -- Simulates an ADC conversion + ------------------------------------------------------------------------------------------------- + function adcConversion ( + ain : real; + low : real; + high : real; + bits : positive; + twosComp : boolean) + return slv is + variable tmpR : real; + variable tmpI : integer; + + variable retSigned : signed(bits-1 downto 0); + variable retUnsigned : unsigned(bits-1 downto 0); + begin + tmpR := ain; + + -- Constrain input to full scale range + tmpR := realmin(high, tmpR); + tmpR := realmax(low, tmpR); + + -- Scale to [0,1] or [-.5,.5] + tmpR := (tmpR-low)/(high-low) + ite(twosComp, -0.5, 0.0); + + -- Scale to number of bits + tmpR := tmpR * real(2**bits); + + if (twosComp) then + retSigned := to_signed(integer(round(tmpR)), bits); + return slv(retSigned); + else + retUnsigned := to_unsigned(integer(round(tmpR)), bits); + return slv(retUnsigned); + end if; + end function adcConversion; + + ----------------------------- + -- gets a time ratio + ----------------------------- + function getTimeRatio (T1, T2 : time) return natural is + begin + return natural(T1/T2); + end function; + + function getTimeRatio (T1, T2 : real) return natural is + begin + return natural(ROUND(abs(T1/T2))); + end function; + + --------------------------------------------------------------------------------------------------------------------- + -- Convert a frequency to a period (time). + --------------------------------------------------------------------------------------------------------------------- + -- pragma translate_off + function toTime(f : frequency) return time is + begin + return(1.0 sec / (f/Hz)); + end function; + --pragma translate_on + + ----------------------------- + -- Mux a SlVectorArray into an SLV + ----------------------------- + function muxSlVectorArray (vec : SlVectorArray; + addr : natural; + allowOutOfRange : boolean := false) + return slv is + variable retVar : slv(vec'range(2)); + begin + -- Check the limit of the address + if (addr < vec'length(1)) or (allowOutOfRange = false) then + for i in vec'range(2) loop + retVar(i) := vec(addr, i); + end loop; + else + retVar := (others => '0'); + end if; + return retVar; + end function; + + procedure assignSlv ( + i : inout integer; + vector : inout slv; + value : in slv) + is + variable low : integer; + begin + low := i; + i := i+value'length; + vector(i-1 downto low) := value; + end procedure assignSlv; + + procedure assignSlv ( + i : inout integer; + vector : inout slv; + value : in sl) + is + variable low : integer; + begin + vector(i) := value; + i := i+1; + end procedure assignSlv; + + procedure assignRecord ( + i : inout integer; + vector : in slv; + value : inout slv) + is + variable low : integer; + begin + low := i; + i := i+value'length; + value := vector(i-1 downto low); + end procedure assignRecord; + + procedure assignRecord ( + i : inout integer; + vector : in slv; + value : inout sl) + is + variable low : integer; + begin + value := vector(i); + i := i+1; + end procedure assignRecord; + + -- Resize an SLV, either by trimming or padding upper bits + function resizeSlv ( vector : slv; newSize : integer) return slv is + variable retVar : slv(newSize-1 downto 0); + variable top : integer; + begin + retVar := (others=>'0'); + + top := minimum( newSize, vector'length) - 1; + + retVar(top downto 0) := vector(top downto 0); + + return retVar; + end function; + +end package body StdRtlPkg; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/adcreadout.vhd b/rce/fw-hsio/modules/pixelcore/hdl/adcreadout.vhd new file mode 100644 index 0000000000000000000000000000000000000000..484cf98d8c00864a0bba93fee0e7146c540ad2e7 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/adcreadout.vhd @@ -0,0 +1,77 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.StdRtlPkg.all; +use work.all; + +-------------------------------------------------------------- + +entity adcreadout is +generic( CHANNEL: std_logic_vector(7 downto 0):=x"ff"); +port( clk: in std_logic; + rst: in std_logic; + d_in: in Slv16Array(11 downto 0); + enabled: in std_logic; + go: in std_logic; + d_out: out std_logic_vector(15 downto 0); + ld: out std_logic; + sof: out std_logic; + eof: out std_logic +); +end adcreadout; + +-------------------------------------------------------------- + +architecture ADCREADOUT of adcreadout is + +begin + + + process(rst, clk) + + variable headercounter: natural range 0 to 29 := 0; + begin + if(rst='1') then + d_out<=x"0000"; + eof<='0'; + sof<='0'; + headercounter:=0; + ld<='0'; + elsif (clk'event and clk='1') then + if(headercounter=0 and enabled='1' and go='1')then + headercounter:=29; + end if; + if (headercounter/=0)then + if(headercounter=29)then + ld<='1'; + sof<='1'; + d_out<=(others=>'0'); + elsif(headercounter=28)then + sof<='0'; + d_out(7 downto 0)<=(others=>'0'); + d_out(15 downto 8)<=CHANNEL; + elsif(headercounter<14 and headercounter>1)then + d_out<=d_in(13-headercounter); + else + d_out<=(others=>'0'); + end if; + if(headercounter=2)then + eof<='1'; + elsif(headercounter=1)then + eof<='0'; + ld<='0'; + end if; + headercounter:=headercounter-1; + end if; + end if; + + end process; + +end ADCREADOUT; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/arraytype.vhd b/rce/fw-hsio/modules/pixelcore/hdl/arraytype.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6bc145fb173aa3e0ea318c6caf660294bab8e5fb --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/arraytype.vhd @@ -0,0 +1,12 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +package arraytype is + type dataarray is array(31 downto 0) of std_logic_vector(17 downto 0); + type fei4array is array(31 downto 0) of std_logic_vector(24 downto 0); + type array10b is array(31 downto 0) of std_logic_vector(9 downto 0); + type hb is array(1 downto 0) of std_logic_vector(4 downto 0); + type hbpipeline is array(40 downto 0) of std_logic_vector(2 downto 0); + type hitbusoutput is array(1 downto 0) of std_logic_vector(31 downto 0); +end package arraytype; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/clock160.vhd b/rce/fw-hsio/modules/pixelcore/hdl/clock160.vhd new file mode 100644 index 0000000000000000000000000000000000000000..17be9c4284b95d2541fce5d4b08960f277230235 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/clock160.vhd @@ -0,0 +1,113 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. +-------------------------------------------------------------------------------- +-- ____ ____ +-- / /\/ / +-- /___/ \ / Vendor: Xilinx +-- \ \ \/ Version : 10.1.03 +-- \ \ Application : xaw2vhdl +-- / / Filename : clock40.vhd +-- /___/ /\ Timestamp : 09/08/2009 09:18:06 +-- \ \ / \ +-- \___\/\___\ +-- +--Command: xaw2vhdl-st /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores/clock40.xaw /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores/clock40 +--Design Name: clock40 +--Device: xc4vfx60-10ff1152 +-- +-- Module clock40 +-- Generated by Xilinx Architecture Wizard +-- Written for synthesis tool: Synplify +-- Period Jitter (unit interval) for block DCM_ADV_INST = 0.012 UI +-- Period Jitter (Peak-to-Peak) for block DCM_ADV_INST = 0.297 ns + +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; +library UNISIM; +use UNISIM.Vcomponents.ALL; + +entity clock160 is + port ( CLKIN_N_IN : in std_logic; + CLKIN_P_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLKIN_IBUFGDS_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); +end clock160; + +architecture BEHAVIORAL of clock160 is + signal CLKFB_IN : std_logic; + signal CLKFX_BUF : std_logic; + signal CLKIN_IBUFGDS : std_logic; + signal CLK0_BUF : std_logic; + signal GND_BIT : std_logic; + signal GND_BUS_7 : std_logic_vector (6 downto 0); + signal GND_BUS_16 : std_logic_vector (15 downto 0); +begin + GND_BIT <= '0'; + GND_BUS_7(6 downto 0) <= "0000000"; + GND_BUS_16(15 downto 0) <= "0000000000000000"; + CLKIN_IBUFGDS_OUT <= CLKIN_IBUFGDS; + CLK0_OUT <= CLKFB_IN; + CLKFX_BUFG_INST : BUFG + port map (I=>CLKFX_BUF, + O=>CLKFX_OUT); + + CLKIN_IBUFGDS_INST : IBUFGDS + generic map(DIFF_TERM=>TRUE, + IOSTANDARD=>"LVDS_25") + port map (I=>CLKIN_P_IN, + IB=>CLKIN_N_IN, + O=>CLKIN_IBUFGDS); + + CLK0_BUFG_INST : BUFG + port map (I=>CLK0_BUF, + O=>CLKFB_IN); + + DCM_ADV_INST : DCM_ADV + generic map( CLK_FEEDBACK => "1X", + CLKDV_DIVIDE => 2.0, + CLKFX_DIVIDE => 25, + CLKFX_MULTIPLY => 32, + CLKIN_DIVIDE_BY_2 => FALSE, + CLKIN_PERIOD => 8.000, + CLKOUT_PHASE_SHIFT => "NONE", + DCM_AUTOCALIBRATION => TRUE, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "LOW", + DUTY_CYCLE_CORRECTION => TRUE, + FACTORY_JF => x"F0F0", + PHASE_SHIFT => 0, + STARTUP_WAIT => FALSE) + port map (CLKFB=>CLKFB_IN, + CLKIN=>CLKIN_IBUFGDS, + DADDR(6 downto 0)=>GND_BUS_7(6 downto 0), + DCLK=>GND_BIT, + DEN=>GND_BIT, + DI(15 downto 0)=>GND_BUS_16(15 downto 0), + DWE=>GND_BIT, + PSCLK=>GND_BIT, + PSEN=>GND_BIT, + PSINCDEC=>GND_BIT, + RST=>RST_IN, + CLKDV=>open, + CLKFX=>CLKFX_BUF, + CLKFX180=>open, + CLK0=>CLK0_BUF, + CLK2X=>open, + CLK2X180=>open, + CLK90=>open, + CLK180=>open, + CLK270=>open, + DO=>open, + DRDY=>open, + LOCKED=>LOCKED_OUT, + PSDONE=>open); + +end BEHAVIORAL; + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/clock200.vhd b/rce/fw-hsio/modules/pixelcore/hdl/clock200.vhd new file mode 100644 index 0000000000000000000000000000000000000000..daa834da7fa31edbcdd936971ca110d3d3ac0f23 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/clock200.vhd @@ -0,0 +1,102 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. +-------------------------------------------------------------------------------- +-- ____ ____ +-- / /\/ / +-- /___/ \ / Vendor: Xilinx +-- \ \ \/ Version : 10.1.03 +-- \ \ Application : xaw2vhdl +-- / / Filename : clock200.vhd +-- /___/ /\ Timestamp : 09/17/2009 10:43:18 +-- \ \ / \ +-- \___\/\___\ +-- +--Command: xaw2vhdl-st /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores/clock200.xaw /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores/clock200 +--Design Name: clock200 +--Device: xc4vfx60-10ff1152 +-- +-- Module clock200 +-- Generated by Xilinx Architecture Wizard +-- Written for synthesis tool: Synplify +-- Period Jitter (unit interval) for block DCM_ADV_INST = 0.042 UI +-- Period Jitter (Peak-to-Peak) for block DCM_ADV_INST = 0.208 ns + +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; +library UNISIM; +use UNISIM.Vcomponents.ALL; + +entity clock200 is + port ( CLKIN_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); +end clock200; + +architecture BEHAVIORAL of clock200 is + signal CLKFB_IN : std_logic; + signal CLKFX_BUF : std_logic; + signal CLK0_BUF : std_logic; + signal GND_BIT : std_logic; + signal GND_BUS_7 : std_logic_vector (6 downto 0); + signal GND_BUS_16 : std_logic_vector (15 downto 0); +begin + GND_BIT <= '0'; + GND_BUS_7(6 downto 0) <= "0000000"; + GND_BUS_16(15 downto 0) <= "0000000000000000"; + CLK0_OUT <= CLKFB_IN; + CLKFX_BUFG_INST : BUFG + port map (I=>CLKFX_BUF, + O=>CLKFX_OUT); + + CLK0_BUFG_INST : BUFG + port map (I=>CLK0_BUF, + O=>CLKFB_IN); + + DCM_ADV_INST : DCM_ADV + generic map( CLK_FEEDBACK => "1X", + CLKDV_DIVIDE => 2.0, + CLKFX_DIVIDE => 4, + CLKFX_MULTIPLY => 5, + CLKIN_DIVIDE_BY_2 => FALSE, + CLKIN_PERIOD => 6.250, + CLKOUT_PHASE_SHIFT => "NONE", + DCM_AUTOCALIBRATION => TRUE, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "HIGH", + DUTY_CYCLE_CORRECTION => TRUE, + FACTORY_JF => x"F0F0", + PHASE_SHIFT => 0, + STARTUP_WAIT => FALSE) + port map (CLKFB=>CLKFB_IN, + CLKIN=>CLKIN_IN, + DADDR(6 downto 0)=>GND_BUS_7(6 downto 0), + DCLK=>GND_BIT, + DEN=>GND_BIT, + DI(15 downto 0)=>GND_BUS_16(15 downto 0), + DWE=>GND_BIT, + PSCLK=>GND_BIT, + PSEN=>GND_BIT, + PSINCDEC=>GND_BIT, + RST=>RST_IN, + CLKDV=>open, + CLKFX=>CLKFX_BUF, + CLKFX180=>open, + CLK0=>CLK0_BUF, + CLK2X=>open, + CLK2X180=>open, + CLK90=>open, + CLK180=>open, + CLK270=>open, + DO=>open, + DRDY=>open, + LOCKED=>LOCKED_OUT, + PSDONE=>open); + +end BEHAVIORAL; + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/coincidence.vhd b/rce/fw-hsio/modules/pixelcore/hdl/coincidence.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fe474592eaf73ec8f2d14f0835483b8dad911dac --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/coincidence.vhd @@ -0,0 +1,117 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.arraytype.all; + +-------------------------------------------------------------- + + +entity coincidence is + +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + fifothresh: in std_logic; + trgin: in std_logic; + serbusy: in std_logic; + tdcreadoutbusy: in std_logic; + extbusy: in std_logic; + firstphase: in std_logic; + tdcready: in std_logic; + starttdc: out std_logic; + l1a: out std_logic; + trgdelay: in std_logic_vector(7 downto 0); + busy: out std_logic; + coinc: out std_logic; + coincd: out std_logic +); +end coincidence; + +-------------------------------------------------------------- + +architecture COINCIDENCE of coincidence is + +signal andr: std_logic_vector(15 downto 0); +signal delaycounter: std_logic_vector(7 downto 0); +signal busys: std_logic; +signal coinct: std_logic; +signal rescoin: std_logic; +signal oldcoinct: std_logic; +signal oldoldcoinct: std_logic; +signal oldbusys: std_logic; +signal oldoldbusys: std_logic; +signal oldtdcreadoutbusy: std_logic; +signal oldenabled: std_logic; +signal l1asig: std_logic; +signal go: std_logic; + +begin + l1a<=l1asig; + busys<=fifothresh or serbusy or tdcreadoutbusy or extbusy or firstphase; + go <= tdcready and enabled and not busys; + busy<= enabled and (busys or not tdcready); + coinc<=coinct; + coincd<=trgin; + + process (rst,rescoin, go,trgin) + begin + if( rst='1' or rescoin='1')then + coinct<='0'; + elsif(rising_edge(trgin))then + if(go='1')then + coinct<='1'; + end if; + end if; + end process; + + process (rst,clk) + begin + if(rst='1')then + starttdc<= '0'; + oldcoinct<='0'; + oldoldcoinct<='0'; + oldbusys<='0'; + oldoldbusys<='0'; + oldenabled<='0'; + l1asig<='0'; + delaycounter<=x"00"; + oldtdcreadoutbusy<='0'; + elsif(rising_edge(clk))then + if(delaycounter/=x"00")then + delaycounter<=unsigned(delaycounter)-1; + elsif(coinct='1' and oldoldcoinct='0')then -- keep one bin as a buffer + delaycounter<=trgdelay; + end if; + if(delaycounter=x"01")then + l1asig<='1'; + else + l1asig<='0'; + end if; + if(l1asig='1')then + rescoin<='1'; + elsif(go='0')then + rescoin<='0'; + end if; + if(tdcready='0' and tdcreadoutbusy='0' and oldtdcreadoutbusy='1')then + starttdc<='1'; + elsif(enabled='1' and oldenabled='0') then + starttdc<='1'; + else + starttdc<='0'; + end if; + oldcoinct<=coinct; + oldoldcoinct<=oldcoinct; + oldbusys<=busys; + oldoldbusys<=oldbusys; + oldtdcreadoutbusy<=tdcreadoutbusy; + oldenabled<=enabled; + end if; + end process; + +end COINCIDENCE; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/datafifo.vhd b/rce/fw-hsio/modules/pixelcore/hdl/datafifo.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b7ea4a7a50ffa3f85abad85b089449265de3b3ac --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/datafifo.vhd @@ -0,0 +1,242 @@ +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity datafifo is + generic ( + buffersize : integer :=8192 -- FIFO size + ); + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end datafifo; + +architecture datafifo of datafifo is + + component datafifo4096 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + + component datafifo8192 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + + COMPONENT datafifo16384 + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(17 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(17 DOWNTO 0); + full : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + underflow : OUT STD_LOGIC; + prog_full : OUT STD_LOGIC + ); + END COMPONENT; + component datafifo32768 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + component datafifo65536 + port ( + din: IN std_logic_VECTOR(17 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(17 downto 0); + empty: OUT std_logic; + full: OUT std_logic; + overflow: OUT std_logic; + prog_full: OUT std_logic; + valid: OUT std_logic; + underflow: out std_logic); + end component; + COMPONENT datafifo131072 + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(17 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(17 DOWNTO 0); + full : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + underflow : OUT STD_LOGIC; + prog_full : OUT STD_LOGIC + ); + END COMPONENT; + +begin + + buf_4096: if (buffersize=4096) generate + fifo4096 : datafifo4096 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + buf_8192: if (buffersize=8192) generate + fifo8192 : datafifo8192 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + buf_16384: if (buffersize=16384) generate + fifo16384 : datafifo16384 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + buf_32768: if (buffersize=32768) generate + fifo32768 : datafifo32768 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + buf_65536: if (buffersize=65536) generate + fifo65536 : datafifo65536 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + buf_131072: if (buffersize=131072) generate + fifo131072 : datafifo131072 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => rd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => dout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => valid, + underflow => underflow); + end generate; + + +end datafifo; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/dataflag.vhd b/rce/fw-hsio/modules/pixelcore/hdl/dataflag.vhd new file mode 100644 index 0000000000000000000000000000000000000000..af926d90003fac339288a0c091fd9d649c6b2ddc --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/dataflag.vhd @@ -0,0 +1,90 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity dataflag is + port ( + eofin : in std_logic; + eofout : in std_logic; + datawaiting: out std_logic; + clk : in std_logic; + rst : in std_logic; + counter : out std_logic_vector(15 downto 0) + ); +end dataflag; + +architecture DATAFLAG of dataflag is + + component eofcounter + port ( + clk: IN std_logic; + up: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(15 downto 0)); + end component; + signal iszero: std_logic; + signal oldeofin: std_logic; + signal oldeofout: std_logic; + signal cond: std_logic; + signal eofincond: std_logic; + signal eofoutcond: std_logic; + signal updown: std_logic; + signal init: std_logic; + +begin + +-- datawaiting<=not iszero; + -- reset resets the threshold flag, too :-( + datawaiting<=not iszero when init='1' else '0'; + process (rst,clk) + begin + if(rst='1')then + oldeofin<='1'; + oldeofout<='1'; + cond<='0'; + init<='0'; + elsif(rising_edge(clk))then + oldeofin<=eofin; + oldeofout<=eofout; + if(eofin='1' and oldeofin='0')then + eofincond<='1'; + init<='1'; + else + eofincond<='0'; + end if; + if(eofout='1' and oldeofout='0')then + eofoutcond<='1'; + else + eofoutcond<='0'; + end if; + cond<=eofincond xor eofoutcond; + updown<=eofincond; + + end if; + end process; + + + theeofcounter: eofcounter + port map( + clk=>clk, + up=>updown, + ce=>cond, + aclr=>rst, + q_thresh0=>iszero, + q=>counter); + +end DATAFLAG; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/dataflagff.vhd b/rce/fw-hsio/modules/pixelcore/hdl/dataflagff.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1581a021e2de54a1c906d3038cb141adeda17c39 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/dataflagff.vhd @@ -0,0 +1,85 @@ +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity dataflagff is + port ( + eofin : in std_logic; + ldin : in std_logic; + eofout : in std_logic; + ldout : in std_logic; + datawaiting: out std_logic; + moredatawaiting: out std_logic; + clkin : in std_logic; + clkinrate : in std_logic; + clkout : in std_logic; + rst : in std_logic + ); +end dataflagff; + +architecture DATAFLAGFF of dataflagff is + COMPONENT dataflagfifo + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(0 DOWNTO 0); + full : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + empty : OUT STD_LOGIC + ); + END COMPONENT; + + signal datain: std_logic; + signal dataout: std_logic; + signal empty: std_logic; + signal almostempty: std_logic; + signal olddatain: std_logic; + signal oldolddatain: std_logic; + signal oldoldolddatain: std_logic; + signal seldatain: std_logic; + + begin + process(rst, clkin) + begin + if(rst='1')then + datain<='0'; + olddatain<='0'; + oldolddatain<='0'; + oldoldolddatain<='0'; + elsif (rising_edge(clkin))then + datain<=eofin and ldin; + olddatain<=datain; + oldolddatain<=olddatain; + oldoldolddatain<=oldolddatain; + end if; + end process; + + dataout<=eofout and ldout; + with clkinrate select + seldatain<=olddatain when '0', + oldoldolddatain when others; + + + thedataflagfifo : dataflagfifo + PORT MAP ( + rst => rst, + wr_clk => clkin, + rd_clk => clkout, + din => "1", + wr_en => seldatain, + rd_en => dataout, + dout => open, + full => open, + almost_empty => almostempty, + empty => empty + ); + datawaiting <= not empty; + moredatawaiting <= not almostempty; + +end DATAFLAGFF; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/dataflagnew.vhd b/rce/fw-hsio/modules/pixelcore/hdl/dataflagnew.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1a006e75cc42837e8e245ccaf646d8d7007be74c --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/dataflagnew.vhd @@ -0,0 +1,79 @@ +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity dataflagnew is + port ( + eofin : in std_logic; + eofout : in std_logic; + datawaiting: out std_logic; + moredatawaiting: out std_logic; + clkin : in std_logic; + clkout : in std_logic; + rst : in std_logic + ); +end dataflagnew; + +architecture DATAFLAGNEW of dataflagnew is + COMPONENT dataflagfifo + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(0 DOWNTO 0); + full : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + empty : OUT STD_LOGIC + ); + END COMPONENT; + + signal oldeofin: std_logic; + signal oldeofout: std_logic; + signal datain: std_logic; + signal dataout: std_logic; + signal empty: std_logic; + signal almostempty: std_logic; + + begin + + process(rst, clkin) + begin + if(rst='1')then + oldeofin<='0'; + elsif (rising_edge(clkin))then + oldeofin<=eofin; + datain<=eofin and not oldeofin; + end if; + end process; + + process(rst, clkout) + begin + if(rst='1')then + oldeofout<='0'; + elsif (rising_edge(clkout))then + oldeofout<=eofout; + dataout<=eofout and not oldeofout; + end if; + end process; + thedataflagfifo : dataflagfifo + PORT MAP ( + rst => rst, + wr_clk => clkin, + rd_clk => clkout, + din => "1", + wr_en => datain, + rd_en => dataout, + dout => open, + full => open, + almost_empty => almostempty, + empty => empty + ); + datawaiting <= not empty; + moredatawaiting <= not empty and not almostempty; + +end DATAFLAGNEW; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/dec.mif b/rce/fw-hsio/modules/pixelcore/hdl/dec.mif new file mode 100644 index 0000000000000000000000000000000000000000..144248874963b33a53b33b3c00573c59ac33d582 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/dec.mif @@ -0,0 +1,1024 @@ +10101111111111 +10101111111111 +10101111111111 +10101111111100 +10101011111111 +10101011101111 +10101011100000 +10101011100111 +10101011111111 +10101011110000 +10101011111111 +00101011101011 +10101011111000 +00101011101101 +00101011101110 +10001011111111 +10101111111111 +10101111100001 +10101111100010 +00101111110011 +10101111100100 +00101111110101 +00101111110110 +10001111110111 +10101111101000 +00101111111001 +00101111111010 +10001111111011 +00101111111100 +10001111111101 +10001111111110 +10001111111111 +10101011111111 +10101011111110 +10101011111101 +00101011100011 +10101011111011 +00101011100101 +00101011100110 +10001011101000 +10101011110111 +00101011101001 +00101011101010 +10001011100100 +00101011101100 +10001011100010 +10001011100001 +10001011111111 +10101011111111 +00101011110001 +00101011110010 +10001011111000 +00101011110100 +10001011111111 +10001011110000 +10001011111111 +00101011100111 +10001011100000 +10001011101111 +10001011111111 +10001111111100 +10001111111111 +10001111111111 +10001111111111 +10101111111111 +10101111111111 +10101111111111 +10101111111100 +10101011111111 +10101011101111 +10101011100000 +10101011100111 +10101011111111 +10101011110000 +10101011111111 +00100011101011 +10101011111000 +00100011101101 +00100011101110 +10001011111111 +10101111111111 +10101111100001 +10101111100010 +00101111110011 +10101111100100 +00101111110101 +00101111110110 +10000111110111 +10101111101000 +00101111111001 +00101111111010 +10000111111011 +00101111111100 +10000111111101 +10000111111110 +10001111111111 +10101011111111 +10101011111110 +10101011111101 +00101011100011 +10101011111011 +00101011100101 +00101011100110 +10001011101000 +10101011110111 +00101011101001 +00101011101010 +10001011100100 +00101011101100 +10001011100010 +10001011100001 +10001011111111 +10101011111111 +00101011110001 +00101011110010 +10001011111000 +00101011110100 +10001011111111 +10001011110000 +10001011111111 +00101011100111 +10001011100000 +10001011101111 +10001011111111 +10000111111100 +10001111111111 +10001111111111 +10001111111111 +10101100011111 +10101100011111 +10101100011111 +10101100011100 +10101000011111 +10101000001111 +10101000000000 +10101000000111 +10101000011111 +10101000010000 +10101000011111 +00100000001011 +10101000011000 +00100000001101 +00100000001110 +10001000011111 +10101000011111 +10101000000001 +10101000000010 +00100000010011 +10101000000100 +00100000010101 +00100000010110 +10000000010111 +10101000001000 +00100000011001 +00100000011010 +10000000011011 +00100000011100 +10000000011101 +10000000011110 +10001000011111 +10101000011111 +10101000011110 +10101000011101 +00100000000011 +10101000011011 +00100000000101 +00100000000110 +10000000001000 +10101000010111 +00100000001001 +00100000001010 +10000000000100 +00100000001100 +10000000000010 +10000000000001 +10001000011111 +10101000011111 +00100000010001 +00100000010010 +10000000011000 +00100000010100 +10000000011111 +10000000010000 +10001000011111 +00100000000111 +10000000000000 +10000000001111 +10001000011111 +10000100011100 +10001100011111 +10001100011111 +10001100011111 +00101101111111 +00101101111111 +00101101111111 +00100101111100 +00101001111111 +00100001101111 +00100001100000 +10000001100111 +00101001111111 +00100001110000 +00100001111111 +10000001101011 +00100001111000 +10000001101101 +10000001101110 +10001001111111 +00101001111111 +00100001100001 +00100001100010 +10000001110011 +00100001100100 +10000001110101 +10000001110110 +10001001110111 +00100001101000 +10000001111001 +10000001111010 +10001001111011 +10000001111100 +10001001111101 +10001001111110 +10001001111111 +00101001111111 +00100001111110 +00100001111101 +10000001100011 +00100001111011 +10000001100101 +10000001100110 +10001001101000 +00100001110111 +10000001101001 +10000001101010 +10001001100100 +10000001101100 +10001001100010 +10001001100001 +10001001111111 +00101001111111 +10000001110001 +10000001110010 +10001001111000 +10000001110100 +10001001111111 +10001001110000 +10001001111111 +10101001100111 +10001001100000 +10001001101111 +10001001111111 +10001101111100 +10001101111111 +10001101111111 +10001101111111 +10101110011111 +10101110011111 +10101110011111 +10101110011100 +10101010011111 +10101010001111 +10101010000000 +10101010000111 +10101010011111 +10101010010000 +10101010011111 +00100010001011 +10101010011000 +00100010001101 +00100010001110 +10001010011111 +10101010011111 +10101010000001 +10101010000010 +00100010010011 +10101010000100 +00100010010101 +00100010010110 +10000010010111 +10101010001000 +00100010011001 +00100010011010 +10000010011011 +00100010011100 +10000010011101 +10000010011110 +10001010011111 +10101010011111 +10101010011110 +10101010011101 +00100010000011 +10101010011011 +00100010000101 +00100010000110 +10000010001000 +10101010010111 +00100010001001 +00100010001010 +10000010000100 +00100010001100 +10000010000010 +10000010000001 +10001010011111 +10101010011111 +00100010010001 +00100010010010 +10000010011000 +00100010010100 +10000010011111 +10000010010000 +10001010011111 +00100010000111 +10000010000000 +10000010001111 +10001010011111 +10000110011100 +10001110011111 +10001110011111 +10001110011111 +00101101011111 +00101101011111 +00101101011111 +00100101011100 +00101010111111 +00100010101111 +00100010100000 +10000010100111 +00101010111111 +00100010110000 +00100010111111 +01000010101011 +00100010111000 +01000010101101 +01000010101110 +11011010111111 +00101010111111 +00100010100001 +00100010100010 +01000010110011 +00100010100100 +01000010110101 +01000010110110 +11010010110111 +00100010101000 +01000010111001 +01000010111010 +11010010111011 +01000010111100 +11010010111101 +11010010111110 +11011010111111 +00101010111111 +00100010111110 +00100010111101 +01000010100011 +00100010111011 +01000010100101 +01000010100110 +11010010101000 +00100010110111 +01000010101001 +01000010101010 +11010010100100 +01000010101100 +11010010100010 +11010010100001 +11011010111111 +00101010111111 +01000010110001 +01000010110010 +11010010111000 +01000010110100 +11010010111111 +11010010110000 +11011010111111 +01110010100111 +11010010100000 +11010010101111 +11011010111111 +11010110111100 +11011110111111 +11011110111111 +11011110111111 +00101100111111 +00101100111111 +00101100111111 +00100100111100 +00101011011111 +00100011001111 +00100011000000 +10000011000111 +00101011011111 +00100011010000 +00100011011111 +01000011001011 +00100011011000 +01000011001101 +01000011001110 +11011011011111 +00101011011111 +00100011000001 +00100011000010 +01000011010011 +00100011000100 +01000011010101 +01000011010110 +11010011010111 +00100011001000 +01000011011001 +01000011011010 +11010011011011 +01000011011100 +11010011011101 +11010011011110 +11011011011111 +00101011011111 +00100011011110 +00100011011101 +01000011000011 +00100011011011 +01000011000101 +01000011000110 +11010011001000 +00100011010111 +01000011001001 +01000011001010 +11010011000100 +01000011001100 +11010011000010 +11010011000001 +11011011011111 +00101011011111 +01000011010001 +01000011010010 +11010011011000 +01000011010100 +11010011011111 +11010011010000 +11011011011111 +01110011000111 +11010011000000 +11010011001111 +11011011011111 +11010111011100 +11011111011111 +11011111011111 +11011111011111 +01111111111111 +01111111111111 +01111111111111 +01111111111100 +01111011111111 +01110011101111 +01110011100000 +11010011100111 +01111011111111 +01110011110000 +01110011111111 +11010011101011 +01110011111000 +11010011101101 +11010011101110 +11111011111111 +01111011111111 +01110011100001 +01110011100010 +11010011110011 +01110011100100 +11010011110101 +11010011110110 +11111011110111 +01110011101000 +11010011111001 +11010011111010 +11111011111011 +11010011111100 +11111011111101 +11111011111110 +11111011111111 +01111011111111 +01110011111110 +01110011111101 +11010011100011 +01110011111011 +11010011100101 +11010011100110 +11111011101000 +01110011110111 +11010011101001 +11010011101010 +11111011100100 +11010011101100 +11111011100010 +11111011100001 +11111011111111 +01111011111111 +11011011110001 +11011011110010 +11111011111000 +11011011110100 +11111011111111 +11111011110000 +11111011111111 +11111011100111 +11111011100000 +11111011101111 +11111011111111 +11111111111100 +11111111111111 +11111111111111 +11111111111111 +10101111111111 +10101111111111 +10101111111111 +10101111111100 +10101011111111 +10101011101111 +10101011100000 +10101011100111 +10101011111111 +10101011110000 +10101011111111 +00101011101011 +10101011111000 +00101011101101 +00101011101110 +10001011111111 +10101011111111 +10101011100001 +10101011100010 +00100011110011 +10101011100100 +00100011110101 +00100011110110 +10000011110111 +10101011101000 +00100011111001 +00100011111010 +10000011111011 +00100011111100 +10000011111101 +10000011111110 +10001011111111 +10101011111111 +10101011111110 +10101011111101 +00100011100011 +10101011111011 +00100011100101 +00100011100110 +10000011101000 +10101011110111 +00100011101001 +00100011101010 +10000011100100 +00100011101100 +10000011100010 +10000011100001 +10001011111111 +10101011111111 +00100011110001 +00100011110010 +10000011111000 +00100011110100 +10000011111111 +10000011110000 +10001011111111 +00100011100111 +10000011100000 +10000011101111 +10001011111111 +10001111111100 +10001111111111 +10001111111111 +10001111111111 +00101111011111 +00101111011111 +00101111011111 +00100111011100 +00101000111111 +00100000101111 +00100000100000 +10000000100111 +00101000111111 +00100000110000 +00100000111111 +01000000101011 +00100000111000 +01000000101101 +01000000101110 +11011000111111 +00101000111111 +00100000100001 +00100000100010 +01000000110011 +00100000100100 +01000000110101 +01000000110110 +11010000110111 +00100000101000 +01000000111001 +01000000111010 +11010000111011 +01000000111100 +11010000111101 +11010000111110 +11011000111111 +00101000111111 +00100000111110 +00100000111101 +01000000100011 +00100000111011 +01000000100101 +01000000100110 +11010000101000 +00100000110111 +01000000101001 +01000000101010 +11010000100100 +01000000101100 +11010000100010 +11010000100001 +11011000111111 +00101000111111 +01000000110001 +01000000110010 +11010000111000 +01000000110100 +11010000111111 +11010000110000 +11011000111111 +01110000100111 +11010000100000 +11010000101111 +11011000111111 +11010100111100 +11011100111111 +11011100111111 +11011100111111 +00101110111111 +00101110111111 +00101110111111 +00100110111100 +00101001011111 +00100001001111 +00100001000000 +10000001000111 +00101001011111 +00100001010000 +00100001011111 +01000001001011 +00100001011000 +01000001001101 +01000001001110 +11011001011111 +00101001011111 +00100001000001 +00100001000010 +01000001010011 +00100001000100 +01000001010101 +01000001010110 +11010001010111 +00100001001000 +01000001011001 +01000001011010 +11010001011011 +01000001011100 +11010001011101 +11010001011110 +11011001011111 +00101001011111 +00100001011110 +00100001011101 +01000001000011 +00100001011011 +01000001000101 +01000001000110 +11010001001000 +00100001010111 +01000001001001 +01000001001010 +11010001000100 +01000001001100 +11010001000010 +11010001000001 +11011001011111 +00101001011111 +01000001010001 +01000001010010 +11010001011000 +01000001010100 +11010001011111 +11010001010000 +11011001011111 +01110001000111 +11010001000000 +11010001001111 +11011001011111 +11010101011100 +11011101011111 +11011101011111 +11011101011111 +01111110011111 +01111110011111 +01111110011111 +01110110011100 +01111010011111 +01110010001111 +01110010000000 +11010010000111 +01111010011111 +01110010010000 +01110010011111 +11010010001011 +01110010011000 +11010010001101 +11010010001110 +11111010011111 +01111010011111 +01110010000001 +01110010000010 +11010010010011 +01110010000100 +11010010010101 +11010010010110 +11111010010111 +01110010001000 +11010010011001 +11010010011010 +11111010011011 +11010010011100 +11111010011101 +11111010011110 +11111010011111 +01111010011111 +01110010011110 +01110010011101 +11010010000011 +01110010011011 +11010010000101 +11010010000110 +11111010001000 +01110010010111 +11010010001001 +11010010001010 +11111010000100 +11010010001100 +11111010000010 +11111010000001 +11111010011111 +01111010011111 +11010010010001 +11010010010010 +11111010011000 +11010010010100 +11111010011111 +11111010010000 +11111010011111 +11111010000111 +11111010000000 +11111010001111 +11111010011111 +11111110011100 +11111110011111 +11111110011111 +11111110011111 +01111101111111 +01111101111111 +01111101111111 +01111101111100 +01111001111111 +01111001101111 +01111001100000 +11111001100111 +01111001111111 +01111001110000 +01111001111111 +01110001101011 +01111001111000 +01110001101101 +01110001101110 +11011001111111 +01111001111111 +01111001100001 +01111001100010 +01110001110011 +01111001100100 +01110001110101 +01110001110110 +11010001110111 +01111001101000 +01110001111001 +01110001111010 +11010001111011 +01110001111100 +11010001111101 +11010001111110 +11011001111111 +01111001111111 +01111001111110 +01111001111101 +01110001100011 +01111001111011 +01110001100101 +01110001100110 +11010001101000 +01111001110111 +01110001101001 +01110001101010 +11010001100100 +01110001101100 +11010001100010 +11010001100001 +11011001111111 +01111001111111 +01110001110001 +01110001110010 +11010001111000 +01110001110100 +11010001111111 +11010001110000 +11011001111111 +01110001100111 +11010001100000 +11010001101111 +11011001111111 +11010101111100 +11011101111111 +11011101111111 +11011101111111 +01111100011111 +01111100011111 +01111100011111 +01110100011100 +01111000011111 +01110000001111 +01110000000000 +11010000000111 +01111000011111 +01110000010000 +01110000011111 +11010000001011 +01110000011000 +11010000001101 +11010000001110 +11111000011111 +01111000011111 +01110000000001 +01110000000010 +11010000010011 +01110000000100 +11010000010101 +11010000010110 +11111000010111 +01110000001000 +11010000011001 +11010000011010 +11111000011011 +11010000011100 +11111000011101 +11111000011110 +11111000011111 +01111000011111 +01110000011110 +01110000011101 +11010000000011 +01110000011011 +11010000000101 +11010000000110 +11111000001000 +01110000010111 +11010000001001 +11010000001010 +11111000000100 +11010000001100 +11111000000010 +11111000000001 +11111000011111 +01111000011111 +11010000010001 +11010000010010 +11111000011000 +11010000010100 +11111000011111 +11111000010000 +11111000011111 +11111000000111 +11111000000000 +11111000001111 +11111000011111 +11111100011100 +11111100011111 +11111100011111 +11111100011111 +01111111111111 +01111111111111 +01111111111111 +01110111111100 +01111011111111 +01111011101111 +01111011100000 +11011011100111 +01111011111111 +01111011110000 +01111011111111 +11011011101011 +01111011111000 +11011011101101 +11011011101110 +11111011111111 +01111011111111 +01111011100001 +01111011100010 +11011011110011 +01111011100100 +11011011110101 +11011011110110 +11111011110111 +01111011101000 +11011011111001 +11011011111010 +11111011111011 +11011011111100 +11111011111101 +11111011111110 +11111011111111 +01111111111111 +01110111111110 +01110111111101 +11011111100011 +01110111111011 +11011111100101 +11011111100110 +11111111101000 +01110111110111 +11011111101001 +11011111101010 +11111111100100 +11011111101100 +11111111100010 +11111111100001 +11111111111111 +01111011111111 +11010011110001 +11010011110010 +11111011111000 +11010011110100 +11111011111111 +11111011110000 +11111011111111 +11111011100111 +11111011100000 +11111011101111 +11111011111111 +11111111111100 +11111111111111 +11111111111111 +11111111111111 +01111111111111 +01111111111111 +01111111111111 +01111111111100 +01111011111111 +01111011101111 +01111011100000 +11011011100111 +01111011111111 +01111011110000 +01111011111111 +11011011101011 +01111011111000 +11011011101101 +11011011101110 +11111011111111 +01111011111111 +01111011100001 +01111011100010 +11011011110011 +01111011100100 +11011011110101 +11011011110110 +11111011110111 +01111011101000 +11011011111001 +11011011111010 +11111011111011 +11011011111100 +11111011111101 +11111011111110 +11111011111111 +01111111111111 +01111111111110 +01111111111101 +11011111100011 +01111111111011 +11011111100101 +11011111100110 +11111111101000 +01111111110111 +11011111101001 +11011111101010 +11111111100100 +11011111101100 +11111111100010 +11111111100001 +11111111111111 +01111011111111 +11011011110001 +11011011110010 +11111011111000 +11011011110100 +11111011111111 +11111011110000 +11111011111111 +11111011100111 +11111011100000 +11111011101111 +11111011111111 +11111111111100 +11111111111111 +11111111111111 +11111111111111 diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_bram.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_bram.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b0f0adb530a26cc7171537498099ef88df744dd3 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_bram.vhd @@ -0,0 +1,337 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_bram.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : Block memory-based Decoder for decoding 8b/10b encoded symbols +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_arith.ALL; +USE IEEE.std_logic_unsigned.ALL; +USE STD.textio.ALL; -- required to initialize bram from .mif + + +LIBRARY decode_8b10b; +USE work.decode_8b10b_pkg.ALL; + +----------------------------------------------------------------------------- +-- Entity Declaration +----------------------------------------------------------------------------- +ENTITY decode_8b10b_bram IS + GENERIC ( + C_ELABORATION_DIR : STRING := "./"; + C_HAS_BPORTS : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_DISP_IN_B : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_DISP_ERR_B : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_HAS_RUN_DISP_B : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0; + C_HAS_SYM_DISP_B : INTEGER := 0; + C_HAS_ND : INTEGER := 0; + C_HAS_ND_B : INTEGER := 0; + C_SINIT_DOUT : STRING := "00000000"; + C_SINIT_DOUT_B : STRING := "00000000"; + C_SINIT_KOUT : INTEGER := 0; + C_SINIT_KOUT_B : INTEGER := 0; + C_SINIT_RUN_DISP : INTEGER := 0; + C_SINIT_RUN_DISP_B : INTEGER := 0 + ); + + PORT ( + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + CE_B : IN STD_LOGIC := '0'; + CLK_B : IN STD_LOGIC := '0'; + DIN_B : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := "0000000000"; + DISP_IN : IN STD_LOGIC := '0'; + DISP_IN_B : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + SINIT_B : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + CODE_ERR_B : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + DISP_ERR_B : OUT STD_LOGIC := '0'; + DOUT_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT_B : OUT STD_LOGIC ; + ND : OUT STD_LOGIC := '0'; + ND_B : OUT STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC ; + RUN_DISP_B : OUT STD_LOGIC ; + SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ; + SYM_DISP_B : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) + ); + +END decode_8b10b_bram; + + +----------------------------------------------------------------------------- +-- Architecture +----------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_bram IS + +----------------------------------------------------------------------------- +-- .MIF file support +----------------------------------------------------------------------------- + -- Specify relative path for .mif file + CONSTANT mif_file_name : STRING := C_ELABORATION_DIR & "dec.mif"; + + -- Initialize inferred ROM from mif file + TYPE RomType IS ARRAY(0 TO 1023) OF BIT_VECTOR(13 DOWNTO 0); + IMPURE FUNCTION InitRomFromFile (RomFileName : IN STRING) RETURN RomType IS + FILE RomFile : TEXT OPEN READ_MODE IS RomFileName; + VARIABLE RomFileLine : LINE; + VARIABLE ROM : RomType; + BEGIN + FOR I IN RomType'range LOOP + READLINE (RomFile, RomFileLine); + for J in 13 downto 0 LOOP + READ (RomFileLine, ROM(I)(J)); + END LOOP; + end LOOP; + RETURN ROM; + END FUNCTION; + SIGNAL ROM : RomType := InitRomFromFile(mif_file_name); + +----------------------------------------------------------------------------- +-- Constant initialization values for internal signals ROM_data(_b) +----------------------------------------------------------------------------- + CONSTANT INIT_DATA : STRING := + concat_sinit(C_SINIT_RUN_DISP,C_SINIT_KOUT, C_SINIT_DOUT); + CONSTANT INIT_DATA_B : STRING := + concat_sinit(C_SINIT_RUN_DISP_B,C_SINIT_KOUT_B, C_SINIT_DOUT_B); + +----------------------------------------------------------------------------- +-- Signal Declarations +----------------------------------------------------------------------------- + SIGNAL dout_i : STD_LOGIC_VECTOR(7 DOWNTO 0) := + str_to_slv(C_SINIT_DOUT,8); + SIGNAL kout_i : STD_LOGIC := + bint_2_sl(C_SINIT_KOUT); + SIGNAL dout_b_i : STD_LOGIC_VECTOR(7 DOWNTO 0) := + str_to_slv(C_SINIT_DOUT_B,8); + SIGNAL kout_b_i : STD_LOGIC := + bint_2_sl(C_SINIT_KOUT_B); + SIGNAL run_disp_i : STD_LOGIC := + bint_2_sl(C_SINIT_RUN_DISP); + SIGNAL run_disp_b_i : STD_LOGIC := + bint_2_sl(C_SINIT_RUN_DISP_B); + SIGNAL sym_disp_i : STD_LOGIC_VECTOR(1 DOWNTO 0) := + conv_std_logic_vector(C_SINIT_RUN_DISP,2); + SIGNAL sym_disp_b_i : STD_LOGIC_VECTOR(1 DOWNTO 0) := + conv_std_logic_vector(C_SINIT_RUN_DISP_B,2); + +--Internal signals tied to the 14x1k block memory---------------------------- + SIGNAL ROM_address : STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + SIGNAL ROM_data : STD_LOGIC_VECTOR(13 DOWNTO 0) := + str_to_slv(INIT_DATA, 14); + +----------------------------------------------------------------------------- +-- BEGIN ARCHITECTURE +----------------------------------------------------------------------------- +BEGIN + + -- Map internal signals to outputs + DOUT <= dout_i; + KOUT <= kout_i; + DOUT_B <= dout_b_i; + KOUT_B <= kout_b_i; + RUN_DISP <= run_disp_i; + RUN_DISP_B <= run_disp_b_i; + SYM_DISP <= sym_disp_i; + SYM_DISP_B <= sym_disp_b_i; + +----------------------------------------------------------------------------- +-- Decoder A +----------------------------------------------------------------------------- + + ROM_address <= DIN; + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + ROM_data <= str_to_slv(INIT_DATA, 14) AFTER TFF; + ELSE + ROM_data <= to_stdlogicvector(ROM(conv_integer(ROM_address))) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + -- Map ROM data into dout, kout, and code_err outputs + dout_i <= ROM_data(7 DOWNTO 0); + kout_i <= ROM_data(8); + CODE_ERR <= ROM_data(9); + + + ----------------------------------------------------------------------------- + -- Instantiate disparity logic block for Decoder A + ----------------------------------------------------------------------------- + dla : ENTITY decode_8b10b_disp + GENERIC MAP( + C_SINIT_DOUT => C_SINIT_DOUT, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP, + C_HAS_DISP_IN => C_HAS_DISP_IN, + C_HAS_DISP_ERR => C_HAS_DISP_ERR, + C_HAS_RUN_DISP => C_HAS_RUN_DISP, + C_HAS_SYM_DISP => C_HAS_SYM_DISP + ) + PORT MAP( + SINIT => SINIT, + CE => CE, + CLK => CLK, + SYM_DISP => ROM_data(13 DOWNTO 10), + DISP_IN => DISP_IN, + RUN_DISP => run_disp_i, + DISP_ERR => DISP_ERR, + USER_SYM_DISP => sym_disp_i + ); + + -- create ND output + gndr : IF (C_HAS_ND = 1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF ((SINIT = '1') AND (CE = '1')) THEN + ND <= '0' AFTER TFF; + ELSE + ND <= CE AFTER TFF; + END IF; + END IF; + END PROCESS; + END GENERATE gndr; + + +------------------------------------------------------------------------------- +-- Generate Decoder B +------------------------------------------------------------------------------- + gdp : IF (C_HAS_BPORTS=1) GENERATE + --Internal signals tied to the 14x1k block memory (B)---------------------- + SIGNAL ROM_address_b : STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + SIGNAL ROM_data_b : STD_LOGIC_VECTOR(13 DOWNTO 0) := + str_to_slv(INIT_DATA_B, 14); + + BEGIN + ROM_address_b <= DIN_B; + PROCESS (CLK_B) + BEGIN + IF (CLK_B'event AND CLK_B = '1') THEN + IF (CE_B = '1') THEN + IF (SINIT_B = '1') THEN + ROM_data_b <= str_to_slv(INIT_DATA_B, 14) AFTER TFF; + ELSE + ROM_data_b <= to_stdlogicvector(ROM(conv_integer(ROM_address_b))) + AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + -- Map ROM_data_b into dout_b, kout_b, and code_err_b outputs + dout_b_i <= ROM_data_b(7 DOWNTO 0); + kout_b_i <= ROM_data_b(8); + CODE_ERR_B <= ROM_data_b(9); + + ----------------------------------------------------------------------------- + -- Instantiate disparity logic block for Decoder B + ----------------------------------------------------------------------------- + dlb : ENTITY decode_8b10b_disp + GENERIC MAP( + C_SINIT_DOUT => C_SINIT_DOUT_B, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP_B, + C_HAS_DISP_IN => C_HAS_DISP_IN_B, + C_HAS_DISP_ERR => C_HAS_DISP_ERR_B, + C_HAS_RUN_DISP => C_HAS_RUN_DISP_B, + C_HAS_SYM_DISP => C_HAS_SYM_DISP_B + ) + PORT MAP( + SINIT => SINIT_B, + CE => CE_B, + CLK => CLK_B, + SYM_DISP => ROM_data_b(13 DOWNTO 10), + DISP_IN => DISP_IN_B, + RUN_DISP => run_disp_b_i, + DISP_ERR => DISP_ERR_B, + USER_SYM_DISP => sym_disp_b_i + ); + + -- create ND_B output + gndbr : IF (C_HAS_ND_B = 1) GENERATE + PROCESS (CLK_B) + BEGIN + IF (CLK_B'event AND CLK_B = '1') THEN + IF ((SINIT_B = '1') AND (CE_B = '1')) THEN + ND_B <= '0' AFTER TFF; + ELSE + ND_B <= CE_B AFTER TFF; + END IF; + END IF; + END PROCESS; + END GENERATE gndbr; + + END GENERATE gdp; + +END xilinx; + + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_disp.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_disp.vhd new file mode 100644 index 0000000000000000000000000000000000000000..9753ec44c32caeebcec8b4ac4ac700023b59b43f --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_disp.vhd @@ -0,0 +1,207 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_disp.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : Block memory-based Decoder disparity logic +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +LIBRARY decode_8b10b; +USE work.decode_8b10b_pkg.ALL; + +------------------------------------------------------------------------------ +--Entity Declaration +------------------------------------------------------------------------------ +ENTITY decode_8b10b_disp IS + GENERIC( + C_SINIT_DOUT : STRING := "00000000"; + C_SINIT_RUN_DISP : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0 + ); + PORT( + CE : IN STD_LOGIC := '0'; + CLK : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + SYM_DISP : IN STD_LOGIC_VECTOR(3 DOWNTO 0) := (OTHERS => '0'); + DISP_IN : IN STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + USER_SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => '0') + ); +END decode_8b10b_disp; + + +------------------------------------------------------------------------------ +-- Architecture +------------------------------------------------------------------------------ +ARCHITECTURE xilinx OF decode_8b10b_disp IS + +---------------------------------------------------------------------------- +-- Signal Declarations +---------------------------------------------------------------------------- + SIGNAL run_disp_q : STD_LOGIC := '0'; + SIGNAL run_disp_d : STD_LOGIC := '0'; + SIGNAL disp_in_q : STD_LOGIC := '0'; + SIGNAL disp_err_i : STD_LOGIC := '0'; + +------------------------------------------------------------------------------- +-- Begin Architecture +------------------------------------------------------------------------------- +BEGIN + + gmndi : IF (C_HAS_DISP_IN/=1 AND (C_HAS_RUN_DISP = 1 OR + C_HAS_SYM_DISP = 1 OR + C_HAS_DISP_ERR = 1)) GENERATE + -- store the current running disparity in run_disp_q as a mux selector for + -- the next code's run_disp and disp_err + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + run_disp_q <= bint_2_sl(C_SINIT_RUN_DISP) AFTER TFF; + ELSE + run_disp_q <= run_disp_d AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + + -- mux the sym_disp bus and decode it into disp_err and run_disp + gde1 : IF (C_HAS_DISP_ERR = 1 OR C_HAS_SYM_DISP = 1) GENERATE + PROCESS (run_disp_q, SYM_DISP) + BEGIN + IF (run_disp_q = '1') THEN + disp_err_i <= SYM_DISP(3); + ELSE + disp_err_i <= SYM_DISP(1); + END IF; + END PROCESS; + END GENERATE gde1; + + grd1 : IF (C_HAS_RUN_DISP = 1 OR C_HAS_SYM_DISP = 1 OR + C_HAS_DISP_ERR = 1) GENERATE + PROCESS (run_disp_q, SYM_DISP) + BEGIN + IF (run_disp_q = '1') THEN + run_disp_d <= SYM_DISP(2); + ELSE + run_disp_d <= SYM_DISP(0); + END IF; + END PROCESS; + END GENERATE grd1; + END GENERATE gmndi; + + gmdi: IF (C_HAS_DISP_IN = 1 AND (C_HAS_RUN_DISP = 1 OR + C_HAS_SYM_DISP = 1 OR + C_HAS_DISP_ERR = 1)) GENERATE + -- use the current disp_in as a mux selector for the next code's run_disp + -- and disp_err + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + disp_in_q <= bint_2_sl(C_SINIT_RUN_DISP) AFTER TFF; + ELSE + disp_in_q <= DISP_IN AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + + -- mux the sym_disp bus and decode it into disp_err and run_disp + gde2 : IF (C_HAS_DISP_ERR = 1 OR C_HAS_SYM_DISP = 1) GENERATE + PROCESS (disp_in_q, SYM_DISP) + BEGIN + IF (disp_in_q = '1') THEN + disp_err_i <= SYM_DISP(3); + ELSE + disp_err_i <= SYM_DISP(1); + END IF; + END PROCESS; + END GENERATE gde2; + + grd2 : IF (C_HAS_RUN_DISP = 1 OR C_HAS_SYM_DISP = 1) GENERATE + PROCESS (disp_in_q, SYM_DISP) + BEGIN + IF (disp_in_q = '1') THEN + run_disp_d <= SYM_DISP(2); + ELSE + run_disp_d <= SYM_DISP(0); + END IF; + END PROCESS; + END GENERATE grd2; + END GENERATE gmdi; + +-- map internal signals to outputs + DISP_ERR <= disp_err_i; + RUN_DISP <= run_disp_d; + USER_SYM_DISP(1) <= disp_err_i; + USER_SYM_DISP(0) <= run_disp_d; + +END xilinx; + + + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a419a55cf4e7223845393b630cd7062940e35196 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut.vhd @@ -0,0 +1,197 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_lut.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : LUT-based Decoder for decoding 8b/10b encoded symbols +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +LIBRARY decode_8b10b; + +----------------------------------------------------------------------------- +-- Entity Declaration +----------------------------------------------------------------------------- +ENTITY decode_8b10b_lut IS + GENERIC ( + C_HAS_BPORTS : INTEGER := 0; + C_HAS_CODE_ERR : INTEGER := 0; + C_HAS_CODE_ERR_B : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_DISP_ERR_B : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_DISP_IN_B : INTEGER := 0; + C_HAS_ND : INTEGER := 0; + C_HAS_ND_B : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0; + C_HAS_SYM_DISP_B : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_HAS_RUN_DISP_B : INTEGER := 0; + C_SINIT_DOUT : STRING := "00000000"; + C_SINIT_DOUT_B : STRING := "00000000"; + C_SINIT_KOUT : INTEGER := 0; + C_SINIT_KOUT_B : INTEGER := 0; + C_SINIT_RUN_DISP : INTEGER := 0; + C_SINIT_RUN_DISP_B : INTEGER := 0 + ); + PORT ( + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + CE_B : IN STD_LOGIC := '0'; + CLK_B : IN STD_LOGIC := '0'; + DIN_B : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DISP_IN : IN STD_LOGIC := '0'; + DISP_IN_B : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + SINIT_B : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + CODE_ERR_B : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + DISP_ERR_B : OUT STD_LOGIC := '0'; + DOUT_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT_B : OUT STD_LOGIC ; + ND : OUT STD_LOGIC := '0'; + ND_B : OUT STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC ; + RUN_DISP_B : OUT STD_LOGIC ; + SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ; + SYM_DISP_B : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) + ); + +END decode_8b10b_lut; + +------------------------------------------------------------------------------- +-- Architecture +------------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_lut IS + +------------------------------------------------------------------------------- +-- Begin Architecture +------------------------------------------------------------------------------- +BEGIN + + ----Instantiate the first decoder (A decoder)-------------------------------- + deca : ENTITY decode_8b10b_lut_base + GENERIC MAP ( + C_HAS_CODE_ERR => C_HAS_CODE_ERR, + C_HAS_DISP_ERR => C_HAS_DISP_ERR, + C_HAS_DISP_IN => C_HAS_DISP_IN, + C_HAS_ND => C_HAS_ND, + C_HAS_SYM_DISP => C_HAS_SYM_DISP, + C_HAS_RUN_DISP => C_HAS_RUN_DISP, + C_SINIT_DOUT => C_SINIT_DOUT, + C_SINIT_KOUT => C_SINIT_KOUT, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP + ) + PORT MAP ( + CLK => CLK, + DIN => DIN, + DOUT => DOUT, + KOUT => KOUT, + + CE => CE, + DISP_IN => DISP_IN, + SINIT => SINIT, + CODE_ERR => CODE_ERR, + DISP_ERR => DISP_ERR, + ND => ND, + RUN_DISP => RUN_DISP, + SYM_DISP => SYM_DISP + ); + + + + gdecb : IF (C_HAS_BPORTS=1) GENERATE + ----Instantiate second decoder (B decoder, only if bports are present)------ + decb : ENTITY decode_8b10b_lut_base + GENERIC MAP ( + C_HAS_CODE_ERR => C_HAS_CODE_ERR_B, + C_HAS_DISP_ERR => C_HAS_DISP_ERR_B, + C_HAS_DISP_IN => C_HAS_DISP_IN_B, + C_HAS_ND => C_HAS_ND_B, + C_HAS_SYM_DISP => C_HAS_SYM_DISP_B, + C_HAS_RUN_DISP => C_HAS_RUN_DISP_B, + C_SINIT_DOUT => C_SINIT_DOUT_B, + C_SINIT_KOUT => C_SINIT_KOUT_B, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP_B + ) + PORT MAP ( + CLK => CLK_B, + DIN => DIN_B, + DOUT => DOUT_B, + KOUT => KOUT_B, + + CE => CE_B, + DISP_IN => DISP_IN_B, + SINIT => SINIT_B, + CODE_ERR => CODE_ERR_B, + DISP_ERR => DISP_ERR_B, + ND => ND_B, + RUN_DISP => RUN_DISP_B, + SYM_DISP => SYM_DISP_B + ); + END GENERATE gdecb; + +END xilinx ; + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut_base.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut_base.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f4de593beefa0e77471cc53c76c49354af498859 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_lut_base.vhd @@ -0,0 +1,801 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_lut_base.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : LUT-based Single-port Base Decoder for decoding 8b/10b +-- encoded symbols +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_arith.ALL; + +LIBRARY decode_8b10b; +USE work.decode_8b10b_pkg.ALL; + +------------------------------------------------------------------------------- +-- Entity Declaration +------------------------------------------------------------------------------- +ENTITY decode_8b10b_lut_base IS + GENERIC ( + C_HAS_CODE_ERR : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_ND : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_SINIT_DOUT : STRING := "00000000"; + C_SINIT_KOUT : INTEGER := 0; + C_SINIT_RUN_DISP : INTEGER := 0 + ); + PORT ( + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + DISP_IN : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + ND : OUT STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC ; + SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) + ); +END decode_8b10b_lut_base; + +------------------------------------------------------------------------------- +-- Architecture +------------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_lut_base IS + + ----------------------------------------------------------------------------- + -- Type Declarations + ----------------------------------------------------------------------------- + TYPE disparity IS (neg, pos, zero, invalid, specneg, specpos) ; + + ----------------------------------------------------------------------------- + -- Constant Declarations + ----------------------------------------------------------------------------- + -- set the default decoder output for invalid codes + CONSTANT DEFAULTB5 : STD_LOGIC_VECTOR(4 DOWNTO 0) := "11111" ; + CONSTANT DEFAULTB3 : STD_LOGIC_VECTOR(2 DOWNTO 0) := "111" ; + + ----------------------------------------------------------------------------- + -- Signal Declarations + ----------------------------------------------------------------------------- + SIGNAL dout_i : STD_LOGIC_VECTOR(7 DOWNTO 0) := + str_to_slv(C_SINIT_DOUT,8); + SIGNAL kout_i : STD_LOGIC := + bint_2_sl(C_SINIT_KOUT); + SIGNAL run_disp_i : STD_LOGIC := + bint_2_sl(C_SINIT_RUN_DISP); + SIGNAL sym_disp_i : STD_LOGIC_VECTOR(1 DOWNTO 0) := + conv_std_logic_vector(C_SINIT_RUN_DISP,2); + SIGNAL code_err_i : STD_LOGIC := '0'; + + SIGNAL symrd : STD_LOGIC_VECTOR(3 DOWNTO 0); + SIGNAL b6_disp : disparity := zero; + SIGNAL b4_disp : disparity := zero; + + SIGNAL b5 : STD_LOGIC_VECTOR(4 DOWNTO 0) := DEFAULTB5; + SIGNAL b3 : STD_LOGIC_VECTOR(7 DOWNTO 5) := DEFAULTB3; + SIGNAL k : STD_LOGIC := '0'; + SIGNAL k28 : STD_LOGIC := '0'; + + ALIAS b6 : STD_LOGIC_VECTOR(5 DOWNTO 0) IS DIN(5 DOWNTO 0) ; --iedcba + ALIAS b4 : STD_LOGIC_VECTOR(3 DOWNTO 0) IS DIN(9 DOWNTO 6) ; --jhgf + ALIAS a : STD_LOGIC IS DIN(0) ; + ALIAS b : STD_LOGIC IS DIN(1) ; + ALIAS c : STD_LOGIC IS DIN(2) ; + ALIAS d : STD_LOGIC IS DIN(3) ; + ALIAS e : STD_LOGIC IS DIN(4) ; + ALIAS i : STD_LOGIC IS DIN(5) ; + ALIAS f : STD_LOGIC IS DIN(6) ; + ALIAS g : STD_LOGIC IS DIN(7) ; + ALIAS h : STD_LOGIC IS DIN(8) ; + ALIAS j : STD_LOGIC IS DIN(9) ; + +--Signals for calculating code_error + SIGNAL p04 : STD_LOGIC := '0'; + SIGNAL p13 : STD_LOGIC := '0'; + SIGNAL p22 : STD_LOGIC := '0'; + SIGNAL p31 : STD_LOGIC := '0'; + SIGNAL p40 : STD_LOGIC := '0'; + SIGNAL fghj : STD_LOGIC := '0'; + SIGNAL eifgh : STD_LOGIC := '0'; + SIGNAL sK28 : STD_LOGIC := '0'; + SIGNAL e_i : STD_LOGIC := '0'; + SIGNAL ighj : STD_LOGIC := '0'; + SIGNAL i_ghj : STD_LOGIC := '0'; + SIGNAL kx7 : STD_LOGIC := '0'; + SIGNAL invr6 : STD_LOGIC := '0'; + SIGNAL pdbr6 : STD_LOGIC := '0'; + SIGNAL ndbr6 : STD_LOGIC := '0'; + SIGNAL pdur6 : STD_LOGIC := '0'; + SIGNAL pdbr4 : STD_LOGIC := '0'; + SIGNAL ndrr4 : STD_LOGIC := '0'; + SIGNAL ndur6 : STD_LOGIC := '0'; + SIGNAL ndbr4 : STD_LOGIC := '0'; + SIGNAL pdrr4 : STD_LOGIC := '0'; + SIGNAL fgh : STD_LOGIC := '0'; + SIGNAL invby_a : STD_LOGIC := '0'; + SIGNAL invby_b : STD_LOGIC := '0'; + SIGNAL invby_c : STD_LOGIC := '0'; + SIGNAL invby_d : STD_LOGIC := '0'; + SIGNAL invby_e : STD_LOGIC := '0'; + SIGNAL invby_f : STD_LOGIC := '0'; + SIGNAL invby_g : STD_LOGIC := '0'; + SIGNAL invby_h : STD_LOGIC := '0'; + + +------------------------------------------------------------------------------- +-- Begin Architecture +------------------------------------------------------------------------------- +BEGIN + + ----------------------------------------------------------------------------- + -- Conditionally tie optional ports to internal signals + ----------------------------------------------------------------------------- + + ----New Data----------------------------------------------------------------- + gnd : IF (C_HAS_ND = 1) GENERATE + + ----Update the New Data output------------------------------- + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF ((CE = '1') AND (SINIT = '1')) THEN + ND <= '0' AFTER TFF; + ELSE + ND <= CE AFTER TFF; + END IF ; + END IF ; + END PROCESS ; + + END GENERATE gnd ; + + ----Code Error--------------------------------------------------------------- + gcerr : IF (C_HAS_CODE_ERR = 1) GENERATE + + ----Update CODE_ERR output------------------- + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + CODE_ERR <= '0' AFTER TFF; + ELSE + CODE_ERR <= code_err_i AFTER TFF; + END IF; + END IF ; + END IF ; + END PROCESS ; + + END GENERATE gcerr ; + + + +-- The following code uses notation and logic from the 8b/10b specification + +------------------------------------------------------------------------------- +-- Set the value of k28 signal +------------------------------------------------------------------------------- + k28 <= NOT((c OR d OR e OR i) OR NOT(h XOR j)) ; + +------------------------------------------------------------------------------- +-- Do the 6B/5B conversion +------------------------------------------------------------------------------- + PROCESS (b6) + BEGIN + CASE b6 IS + WHEN "000110" => b5 <= "00000" ; --D.0 + WHEN "111001" => b5 <= "00000" ; --D.0 + WHEN "010001" => b5 <= "00001" ; --D.1 + WHEN "101110" => b5 <= "00001" ; --D.1 + WHEN "010010" => b5 <= "00010" ; --D.2 + WHEN "101101" => b5 <= "00010" ; --D.2 + WHEN "100011" => b5 <= "00011" ; --D.3 + WHEN "010100" => b5 <= "00100" ; --D.4 + WHEN "101011" => b5 <= "00100" ; --D.4 + WHEN "100101" => b5 <= "00101" ; --D.5 + WHEN "100110" => b5 <= "00110" ; --D.6 + WHEN "000111" => b5 <= "00111" ; --D.7 + WHEN "111000" => b5 <= "00111" ; --D.7 + WHEN "011000" => b5 <= "01000" ; --D.8 + WHEN "100111" => b5 <= "01000" ; --D.8 + WHEN "101001" => b5 <= "01001" ; --D.9 + WHEN "101010" => b5 <= "01010" ; --D.10 + WHEN "001011" => b5 <= "01011" ; --D.11 + WHEN "101100" => b5 <= "01100" ; --D.12 + WHEN "001101" => b5 <= "01101" ; --D.13 + WHEN "001110" => b5 <= "01110" ; --D.14 + WHEN "000101" => b5 <= "01111" ; --D.15 + WHEN "111010" => b5 <= "01111" ; --D.15 + + WHEN "110110" => b5 <= "10000" ; --D.16 + WHEN "001001" => b5 <= "10000" ; --D.16 + WHEN "110001" => b5 <= "10001" ; --D.17 + WHEN "110010" => b5 <= "10010" ; --D.18 + WHEN "010011" => b5 <= "10011" ; --D.19 + WHEN "110100" => b5 <= "10100" ; --D.20 + WHEN "010101" => b5 <= "10101" ; --D.21 + WHEN "010110" => b5 <= "10110" ; --D.22 + WHEN "010111" => b5 <= "10111" ; --D/K.23 + WHEN "101000" => b5 <= "10111" ; --D/K.23 + WHEN "001100" => b5 <= "11000" ; --D.24 + WHEN "110011" => b5 <= "11000" ; --D.24 + WHEN "011001" => b5 <= "11001" ; --D.25 + WHEN "011010" => b5 <= "11010" ; --D.26 + WHEN "011011" => b5 <= "11011" ; --D/K.27 + WHEN "100100" => b5 <= "11011" ; --D/K.27 + WHEN "011100" => b5 <= "11100" ; --D.28 + WHEN "111100" => b5 <= "11100" ; --K.28 + WHEN "000011" => b5 <= "11100" ; --K.28 + WHEN "011101" => b5 <= "11101" ; --D/K.29 + WHEN "100010" => b5 <= "11101" ; --D/K.29 + WHEN "011110" => b5 <= "11110" ; --D.30 + WHEN "100001" => b5 <= "11110" ; --D.30 + WHEN "110101" => b5 <= "11111" ; --D.31 + WHEN "001010" => b5 <= "11111" ; --D.31 + WHEN OTHERS => b5 <= DEFAULTB5 ; --CODE VIOLATION! + END CASE ; + END PROCESS ; + +------------------------------------------------------------------------------- +-- Disparity for the 6B block +------------------------------------------------------------------------------- + PROCESS (b6) + BEGIN + CASE b6 IS + WHEN "000000" => b6_disp <= neg ; --invalid ; + WHEN "000001" => b6_disp <= neg ; --invalid ; + WHEN "000010" => b6_disp <= neg ; --invalid ; + WHEN "000011" => b6_disp <= neg ; --K.28 + WHEN "000100" => b6_disp <= neg ; --invalid ; + WHEN "000101" => b6_disp <= neg ; --D.15 + WHEN "000110" => b6_disp <= neg ; --D.0 + WHEN "000111" => b6_disp <= specneg; --D.7 + WHEN "001000" => b6_disp <= neg ; --invalid ; + WHEN "001001" => b6_disp <= neg ; --D.16 + WHEN "001010" => b6_disp <= neg ; --D.31 + WHEN "001011" => b6_disp <= zero ; --D.11 + WHEN "001100" => b6_disp <= neg ; --D.24 + WHEN "001101" => b6_disp <= zero ; --D.13 + WHEN "001110" => b6_disp <= zero ; --D.14 + WHEN "001111" => b6_disp <= pos ; --invalid ; + + WHEN "010000" => b6_disp <= neg ; --invalid ; + WHEN "010001" => b6_disp <= neg ; --D.1 + WHEN "010010" => b6_disp <= neg ; --D.2 + WHEN "010011" => b6_disp <= zero ; --D.19 + WHEN "010100" => b6_disp <= neg ; --D.4 + WHEN "010101" => b6_disp <= zero ; --D.21 + WHEN "010110" => b6_disp <= zero ; --D.22 + WHEN "010111" => b6_disp <= pos ; --D.23 + WHEN "011000" => b6_disp <= neg ; --D.8 + WHEN "011001" => b6_disp <= zero ; --D.25 + WHEN "011010" => b6_disp <= zero ; --D.26 + WHEN "011011" => b6_disp <= pos ; --D.27 + WHEN "011100" => b6_disp <= zero ; --D.28 + WHEN "011101" => b6_disp <= pos ; --D.29 + WHEN "011110" => b6_disp <= pos ; --D.30 + WHEN "011111" => b6_disp <= pos ; --invalid ; + + WHEN "100000" => b6_disp <= neg ; --invalid ; + WHEN "100001" => b6_disp <= neg ; --D.30 ; + WHEN "100010" => b6_disp <= neg ; --D.29 ; + WHEN "100011" => b6_disp <= zero ; --D.3 + WHEN "100100" => b6_disp <= neg ; --D.27 + WHEN "100101" => b6_disp <= zero ; --D.5 + WHEN "100110" => b6_disp <= zero ; --D.6 + WHEN "100111" => b6_disp <= pos ; --D.8 + WHEN "101000" => b6_disp <= neg ; --D.23 + WHEN "101001" => b6_disp <= zero ; --D.9 + WHEN "101010" => b6_disp <= zero ; --D.10 + WHEN "101011" => b6_disp <= pos ; --D.4 + WHEN "101100" => b6_disp <= zero ; --D.12 + WHEN "101101" => b6_disp <= pos ; --D.2 + WHEN "101110" => b6_disp <= pos ; --D.1 + WHEN "101111" => b6_disp <= pos ; --invalid ; + + WHEN "110000" => b6_disp <= neg ; --invalid ; + WHEN "110001" => b6_disp <= zero ; --D.17 + WHEN "110010" => b6_disp <= zero ; --D.18 + WHEN "110011" => b6_disp <= pos ; --D.24 + WHEN "110100" => b6_disp <= zero ; --D.20 + WHEN "110101" => b6_disp <= pos ; --D.31 + WHEN "110110" => b6_disp <= pos ; --D.16 + WHEN "110111" => b6_disp <= pos ; --invalid ; + WHEN "111000" => b6_disp <= specpos; --D.7 + WHEN "111001" => b6_disp <= pos ; --D.0 + WHEN "111010" => b6_disp <= pos ; --D.15 + WHEN "111011" => b6_disp <= pos ; --invalid ; + WHEN "111100" => b6_disp <= pos ; --K.28 + WHEN "111101" => b6_disp <= pos ; --invalid ; + WHEN "111110" => b6_disp <= pos ; --invalid ; + WHEN "111111" => b6_disp <= pos ; --invalid ; + + WHEN OTHERS => b6_disp <= zero ; + END CASE ; + END PROCESS ; + +------------------------------------------------------------------------------- +-- Do the 3B/4B conversion +------------------------------------------------------------------------------- + PROCESS (b4, k28) + BEGIN + CASE b4 IS + WHEN "0010" => b3 <= "000" ; --D/K.x.0 + WHEN "1101" => b3 <= "000" ; --D/K.x.0 + WHEN "1001" => + IF (k28 = '0') + THEN b3 <= "001" ; --D/K.x.1 + ELSE b3 <= "110" ; --K28.6 + END IF ; + WHEN "0110" => + IF (k28 = '1') + THEN b3 <= "001" ; --K.28.1 + ELSE b3 <= "110" ; --D/K.x.6 + END IF ; + WHEN "1010" => + IF (k28 = '0') + THEN b3 <= "010" ; --D/K.x.2 + ELSE b3 <= "101" ; --K28.5 + END IF ; + WHEN "0101" => + IF (k28 = '1') + THEN b3 <= "010" ; --K28.2 + ELSE b3 <= "101" ; --D/K.x.5 + END IF ; + WHEN "0011" => b3 <= "011" ; --D/K.x.3 + WHEN "1100" => b3 <= "011" ; --D/K.x.3 + WHEN "0100" => b3 <= "100" ; --D/K.x.4 + WHEN "1011" => b3 <= "100" ; --D/K.x.4 + WHEN "0111" => b3 <= "111" ; --D.x.7 + WHEN "1000" => b3 <= "111" ; --D.x.7 + WHEN "1110" => b3 <= "111" ; --D/K.x.7 + WHEN "0001" => b3 <= "111" ; --D/K.x.7 + WHEN OTHERS => b3 <= DEFAULTB3 ; --CODE VIOLATION! + END CASE ; + END PROCESS ; + +------------------------------------------------------------------------------- +-- Disparity for the 4B block +------------------------------------------------------------------------------- + PROCESS (b4) + BEGIN + CASE b4 IS + WHEN "0000" => b4_disp <= neg ; + WHEN "0001" => b4_disp <= neg ; + WHEN "0010" => b4_disp <= neg ; + WHEN "0011" => b4_disp <= specneg; + WHEN "0100" => b4_disp <= neg ; + WHEN "0101" => b4_disp <= zero ; + WHEN "0110" => b4_disp <= zero ; + WHEN "0111" => b4_disp <= pos ; + WHEN "1000" => b4_disp <= neg ; + WHEN "1001" => b4_disp <= zero ; + WHEN "1010" => b4_disp <= zero ; + WHEN "1011" => b4_disp <= pos ; + WHEN "1100" => b4_disp <= specpos; + WHEN "1101" => b4_disp <= pos ; + WHEN "1110" => b4_disp <= pos ; + WHEN "1111" => b4_disp <= pos ; + WHEN OTHERS => b4_disp <= zero ; + END CASE ; + END PROCESS ; + +------------------------------------------------------------------------------- +-- Special Code for calculating symrd[3:0] +-- +-- +---------+---------+-------+------------+-------+------------+ +-- | | | symrd | +-- | | | + Start Disp | - Start Disp | +-- | b6_disp | b4_disp | Error | NewRunDisp | Error | NewRunDisp | +-- +---------+---------+-------+------------+-------+------------+ +-- | + | + | 1 | 1 | 1 | 1 | +-- | + | - | 1 | 0 | 0 | 0 | +-- | + | 0 | 1 | 1 | 0 | 1 | +-- | - | + | 0 | 1 | 1 | 1 | +-- | - | - | 1 | 0 | 1 | 0 | +-- | - | 0 | 0 | 0 | 1 | 0 | +-- | 0 | + | 1 | 1 | 0 | 1 | +-- | 0 | - | 0 | 0 | 1 | 0 | +-- | 0 | 0 | 0 | 1 | 0 | 0 | +-- +---------+---------+-------+------------+-------+------------+ +-- +------------------------------------------------------------------------------- + PROCESS (b4_disp, b6_disp) + BEGIN + CASE b6_disp IS + WHEN pos => + CASE b4_disp IS + WHEN pos => symrd(3 DOWNTO 0) <= "1111"; + WHEN neg => symrd(3 DOWNTO 0) <= "1000"; + WHEN specpos=> symrd(3 DOWNTO 0) <= "1101"; --Ex: D1.3- + WHEN specneg=> symrd(3 DOWNTO 0) <= "1000"; + WHEN zero => symrd(3 DOWNTO 0) <= "1101"; + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + WHEN neg => + CASE b4_disp IS + WHEN pos => symrd(3 DOWNTO 0) <= "0111"; + WHEN neg => symrd(3 DOWNTO 0) <= "1010"; + WHEN specpos=> symrd(3 DOWNTO 0) <= "0111"; + WHEN specneg=> symrd(3 DOWNTO 0) <= "0010"; --Ex: D1.3+ + WHEN zero => symrd(3 DOWNTO 0) <= "0010"; + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + WHEN zero => + CASE b4_disp IS + WHEN pos => symrd(3 DOWNTO 0) <= "1101"; + WHEN neg => symrd(3 DOWNTO 0) <= "0010"; + WHEN specpos=> symrd(3 DOWNTO 0) <= "0111"; --Ex: D11.3+ + WHEN specneg=> symrd(3 DOWNTO 0) <= "1000"; --Ex: D11.3- + WHEN zero => symrd(3 DOWNTO 0) <= "0100"; + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + WHEN specpos => + CASE b4_disp IS + WHEN pos => symrd(3 DOWNTO 0) <= "1111"; + WHEN neg => symrd(3 DOWNTO 0) <= "0010"; --Ex: D7.0+ + WHEN specpos=> symrd(3 DOWNTO 0) <= "0111"; --Ex: D7.3+ + WHEN specneg=> symrd(3 DOWNTO 0) <= "1010"; + WHEN zero => symrd(3 DOWNTO 0) <= "0111"; --Ex: D7.5+ + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + WHEN specneg => + CASE b4_disp IS + WHEN pos => symrd(3 DOWNTO 0) <= "1101"; --Ex: D7.0- + WHEN neg => symrd(3 DOWNTO 0) <= "1010"; + WHEN specpos=> symrd(3 DOWNTO 0) <= "1111"; + WHEN specneg=> symrd(3 DOWNTO 0) <= "1000"; --Ex: D7.3- + WHEN zero => symrd(3 DOWNTO 0) <= "1000"; --Ex: D7.5- + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + WHEN OTHERS => symrd(3 DOWNTO 0) <= "XXXX"; + END CASE; + END PROCESS; + + -- the new running disparity is calculated from the input disparity + -- and the disparity of the 10-bit word + grdi : IF (C_HAS_DISP_IN = 1 AND C_HAS_RUN_DISP=1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event and CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + run_disp_i <= bint_2_sl(C_SINIT_RUN_DISP) AFTER TFF; + ELSIF (DISP_IN = '1') THEN + run_disp_i <= symrd(2) AFTER TFF; + ELSE + run_disp_i <= symrd(0) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE grdi; + + -- the new running disparity is calculated from the old running disparity + -- and the disparity of the 10-bit word. run_disp is also used to + -- calculate disp_err and sym_disp when disp_in is not present + grdni : IF (C_HAS_DISP_IN /= 1 AND (C_HAS_RUN_DISP=1 OR + C_HAS_DISP_ERR=1 OR + C_HAS_SYM_DISP=1)) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event and CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + run_disp_i <= bint_2_sl(C_SINIT_RUN_DISP) AFTER TFF; + ELSIF (run_disp_i = '1') THEN + run_disp_i <= symrd(2) AFTER TFF; + ELSE + run_disp_i <= symrd(0) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE grdni; + + gde : IF (C_HAS_DISP_ERR = 1) GENERATE + -- the new disparity error is calculated from the old running disparity + -- and the error information from the 10-bit word + gdei : IF (C_HAS_DISP_IN = 1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + disp_err <= '0' AFTER TFF; + ELSIF (DISP_IN='1') THEN + disp_err <= symrd(3) AFTER TFF; + ELSE + disp_err <= symrd(1) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE gdei; + + gdeni : IF (C_HAS_DISP_IN /= 1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + disp_err <= '0' AFTER TFF; + ELSIF (run_disp_i='1') THEN + disp_err <= symrd(3) AFTER TFF; + ELSE + disp_err <= symrd(1) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE gdeni; + END GENERATE gde; + + gsd : IF (C_HAS_SYM_DISP = 1) GENERATE + gsdi : IF (C_HAS_DISP_IN = 1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + sym_disp_i <= conv_std_logic_vector(C_SINIT_RUN_DISP,2) AFTER TFF; + ELSIF (DISP_IN='1') THEN + sym_disp_i <= symrd(3 DOWNTO 2) AFTER TFF; + ELSE + sym_disp_i <= symrd(1 DOWNTO 0) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE gsdi; + + gsdni : IF (C_HAS_DISP_IN /= 1) GENERATE + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK='1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + sym_disp_i <= conv_std_logic_vector(C_SINIT_RUN_DISP,2) AFTER TFF; + ELSIF (run_disp_i='1') THEN + sym_disp_i <= symrd(3 DOWNTO 2) AFTER TFF; + ELSE + sym_disp_i <= symrd(1 DOWNTO 0) AFTER TFF; + END IF; + END IF; + END IF; + END PROCESS; + END GENERATE gsdni; + END GENERATE gsd; + + -- map internal signals to outputs + run_disp <= run_disp_i; + sym_disp <= sym_disp_i; + +------------------------------------------------------------------------------- +-- Decode the K codes +------------------------------------------------------------------------------- + PROCESS (c, d, e, i, g, h, j) + BEGIN + k <= (c AND d AND e AND i) OR NOT(c OR d OR e OR i) OR + ((e XOR i) AND ((i AND g AND h AND j) OR + NOT(i OR g OR h OR j))) ; + END PROCESS ; + +------------------------------------------------------------------------------- +-- Update the outputs on the clock +------------------------------------------------------------------------------- + ----Update DOUT output------------------- + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + dout_i <= str_to_slv(C_SINIT_DOUT, 8) AFTER TFF ; + ELSE + dout_i <= (b3 & b5) AFTER TFF; + END IF; + END IF ; + END IF ; + END PROCESS ; + DOUT <= dout_i; + ----Update KOUT output------------------- + PROCESS (CLK) + BEGIN + IF (CLK'event AND CLK = '1') THEN + IF (CE = '1') THEN + IF (SINIT = '1') THEN + kout_i <= bint_2_sl(C_SINIT_KOUT) AFTER TFF; + ELSE + kout_i <= k AFTER TFF; + END IF; + END IF ; + END IF ; + END PROCESS ; + KOUT <= kout_i; + +------------------------------------------------------------------------------- +-- Calculate code_error (uses notation from IBM spec) +------------------------------------------------------------------------------- + bitcount: PROCESS (DIN) + BEGIN + CASE DIN(3 DOWNTO 0) IS + WHEN "0000" => p04 <= '1'; + p13 <= '0'; + p22 <= '0'; + p31 <= '0'; + p40 <= '0'; + WHEN "0001" => p04 <= '0'; + p13 <= '1'; + p22 <= '0'; + p31 <= '0'; + p40 <= '0'; + WHEN "0010" => p04 <= '0'; + p13 <= '1'; + p22 <= '0'; + p31 <= '0'; + p40 <= '0'; + WHEN "0011" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "0100" => p04 <= '0'; + p13 <= '1'; + p22 <= '0'; + p31 <= '0'; + p40 <= '0'; + WHEN "0101" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "0110" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "0111" => p04 <= '0'; + p13 <= '0'; + p22 <= '0'; + p31 <= '1'; + p40 <= '0'; + WHEN "1000" => p04 <= '0'; + p13 <= '1'; + p22 <= '0'; + p31 <= '0'; + p40 <= '0'; + WHEN "1001" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "1010" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "1011" => p04 <= '0'; + p13 <= '0'; + p22 <= '0'; + p31 <= '1'; + p40 <= '0'; + WHEN "1100" => p04 <= '0'; + p13 <= '0'; + p22 <= '1'; + p31 <= '0'; + p40 <= '0'; + WHEN "1101" => p04 <= '0'; + p13 <= '0'; + p22 <= '0'; + p31 <= '1'; + p40 <= '0'; + WHEN "1110" => p04 <= '0'; + p13 <= '0'; + p22 <= '0'; + p31 <= '1'; + p40 <= '0'; + WHEN "1111" => p04 <= '0'; + p13 <= '0'; + p22 <= '0'; + p31 <= '0'; + p40 <= '1'; + WHEN OTHERS => NULL; + END CASE; + END PROCESS bitcount; + + fghj <= (f AND g AND h AND j) OR (NOT f AND NOT g AND NOT h AND NOT j); + eifgh <= (e AND i AND f AND g AND h) OR (NOT e AND NOT i AND NOT f AND NOT g + AND NOT h); + sk28 <= (c AND d AND e AND i) OR (NOT c AND NOT d AND NOT e AND NOT i); + e_i <= (e AND NOT i) OR (NOT e AND i); + ighj <= (i AND g AND h AND j) OR (NOT i AND NOT g AND NOT h AND NOT j); + i_ghj <= (NOT i AND g AND h AND j) OR (i AND NOT g AND NOT h AND NOT j); + kx7 <= e_i AND ighj; + invr6 <= p40 OR p04 OR (p31 AND e AND i) OR (p13 AND NOT e AND NOT i); + pdbr6 <= (p31 AND (e OR i)) OR (p22 AND e AND i) OR p40; + ndbr6 <= (p13 AND (NOT e OR NOT i)) OR (p22 AND NOT e AND NOT i) OR p04; + pdur6 <= pdbr6 OR (d AND e AND i); + pdbr4 <= (f AND g AND (h OR j)) OR ((f OR g) AND h AND j); + ndrr4 <= pdbr4 OR (f AND g); + ndur6 <= ndbr6 OR (NOT d AND NOT e AND NOT i); + fgh <= (f AND g AND h) OR (NOT f AND NOT g AND NOT h); + ndbr4 <= (NOT f AND NOT g AND (NOT h OR NOT j)) OR ((NOT f OR NOT g) AND + NOT h AND NOT j); + pdrr4 <= ndbr4 OR (NOT f AND NOT g); + + invby_a <= invr6; + invby_b <= fghj; + invby_c <= eifgh; + invby_d <= (NOT sk28 AND i_ghj); + invby_e <= (sk28 AND fgh); + invby_f <= (kx7 AND NOT pdbr6 AND NOT ndbr6); + invby_g <= (pdur6 AND ndrr4); + invby_h <= (ndur6 AND pdrr4); + + --Update internal code error signal + code_err_i <= invby_a OR invby_b OR invby_c OR invby_d OR invby_e OR invby_f OR + invby_g OR invby_h; + +END xilinx ; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_pkg.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..01cdcb7fbfd039d8d1a85ae00125bf23c756a7f1 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_pkg.vhd @@ -0,0 +1,251 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_pkg.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : 8b/10b Decoder package file +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +--------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +------------------------------------------------------------------------------- +-- Package Declaration +------------------------------------------------------------------------------- +PACKAGE decode_8b10b_pkg IS + +------------------------------------------------------------------------------- +-- Constant Declarations +------------------------------------------------------------------------------- + CONSTANT TFF : TIME := 2 ns; + CONSTANT CONST_NEG : STRING (1 TO 2) := "00"; + CONSTANT CONST_POS : STRING (1 TO 2) := "01"; + +------------------------------------------------------------------------------- +-- Function Declarations +------------------------------------------------------------------------------- + FUNCTION int_to_str_1bit ( + bit : INTEGER + ) RETURN STRING; + FUNCTION bint_2_sl ( + X : INTEGER + ) RETURN STD_LOGIC; + FUNCTION concat_sinit ( + integer_run_disp : INTEGER; + integer_kout : INTEGER; + string_dout : STRING + ) RETURN STRING; + FUNCTION str_to_slv( + bitsin : STRING; + nbits : INTEGER + ) RETURN STD_LOGIC_VECTOR; + FUNCTION calc_init_val_rd ( + SINIT_VAL : STRING(10 DOWNTO 1) + ) RETURN INTEGER; + FUNCTION has_bport ( + C_HAS_BPORTS : INTEGER; + has_aport : INTEGER + ) RETURN INTEGER; + +END decode_8b10b_pkg; + +------------------------------------------------------------------------------- +-- Package Body +------------------------------------------------------------------------------- +PACKAGE BODY decode_8b10b_pkg IS + +------------------------------------------------------------------------------- +-- Convert binary integer (0 or 1) into a single-character-string ("0" or "1") +------------------------------------------------------------------------------- + FUNCTION int_to_str_1bit(bit : INTEGER) RETURN STRING IS + BEGIN + IF (bit = 1) THEN + RETURN "1"; + ELSE + RETURN "0"; + END IF; + END int_to_str_1bit; + +------------------------------------------------------------------------------- +-- Convert binary integer (0 or 1) into std_logic ('0' or '1') +------------------------------------------------------------------------------- + FUNCTION bint_2_sl (X : INTEGER) RETURN STD_LOGIC IS + BEGIN + IF (X = 0) THEN + RETURN '0'; + ELSE + RETURN '1'; + END IF; + END bint_2_sl; + +------------------------------------------------------------------------------- +-- Calculate the SINIT value for the inferred BRAM using the generics: +-- C_SINIT_DOUT, C_SINIT_KOUT, and C_SINIT_RUN_DISP +------------------------------------------------------------------------------- + FUNCTION concat_sinit( + integer_run_disp : INTEGER; + integer_kout : INTEGER; + string_dout : STRING) + RETURN STRING IS + VARIABLE tmp_sym_disp : STRING(1 TO 2); + CONSTANT TMP_CODE_ERR : STRING(1 TO 1) := "0"; + CONSTANT TMP_KOUT_0 : STRING(1 TO 1) := "0"; + CONSTANT TMP_KOUT_1 : STRING(1 TO 1) := "1"; + VARIABLE tmp_str : STRING(1 TO 14); + BEGIN + IF (integer_run_disp = 1) THEN + tmp_sym_disp := CONST_POS; -- D0.0+ has sym_disp of pos + ELSE + tmp_sym_disp := CONST_NEG; -- D0.0- has sym_disp of neg + END IF; + IF (integer_kout = 1) THEN + tmp_str := tmp_sym_disp & tmp_sym_disp & TMP_CODE_ERR & + TMP_KOUT_1 & string_dout; + ELSE + tmp_str := tmp_sym_disp & tmp_sym_disp & TMP_CODE_ERR & + TMP_KOUT_0 & string_dout; + END IF; + RETURN tmp_str; + END concat_sinit; + +----------------------------------------------------------------------------- +-- Convert a string containing 1's and 0's into a std_logic_vector of +-- width nbits +----------------------------------------------------------------------------- + FUNCTION str_to_slv( + bitsin : STRING; + nbits : INTEGER) + RETURN STD_LOGIC_VECTOR IS + VARIABLE ret : STD_LOGIC_VECTOR(bitsin'range); + VARIABLE ret0s : STD_LOGIC_VECTOR(1 TO nbits) := (OTHERS => '0'); + VARIABLE retpadded : STD_LOGIC_VECTOR(1 TO nbits) := (OTHERS => '0'); + VARIABLE offset : INTEGER := 0; + BEGIN + IF(bitsin'length = 0) THEN -- Make all '0's + RETURN ret0s; + END IF; + IF(bitsin'length < nbits) THEN -- pad MSBs with '0's + offset := nbits - bitsin'length; + FOR i IN bitsin'range LOOP + IF bitsin(i) = '1' THEN + retpadded(i+offset) := '1'; + ELSIF (bitsin(i) = 'X' OR bitsin(i) = 'x') THEN + retpadded(i+offset) := 'X'; + ELSIF (bitsin(i) = 'Z' OR bitsin(i) = 'z') THEN + retpadded(i+offset) := 'Z'; + ELSIF (bitsin(i) = '0') THEN + retpadded(i+offset) := '0'; + END IF; + END LOOP; + retpadded(1 TO offset) := (OTHERS => '0'); + RETURN retpadded; + END IF; + FOR i IN bitsin'range LOOP + IF bitsin(i) = '1' THEN + ret(i) := '1'; + ELSIF (bitsin(i) = 'X' OR bitsin(i) = 'x') THEN + ret(i) := 'X'; + ELSIF (bitsin(i) = 'Z' OR bitsin(i) = 'z') THEN + ret(i) := 'Z'; + ELSIF (bitsin(i) = '0') THEN + ret(i) := '0'; + END IF; + END LOOP; + + RETURN ret; + END str_to_slv; + +----------------------------------------------------------------------------- +-- Translate the SINIT string value from the core wrapper to +-- C_SINIT_RUN_DISP +----------------------------------------------------------------------------- + FUNCTION calc_init_val_rd (SINIT_VAL : STRING(10 DOWNTO 1)) RETURN INTEGER IS + VARIABLE tmp_init_val : INTEGER; + BEGIN + CASE SINIT_VAL IS + WHEN "0000000001" => tmp_init_val := 1; --D.0.0 (pos) + WHEN "0000000000" => tmp_init_val := 0; --D.0.0 (neg) + WHEN "0100101001" => tmp_init_val := 1; --D.10.2 (pos) + WHEN "0100101000" => tmp_init_val := 0; --D.10.2 (neg) + WHEN "1011010101" => tmp_init_val := 1; --D.21.5 (pos) + WHEN "1011010100" => tmp_init_val := 0; --D.21.5 (neg) + WHEN OTHERS => tmp_init_val := 0; --invalid init value + END CASE; + RETURN tmp_init_val; + END calc_init_val_rd; + +----------------------------------------------------------------------------- +-- If C_HAS_BPORTS = 1, then the optional B ports are configured the +-- same as the optional A ports +-- If C_HAS_BPORTS = 0, then the optional B ports are disabled (= 0) +----------------------------------------------------------------------------- + FUNCTION has_bport ( + C_HAS_BPORTS : INTEGER; + has_aport : INTEGER) + RETURN INTEGER IS + VARIABLE has_bport : INTEGER; + BEGIN + IF (C_HAS_BPORTS = 1) THEN + has_bport := has_aport; + ELSE + has_bport := 0; + END IF; + RETURN has_bport; + END has_bport; + +END decode_8b10b_pkg; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_rtl.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_rtl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..89e5be8d2e7b314382956f3b652df2a799e4d1c5 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_rtl.vhd @@ -0,0 +1,565 @@ +--------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_rtl.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : Top-level, synthesizable 8b/10b decoder core file +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.std_logic_arith.ALL; + +LIBRARY decode_8b10b; +USE work.decode_8b10b_pkg.ALL; + +----------------------------------------------------------------------------- +-- Entity Declaration +----------------------------------------------------------------------------- +ENTITY decode_8b10b_rtl IS + GENERIC ( + C_DECODE_TYPE : INTEGER := 0; + C_ELABORATION_DIR : STRING := "./"; + C_HAS_BPORTS : INTEGER := 0; + C_HAS_CE : INTEGER := 0; + C_HAS_CE_B : INTEGER := 0; + C_HAS_CODE_ERR : INTEGER := 0; + C_HAS_CODE_ERR_B : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_DISP_ERR_B : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_DISP_IN_B : INTEGER := 0; + C_HAS_ND : INTEGER := 0; + C_HAS_ND_B : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_HAS_RUN_DISP_B : INTEGER := 0; + C_HAS_SINIT : INTEGER := 0; + C_HAS_SINIT_B : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0; + C_HAS_SYM_DISP_B : INTEGER := 0; + C_SINIT_DOUT : STRING := "00000000"; + C_SINIT_DOUT_B : STRING := "00000000"; + C_SINIT_KOUT : INTEGER := 0; + C_SINIT_KOUT_B : INTEGER := 0; + C_SINIT_RUN_DISP : INTEGER := 0; + C_SINIT_RUN_DISP_B : INTEGER := 0 + ); + PORT ( + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + CE_B : IN STD_LOGIC := '0'; + CLK_B : IN STD_LOGIC := '0'; + DIN_B : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DISP_IN : IN STD_LOGIC := '0'; + DISP_IN_B : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + SINIT_B : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + CODE_ERR_B : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + DISP_ERR_B : OUT STD_LOGIC := '0'; + DOUT_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT_B : OUT STD_LOGIC ; + ND : OUT STD_LOGIC := '0'; + ND_B : OUT STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC ; + RUN_DISP_B : OUT STD_LOGIC ; + SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ; + SYM_DISP_B : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) + ); +END decode_8b10b_rtl; + +-------------------------------------------------------------------------------- +-- Generic Definitions: +-------------------------------------------------------------------------------- + -- C_DECODE_TYPE : Implementation: 0=Slice based, 1=BlockRam + -- C_ELABORATION_DIR : Directory path for mif file + -- C_HAS_BPORTS : 1 indicates second decoder should be generated + -- C_HAS_CE : 1 indicates ce port is present + -- C_HAS_CE_B : 1 indicates ce_b port is present (if c_has_bports=1) + -- C_HAS_CODE_ERR : 1 indicates code_err port is present + -- C_HAS_CODE_ERR_B : 1 indicates code_err_b port is present + -- (if c_has_bports=1) + -- C_HAS_DISP_ERR : 1 indicates disp_err port is present + -- C_HAS_DISP_ERR_B : 1 indicates disp_err_b port is present + -- (if c_has_bports=1) + -- C_HAS_DISP_IN : 1 indicates disp_in port is present + -- C_HAS_DISP_IN_B : 1 indicates disp_in_b port is present + -- (if c_has_bports=1) + -- C_HAS_ND : 1 indicates nd port is present + -- C_HAS_ND_B : 1 indicates nd_b port is present (if c_has_bports=1) + -- C_HAS_RUN_DISP : 1 indicates run_disp port is present + -- C_HAS_RUN_DISP_B : 1 indicates run_disp_b port is present + -- (if c_has_bports=1) + -- C_HAS_SINIT : 1 indicates sinit port is present + -- C_HAS_SINIT_B : 1 indicates sinit_b port is present + -- (if c_has_bports=1) + -- C_HAS_SYM_DISP : 1 indicates sym_disp port is present + -- C_HAS_SYM_DISP_B : 1 indicates sym_disp_b port is present + -- (if c_has_bports=1) + -- C_SINIT_DOUT : 8-bit binary string, dout value when sinit is active + -- C_SINIT_DOUT_B : 8-bit binary string, dout_b value when sinit_b is + -- active + -- C_SINIT_KOUT : controls kout output when sinit is active + -- C_SINIT_KOUT_B : controls kout_b output when sinit_b is active + -- C_SINIT_RUN_DISP : Initializes run_disp (and disp_in) value to + -- positive(1) or negative(0) + -- C_SINIT_RUN_DISP_B : Initializes run_disp_b (and disp_in_b) value to + -- positive(1) or negative(0) +-------------------------------------------------------------------------------- +-- Port Definitions: +-------------------------------------------------------------------------------- + -- Mandatory Pins + -- CLK : Clock Input + -- DIN : Encoded Symbol Input + -- DOUT : Data Output, decoded data byte + -- KOUT : Command Output + ------------------------------------------------------------------------- + -- Optional Pins + -- CE : Clock Enable + -- CE_B : Clock Enable (B port) + -- CLK_B : Clock Input (B port) + -- DIN_B : Encoded Symbol Input (B port) + -- DISP_IN : Disparity Input (running disparity in) + -- DISP_IN_B : Disparity Input (running disparity in) (B port) + -- SINIT : Synchronous Initialization. Resets core to known state. + -- SINIT_B : Synchronous Initialization. Resets core to known state. + -- (B port) + -- CODE_ERR : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. + -- CODE_ERR_B : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. (B port) + -- DISP_ERR : Disparity Error + -- DISP_ERR_B : Disparity Error (B port) + -- DOUT_B : Data Output, decoded data byte (B port) + -- KOUT_B : Command Output (B port) + -- ND : New Data + -- ND_B : New Data (B port) + -- RUN_DISP : Running Disparity + -- RUN_DISP_B : Running Disparity (B port) + -- SYM_DISP : Symbol Disparity + -- SYM_DISP_B : Symbol Disparity (B port) + ------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +-- Architecture +------------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_rtl IS + +------------------------------------------------------------------------------- +-- Signal Declarations +------------------------------------------------------------------------------- + SIGNAL dout_i : STD_LOGIC_VECTOR(7 DOWNTO 0) := + str_to_slv(C_SINIT_DOUT,8); + --convert C_SINIT_DOUT string to 8bit std_logic_vector + SIGNAL kout_i : STD_LOGIC := + bint_2_sl(C_SINIT_KOUT); + --convert C_SINIT_KOUT integer to std_logic + SIGNAL clk_b_i : STD_LOGIC := '0'; + SIGNAL din_b_i : STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + SIGNAL ce_i : STD_LOGIC := '0'; + SIGNAL ce_b_i : STD_LOGIC := '0'; + SIGNAL disp_in_i : STD_LOGIC := '0'; + SIGNAL disp_in_b_i : STD_LOGIC := '0'; + SIGNAL sinit_i : STD_LOGIC := '0'; + SIGNAL sinit_b_i : STD_LOGIC := '0'; + SIGNAL code_err_i : STD_LOGIC := '0'; + SIGNAL code_err_b_i : STD_LOGIC := '0'; + SIGNAL disp_err_i : STD_LOGIC := '0'; + SIGNAL disp_err_b_i : STD_LOGIC := '0'; + SIGNAL dout_b_i : STD_LOGIC_VECTOR(7 DOWNTO 0) := + str_to_slv(C_SINIT_DOUT_B,8); + --convert C_SINIT_DOUT_B string to 8bit std_logic_vector + SIGNAL kout_b_i : STD_LOGIC := + bint_2_sl(C_SINIT_KOUT_B); + --convert C_SINIT_KOUT_B integer to std_logic + SIGNAL nd_i : STD_LOGIC := '0'; + SIGNAL nd_b_i : STD_LOGIC := '0'; + SIGNAL run_disp_i : STD_LOGIC := + bint_2_sl(C_SINIT_RUN_DISP); + --convert C_SINIT_RUN_DISP integer to std logic + SIGNAL run_disp_b_i : STD_LOGIC := + bint_2_sl(C_SINIT_RUN_DISP_B); + --convert C_SINIT_RUN_DISP_B integer to std logic + SIGNAL sym_disp_i : STD_LOGIC_VECTOR(1 DOWNTO 0) := + conv_std_logic_vector(C_SINIT_RUN_DISP,2); + --convert C_SINIT_RUN_DISP integer to slv + SIGNAL sym_disp_b_i : STD_LOGIC_VECTOR(1 DOWNTO 0) := + conv_std_logic_vector(C_SINIT_RUN_DISP_B,2); + --convert C_SINIT_RUN_DISP_B integer to slv + +------------------------------------------------------------------------------- +-- Begin Architecture +------------------------------------------------------------------------------- +BEGIN + + ----------------------------------------------------------------------------- + -- LUT-based decoder + ----------------------------------------------------------------------------- + glut : IF (C_DECODE_TYPE = 0) GENERATE + ldec : ENTITY decode_8b10b_lut + GENERIC MAP ( + C_HAS_BPORTS => C_HAS_BPORTS, + C_HAS_CODE_ERR => C_HAS_CODE_ERR, + C_HAS_CODE_ERR_B => C_HAS_CODE_ERR_B, + C_HAS_DISP_ERR => C_HAS_DISP_ERR, + C_HAS_DISP_ERR_B => C_HAS_DISP_ERR_B, + C_HAS_DISP_IN => C_HAS_DISP_IN, + C_HAS_DISP_IN_B => C_HAS_DISP_IN_B, + C_HAS_ND => C_HAS_ND, + C_HAS_ND_B => C_HAS_ND_B, + C_HAS_SYM_DISP => C_HAS_SYM_DISP, + C_HAS_SYM_DISP_B => C_HAS_SYM_DISP_B, + C_HAS_RUN_DISP => C_HAS_RUN_DISP, + C_HAS_RUN_DISP_B => C_HAS_RUN_DISP_B, + C_SINIT_DOUT => C_SINIT_DOUT, + C_SINIT_DOUT_B => C_SINIT_DOUT_B, + C_SINIT_KOUT => C_SINIT_KOUT, + C_SINIT_KOUT_B => C_SINIT_KOUT_B, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP, + C_SINIT_RUN_DISP_B => C_SINIT_RUN_DISP_B + ) + PORT MAP( + CLK => CLK, + DIN => DIN, + DOUT => dout_i, + KOUT => kout_i, + + CE => ce_i, + DISP_IN => disp_in_i, + SINIT => sinit_i, + CODE_ERR => code_err_i, + DISP_ERR => disp_err_i, + ND => nd_i, + RUN_DISP => run_disp_i, + SYM_DISP => sym_disp_i, + + CLK_B => clk_b_i, + DIN_B => din_b_i, + DOUT_B => dout_b_i, + KOUT_B => kout_b_i, + + CE_B => ce_b_i, + DISP_IN_B => disp_in_b_i, + SINIT_B => sinit_b_i, + CODE_ERR_B => code_err_b_i, + DISP_ERR_B => disp_err_b_i, + ND_B => nd_b_i, + RUN_DISP_B => run_disp_b_i, + SYM_DISP_B => sym_disp_b_i + ); + END GENERATE glut; + + ----------------------------------------------------------------------------- + -- BRAM-based decoder + ----------------------------------------------------------------------------- + gbram : IF (C_DECODE_TYPE /= 0) GENERATE + bdec : ENTITY decode_8b10b_bram + GENERIC MAP ( + C_ELABORATION_DIR => C_ELABORATION_DIR, + C_HAS_BPORTS => C_HAS_BPORTS, + C_HAS_DISP_IN => C_HAS_DISP_IN, + C_HAS_DISP_IN_B => C_HAS_DISP_IN_B, + C_HAS_DISP_ERR => C_HAS_DISP_ERR, + C_HAS_DISP_ERR_B => C_HAS_DISP_ERR_B, + C_HAS_RUN_DISP => C_HAS_RUN_DISP, + C_HAS_RUN_DISP_B => C_HAS_RUN_DISP_B, + C_HAS_SYM_DISP => C_HAS_SYM_DISP, + C_HAS_SYM_DISP_B => C_HAS_SYM_DISP_B, + C_HAS_ND => C_HAS_ND, + C_HAS_ND_B => C_HAS_ND_B, + C_SINIT_DOUT => C_SINIT_DOUT, + C_SINIT_DOUT_B => C_SINIT_DOUT_B, + C_SINIT_KOUT => C_SINIT_KOUT, + C_SINIT_KOUT_B => C_SINIT_KOUT_B, + C_SINIT_RUN_DISP => C_SINIT_RUN_DISP, + C_SINIT_RUN_DISP_B => C_SINIT_RUN_DISP_B + ) + + PORT MAP( + CLK => CLK, + DIN => DIN, + DOUT => dout_i, + KOUT => kout_i, + + CE => ce_i, + DISP_IN => disp_in_i, + SINIT => sinit_i, + CODE_ERR => code_err_i, + DISP_ERR => disp_err_i, + ND => nd_i, + RUN_DISP => run_disp_i, + SYM_DISP => sym_disp_i, + + CLK_B => clk_b_i, + DIN_B => din_b_i, + DOUT_B => dout_b_i, + KOUT_B => kout_b_i, + + CE_B => ce_b_i, + DISP_IN_B => disp_in_b_i, + SINIT_B => sinit_b_i, + CODE_ERR_B => code_err_b_i, + DISP_ERR_B => disp_err_b_i, + ND_B => nd_b_i, + RUN_DISP_B => run_disp_b_i, + SYM_DISP_B => sym_disp_b_i + ); + END GENERATE gbram; + + + --------------------------------------------------------------------------- + -- Mandatory A Ports + --------------------------------------------------------------------------- + DOUT <= dout_i; + KOUT <= kout_i; + + --------------------------------------------------------------------------- + -- Optional A Ports --tying off unused ports + --------------------------------------------------------------------------- + --Inputs + --ce + gen : IF (C_HAS_CE/=0) GENERATE + ce_i <= CE; + END GENERATE gen; + ngen : IF (C_HAS_CE = 0) GENERATE + ce_i <= '1'; + END GENERATE ngen; + + --disp_in + gdi : IF (C_HAS_DISP_IN /= 0) GENERATE + disp_in_i <= DISP_IN; + END GENERATE gdi; + ngdi : IF (C_HAS_DISP_IN = 0) GENERATE + disp_in_i <= '0'; + END GENERATE ngdi; + + --sinit + gs : IF (C_HAS_SINIT /= 0) GENERATE + sinit_i <= SINIT; + END GENERATE gs; + ngs : IF (C_HAS_SINIT = 0) GENERATE + sinit_i <= '0'; + END GENERATE ngs; + + + --Outputs + --nd + gnd : IF (C_HAS_ND /= 0) GENERATE + ASSERT (C_HAS_CE /= 0) + REPORT "Invalid configuration: ND port requires CE port" + SEVERITY WARNING; + ND <= nd_i; + END GENERATE gnd; + ngnd : IF (C_HAS_ND = 0) GENERATE + ND <= '0'; + END GENERATE ngnd; + + --code_err + gce : IF (C_HAS_CODE_ERR /= 0) GENERATE + CODE_ERR <= code_err_i; + END GENERATE gce; + ngce : IF (C_HAS_CODE_ERR = 0) GENERATE + CODE_ERR <= '0'; + END GENERATE ngce; + + --disp_err + gder : IF (C_HAS_DISP_ERR /= 0) GENERATE + DISP_ERR <= disp_err_i; + END GENERATE gder; + ngder : IF (C_HAS_DISP_ERR = 0) GENERATE + DISP_ERR <= '0'; + END GENERATE ngder; + + --run_disp + grd : IF (C_HAS_RUN_DISP /= 0) GENERATE + RUN_DISP <= run_disp_i; + END GENERATE grd; + ngrd : IF (C_HAS_RUN_DISP = 0) GENERATE + RUN_DISP <= '0'; + END GENERATE ngrd; + + --sym_disp + gsd : IF (C_HAS_SYM_DISP /= 0) GENERATE + SYM_DISP <= sym_disp_i; + END GENERATE gsd; + ngsd : IF (C_HAS_SYM_DISP = 0) GENERATE + SYM_DISP <= "00"; + END GENERATE ngsd; + + ---------------------------------------------------------------------------- + -- Optional B Ports -- tying off unused ports + ---------------------------------------------------------------------------- + --Mandatory B ports (if B ports are selected) + gbpt : IF (C_HAS_BPORTS /= 0) GENERATE + din_b_i <= DIN_B; + clk_b_i <= CLK_B; + DOUT_B <= dout_b_i; + KOUT_B <= kout_b_i; + END GENERATE gbpt; + ngbpt : IF (C_HAS_BPORTS = 0) GENERATE + din_b_i <= (OTHERS => '0'); + clk_b_i <= '0'; + DOUT_B <= (OTHERS => '0'); + KOUT_B <= '0'; + END GENERATE ngbpt; + + --Inputs + --ce_b + genb : IF (C_HAS_CE_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + ce_b_i <= CE_B; + END GENERATE genb; + ngenb : IF (C_HAS_CE_B = 0 OR C_HAS_BPORTS = 0) GENERATE + ce_b_i <= '1'; + END GENERATE ngenb; + ASSERT (NOT(C_HAS_CE_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate CE_B when C_HAS_BPORTS=0" + SEVERITY WARNING; + + --disp_in_b + gdib : IF (C_HAS_DISP_IN_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + disp_in_b_i <= DISP_IN_B; + END GENERATE gdib; + ngdib : IF (C_HAS_DISP_IN_B = 0 OR C_HAS_BPORTS = 0) GENERATE + disp_in_b_i <= '0'; + END GENERATE ngdib; + ASSERT (NOT(C_HAS_DISP_IN_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate DISP_IN_B when " & + "C_HAS_BPORTS=0" + SEVERITY WARNING; + + --sinit_b + gsb : IF (C_HAS_SINIT_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + sinit_b_i <= SINIT_B; + END GENERATE gsb; + ngsb : IF (C_HAS_SINIT_B = 0 OR C_HAS_BPORTS = 0) GENERATE + sinit_b_i <= '0'; + END GENERATE ngsb; + ASSERT (NOT(C_HAS_SINIT_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate SINIT_B when C_HAS_BPORTS=0" + SEVERITY WARNING; + + --Outputs + --code_err_b + gceb : IF (C_HAS_CODE_ERR_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + CODE_ERR_B <= code_err_b_i; + END GENERATE gceb; + ngceb : IF (C_HAS_CODE_ERR_B = 0 OR C_HAS_BPORTS = 0) GENERATE + CODE_ERR_B <= '0'; + END GENERATE ngceb; + ASSERT (NOT(C_HAS_CODE_ERR_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate CODE_ERR_B when " & + "C_HAS_BPORTS=0" + SEVERITY WARNING; + + --disp_err_b + gdeb : IF (C_HAS_DISP_ERR_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + DISP_ERR_B <= disp_err_b_i; + END GENERATE gdeb; + ngdeb : IF (C_HAS_DISP_ERR_B = 0 OR C_HAS_BPORTS = 0) GENERATE + DISP_ERR_B <= '0'; + END GENERATE ngdeb; + ASSERT (NOT(C_HAS_DISP_ERR_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate DISP_ERR_B when " & + "C_HAS_BPORTS=0" + SEVERITY WARNING; + + --nd_b + gndb : IF (C_HAS_ND_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + ASSERT (C_HAS_CE_B /= 0) + REPORT "Invalid configuration: ND_B port requires CE_B port" + SEVERITY WARNING; + ND_B <= nd_b_i; + END GENERATE gndb; + ngndb : IF (C_HAS_ND_B = 0 OR C_HAS_BPORTS = 0) GENERATE + ND_B <= '0'; + END GENERATE ngndb; + ASSERT (NOT(C_HAS_ND_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate ND_B when C_HAS_BPORTS=0" + SEVERITY WARNING; + + --run_disp_b + grdb : IF (C_HAS_RUN_DISP_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + RUN_DISP_B <= run_disp_b_i; + END GENERATE grdb; + ngrdb : IF (C_HAS_RUN_DISP_B = 0 OR C_HAS_BPORTS = 0) GENERATE + RUN_DISP_B <= '0'; + END GENERATE ngrdb; + ASSERT (NOT(C_HAS_RUN_DISP_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate RUN_DISP_B when " & + "C_HAS_BPORTS=0" + SEVERITY WARNING; + + --sym_disp_b + gsdb : IF (C_HAS_SYM_DISP_B /= 0 AND C_HAS_BPORTS /= 0) GENERATE + SYM_DISP_B <= sym_disp_b_i; + END GENERATE gsdb; + ngsdb : IF (C_HAS_SYM_DISP_B = 0 OR C_HAS_BPORTS = 0) GENERATE + SYM_DISP_B <= "00"; + END GENERATE ngsdb; + ASSERT (NOT(C_HAS_SYM_DISP_B /= 0 AND C_HAS_BPORTS = 0)) + REPORT "Invalid configuration: Will not generate SYM_DISP_B when " & + "C_HAS_BPORTS=0" + SEVERITY WARNING; + +END xilinx; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_top.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_top.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b9f4d238658d4fa7aea7be99bfba7f9e6e742e2c --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_top.vhd @@ -0,0 +1,280 @@ +------------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_top.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder Reference Design +-- +-- Description : Core wrapper file +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008 Xilinx, Inc. +-- All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + + +LIBRARY decode_8b10b; +USE work.decode_8b10b_pkg.ALL; + +------------------------------------------------------------------------------- +-- Entity Declaration +------------------------------------------------------------------------------- +ENTITY decode_8b10b_top IS + GENERIC ( + C_DECODE_TYPE : INTEGER := 0; + C_HAS_BPORTS : INTEGER := 0; + C_HAS_CE : INTEGER := 0; + C_HAS_CODE_ERR : INTEGER := 0; + C_HAS_DISP_ERR : INTEGER := 0; + C_HAS_DISP_IN : INTEGER := 0; + C_HAS_ND : INTEGER := 0; + C_HAS_RUN_DISP : INTEGER := 0; + C_HAS_SINIT : INTEGER := 0; + C_HAS_SYM_DISP : INTEGER := 0; + C_SINIT_VAL : STRING(1 TO 10) := "0000000000"; + C_SINIT_VAL_B : STRING(1 TO 10) := "0000000000" + ); + + PORT ( + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + CE_B : IN STD_LOGIC := '0'; + CLK_B : IN STD_LOGIC := '0'; + DIN_B : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DISP_IN : IN STD_LOGIC := '0'; + DISP_IN_B : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + SINIT_B : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + CODE_ERR_B : OUT STD_LOGIC := '0'; + DISP_ERR : OUT STD_LOGIC := '0'; + DISP_ERR_B : OUT STD_LOGIC := '0'; + DOUT_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT_B : OUT STD_LOGIC ; + ND : OUT STD_LOGIC := '0'; + ND_B : OUT STD_LOGIC := '0'; + RUN_DISP : OUT STD_LOGIC ; + RUN_DISP_B : OUT STD_LOGIC ; + SYM_DISP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ; + SYM_DISP_B : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) + ); +-------------------------------------------------------------------------------- +-- Port Definitions: +-------------------------------------------------------------------------------- + -- Mandatory Pins + -- CLK : Clock Input + -- DIN : Encoded Symbol Input + -- DOUT : Data Output, decoded data byte + -- KOUT : Command Output + ------------------------------------------------------------------------- + -- Optional Pins + -- CE : Clock Enable + -- CE_B : Clock Enable (B port) + -- CLK_B : Clock Input (B port) + -- DIN_B : Encoded Symbol Input (B port) + -- DISP_IN : Disparity Input (running disparity in) + -- DISP_IN_B : Disparity Input (running disparity in) (B port) + -- SINIT : Synchronous Initialization. Resets core to known state. + -- SINIT_B : Synchronous Initialization. Resets core to known state. + -- (B port) + -- CODE_ERR : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. + -- CODE_ERR_B : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. (B port) + -- DISP_ERR : Disparity Error + -- DISP_ERR_B : Disparity Error (B port) + -- DOUT_B : Data Output, decoded data byte (B port) + -- KOUT_B : Command Output (B port) + -- ND : New Data + -- ND_B : New Data (B port) + -- RUN_DISP : Running Disparity + -- RUN_DISP_B : Running Disparity (B port) + -- SYM_DISP : Symbol Disparity + -- SYM_DISP_B : Symbol Disparity (B port) + ------------------------------------------------------------------------- +END decode_8b10b_top; + + +------------------------------------------------------------------------------- +-- Architecture +------------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_top IS + +CONSTANT SINIT_DOUT : STRING(1 TO 8) := C_SINIT_VAL(1 TO 8); +CONSTANT SINIT_DOUT_B : STRING(1 TO 8) := C_SINIT_VAL_B(1 TO 8); +CONSTANT SINIT_RD : INTEGER := calc_init_val_rd(C_SINIT_VAL); + -- converts C_SINIT_VAL string to integer +CONSTANT SINIT_RD_B : INTEGER := calc_init_val_rd(C_SINIT_VAL_B); + -- converts C_SINIT_VAL_B string to integer + +-- If C_HAS_BPORTS=1, the optional B ports are configured the same way as the +-- optional A ports. Otherwise, all the B ports are disabled. +CONSTANT C_HAS_CE_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_CE); +CONSTANT C_HAS_CODE_ERR_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_CODE_ERR); +CONSTANT C_HAS_DISP_ERR_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_DISP_ERR); +CONSTANT C_HAS_DISP_IN_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_DISP_IN); +CONSTANT C_HAS_ND_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_ND); +CONSTANT C_HAS_RUN_DISP_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_RUN_DISP); +CONSTANT C_HAS_SINIT_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_SINIT); +CONSTANT C_HAS_SYM_DISP_B : INTEGER := has_bport(C_HAS_BPORTS, C_HAS_SYM_DISP); + +------------------------------------------------------------------------------- +-- BEGIN ARCHITECTURE +------------------------------------------------------------------------------- +BEGIN + +dec : ENTITY decode_8b10b_rtl + GENERIC MAP ( + C_DECODE_TYPE => C_DECODE_TYPE, + C_ELABORATION_DIR => "./", + C_HAS_BPORTS => C_HAS_BPORTS, + C_HAS_CE => C_HAS_CE, + C_HAS_CE_B => C_HAS_CE_B, + C_HAS_CODE_ERR => C_HAS_CODE_ERR, + C_HAS_CODE_ERR_B => C_HAS_CODE_ERR_B, + C_HAS_DISP_ERR => C_HAS_DISP_ERR, + C_HAS_DISP_ERR_B => C_HAS_DISP_ERR_B, + C_HAS_DISP_IN => C_HAS_DISP_IN, + C_HAS_DISP_IN_B => C_HAS_DISP_IN_B, + C_HAS_ND => C_HAS_ND, + C_HAS_ND_B => C_HAS_ND_B, + C_HAS_RUN_DISP => C_HAS_RUN_DISP, + C_HAS_RUN_DISP_B => C_HAS_RUN_DISP_B, + C_HAS_SINIT => C_HAS_SINIT, + C_HAS_SINIT_B => C_HAS_SINIT_B, + C_HAS_SYM_DISP => C_HAS_SYM_DISP, + C_HAS_SYM_DISP_B => C_HAS_SYM_DISP_B, + C_SINIT_DOUT => SINIT_DOUT, + C_SINIT_DOUT_B => SINIT_DOUT_B, + C_SINIT_KOUT => 0, + C_SINIT_KOUT_B => 0, + C_SINIT_RUN_DISP => SINIT_RD, + C_SINIT_RUN_DISP_B => SINIT_RD_B + ) + PORT MAP( + CLK => CLK, + DIN => DIN, + DOUT => DOUT, + KOUT => KOUT, + CE => CE, + CE_B => CE_B, + CLK_B => CLK_B, + DIN_B => DIN_B, + DISP_IN => DISP_IN, + DISP_IN_B => DISP_IN_B, + SINIT => SINIT, + SINIT_B => SINIT_B, + CODE_ERR => CODE_ERR, + CODE_ERR_B => CODE_ERR_B, + DISP_ERR => DISP_ERR, + DISP_ERR_B => DISP_ERR_B, + DOUT_B => DOUT_B, + KOUT_B => KOUT_B, + ND => ND, + ND_B => ND_B, + RUN_DISP => RUN_DISP, + RUN_DISP_B => RUN_DISP_B, + SYM_DISP => SYM_DISP, + SYM_DISP_B => SYM_DISP_B + ); +-------------------------------------------------------------------------------- +-- Generic Definitions: +-------------------------------------------------------------------------------- + -- C_DECODE_TYPE : Implementation: 0=Slice based, 1=BlockRam + -- C_ELABORATION_DIR : Directory path for mif file + -- C_HAS_BPORTS : 1 indicates second decoder should be generated + -- C_HAS_CE : 1 indicates ce port is present + -- C_HAS_CE_B : 1 indicates ce_b port is present (if c_has_bports=1) + -- C_HAS_CODE_ERR : 1 indicates code_err port is present + -- C_HAS_CODE_ERR_B : 1 indicates code_err_b port is present + -- (if c_has_bports=1) + -- C_HAS_DISP_ERR : 1 indicates disp_err port is present + -- C_HAS_DISP_ERR_B : 1 indicates disp_err_b port is present + -- (if c_has_bports=1) + -- C_HAS_DISP_IN : 1 indicates disp_in port is present + -- C_HAS_DISP_IN_B : 1 indicates disp_in_b port is present + -- (if c_has_bports=1) + -- C_HAS_ND : 1 indicates nd port is present + -- C_HAS_ND_B : 1 indicates nd_b port is present (if c_has_bports=1) + -- C_HAS_RUN_DISP : 1 indicates run_disp port is present + -- C_HAS_RUN_DISP_B : 1 indicates run_disp_b port is present + -- (if c_has_bports=1) + -- C_HAS_SINIT : 1 indicates sinit port is present + -- C_HAS_SINIT_B : 1 indicates sinit_b port is present + -- (if c_has_bports=1) + -- C_HAS_SYM_DISP : 1 indicates sym_disp port is present + -- C_HAS_SYM_DISP_B : 1 indicates sym_disp_b port is present + -- (if c_has_bports=1) + -- C_SINIT_DOUT : 8-bit binary string, dout value when sinit is active + -- C_SINIT_DOUT_B : 8-bit binary string, dout_b value when sinit_b is + -- active + -- C_SINIT_KOUT : controls kout output when sinit is active + -- C_SINIT_KOUT_B : controls kout_b output when sinit_b is active + -- C_SINIT_RUN_DISP : Initializes run_disp (and disp_in) value to + -- positive(1) or negative(0) + -- C_SINIT_RUN_DISP_B : Initializes run_disp_b (and disp_in_b) value to + -- positive(1) or negative(0) +-------------------------------------------------------------------------------- + + +END xilinx; + + + + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_wrapper.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_wrapper.vhd new file mode 100644 index 0000000000000000000000000000000000000000..50e45f9b12613ffaafbda2a7b1c2ba41593e8654 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decode_8b10b_wrapper.vhd @@ -0,0 +1,215 @@ +------------------------------------------------------------------------------- +-- +-- Module : decode_8b10b_wrapper.vhd +-- +-- Version : 1.1 +-- +-- Last Update : 2008-10-31 +-- +-- Project : 8b/10b Decoder +-- +-- Description : Top-level core wrapper file +-- +-- Company : Xilinx, Inc. +-- +-- DISCLAIMER OF LIABILITY +-- +-- This file contains proprietary and confidential information of +-- Xilinx, Inc. ("Xilinx"), that is distributed under a license +-- from Xilinx, and may be used, copied and/or disclosed only +-- pursuant to the terms of a valid license agreement with Xilinx. +-- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION +-- ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +-- EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT +-- LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, +-- MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx +-- does not warrant that functions included in the Materials will +-- meet the requirements of Licensee, or that the operation of the +-- Materials will be uninterrupted or error-free, or that defects +-- in the Materials will be corrected. Furthermore, Xilinx does +-- not warrant or make any representations regarding use, or the +-- results of the use, of the Materials in terms of correctness, +-- accuracy, reliability or otherwise. +-- +-- Xilinx products are not designed or intended to be fail-safe, +-- or for use in any application requiring fail-safe performance, +-- such as life-support or safety devices or systems, Class III +-- medical devices, nuclear facilities, applications related to +-- the deployment of airbags, or any other applications that could +-- lead to death, personal injury or severe property or +-- environmental damage (individually and collectively, "critical +-- applications"). Customer assumes the sole risk and liability +-- of any use of Xilinx products in critical applications, +-- subject only to applicable laws and regulations governing +-- limitations on product liability. +-- +-- Copyright 2008 Xilinx, Inc. All rights reserved. +-- +-- This disclaimer and copyright notice must be retained as part +-- of this file at all times. +-- +------------------------------------------------------------------------------- +-- +-- History +-- +-- Date Version Description +-- +-- 10/31/2008 1.1 Initial release +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + + +LIBRARY decode_8b10b; + +------------------------------------------------------------------------------- +-- Entity Declaration +------------------------------------------------------------------------------- +ENTITY decode_8b10b_wrapper IS + PORT ( + + CLK : IN STD_LOGIC := '0'; + DIN : IN STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + DOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ; + KOUT : OUT STD_LOGIC ; + + CE : IN STD_LOGIC := '0'; + SINIT : IN STD_LOGIC := '0'; + CODE_ERR : OUT STD_LOGIC := '0'; + ND : OUT STD_LOGIC := '0' + + + + ); +-------------------------------------------------------------------------------- +-- Port Definitions: +-------------------------------------------------------------------------------- + -- Mandatory Pins + -- CLK : Clock Input + -- DIN : Encoded Symbol Input + -- DOUT : Data Output, decoded data byte + -- KOUT : Command Output + ------------------------------------------------------------------------- + -- Optional Pins + -- CLK_B : Clock Input (B port) + -- DIN_B : Encoded Symbol Input (B port) + -- DOUT_B : Data Output, decoded data byte (B port) + -- KOUT_B : Command Output (B port) + -- CE : Clock Enable + -- SINIT : Synchronous Initialization. Resets core to known state. + -- DISP_IN : Disparity Input (running disparity in) + -- CODE_ERR : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. + -- DISP_ERR : Disparity Error + -- ND : New Data + -- RUN_DISP : Running Disparity + -- SYM_DISP : Symbol Disparity + -- CE_B : Clock Enable (B port) + -- SINIT_B : Synchronous Initialization. Resets core to known state. + -- (B port) + -- DISP_IN_B : Disparity Input (running disparity in) (B port) + -- CODE_ERR_B : Code Error, indicates that input symbol did not correspond + -- to a valid member of the code set. (B port) + -- DISP_ERR_B : Disparity Error (B port) + -- ND_B : New Data (B port) + -- RUN_DISP_B : Running Disparity (B port) + -- SYM_DISP_B : Symbol Disparity (B port) +---------------------------------------------------------------------------- +END decode_8b10b_wrapper; + +------------------------------------------------------------------------------- +-- Architecture +------------------------------------------------------------------------------- +ARCHITECTURE xilinx OF decode_8b10b_wrapper IS + + CONSTANT LOW : STD_LOGIC := '0'; + CONSTANT HIGH : STD_LOGIC := '1'; + CONSTANT LOWSLV : STD_LOGIC_VECTOR(9 DOWNTO 0) := (OTHERS => '0'); + +------------------------------------------------------------------------------- +-- BEGIN ARCHITECTURE +------------------------------------------------------------------------------- +BEGIN + +dec : ENTITY decode_8b10b_top + GENERIC MAP ( + C_DECODE_TYPE => 1, + C_HAS_BPORTS => 0, + C_HAS_CE => 1, + C_HAS_CODE_ERR => 1, + C_HAS_DISP_ERR => 0, + C_HAS_DISP_IN => 0, + C_HAS_ND => 1, + C_HAS_RUN_DISP => 0, + C_HAS_SINIT => 1, + C_HAS_SYM_DISP => 0, + C_SINIT_VAL => "0000000001", + C_SINIT_VAL_B => "0000000000" + ) + PORT MAP( + CLK => CLK, + DIN => DIN, + DOUT => DOUT, + KOUT => KOUT, + + CE => CE, + SINIT => SINIT, + DISP_IN => LOW, + CODE_ERR => CODE_ERR, + DISP_ERR => open, + ND => ND, + RUN_DISP => open, + SYM_DISP => open, + + CLK_B => LOW, + DIN_B => LOWSLV, + DOUT_B => open, + KOUT_B => open, + + CE_B => HIGH, + SINIT_B => LOW, + DISP_IN_B => LOW, + CODE_ERR_B => open, + DISP_ERR_B => open, + ND_B => open, + RUN_DISP_B => open, + SYM_DISP_B => open + + ); +-------------------------------------------------------------------------------- +-- Generic Definitions: +-------------------------------------------------------------------------------- + -- C_DECODE_TYPE : Implementation: 0=LUT based, 1=BRAM based + -- C_HAS_BPORTS : 1 indicates second decoder should be generated + -- C_HAS_CE : 1 indicates ce(_b) port is present + -- C_HAS_CODE_ERR : 1 indicates code_err(_b) port is present + -- C_HAS_DISP_ERR : 1 indicates disp_err(_b) port is present + -- C_HAS_DISP_IN : 1 indicates disp_in(_b) port is present + -- C_HAS_ND : 1 indicates nd(_b) port is present + -- C_HAS_RUN_DISP : 1 indicates run_disp(_b) port is present + -- C_HAS_SINIT : 1 indicates sinit(_b) port is present + -- C_HAS_SYM_DISP : 1 indicates sym_disp(_b) port is present + -- C_SINIT_VAL : 10-bit binary string, dout/kout/run_disp init value + -- C_SINIT_VAL_B : 10-bit binary string, dout_b/kout_b/run_disp_b init + -- value +-------------------------------------------------------------------------------- + +-------------------------------------------------------- +-- C_SINIT_VAL/C_SINIT_VAL_B {DOUT,KOUT,RD} +-------------------------------------------------------- + -- D.0.0 (pos) DOUT: 000_00000 KOUT: 0 RD: 1 + -- D.0.0 (neg) DOUT: 000_00000 KOUT: 0 RD: 0 + -- D.10.2 (pos) DOUT: 010_01010 KOUT: 0 RD: 1 + -- D.10.2 (neg) DOUT: 010_01010 KOUT: 0 RD: 0 + -- D.21.5 (pos) DOUT: 101_10101 KOUT: 0 RD: 1 + -- D.21.5 (neg) DOUT: 101_10101 KOUT: 0 RD: 0 +-------------------------------------------------------- + + +END xilinx; + + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/decodefei4record.vhd b/rce/fw-hsio/modules/pixelcore/hdl/decodefei4record.vhd new file mode 100644 index 0000000000000000000000000000000000000000..15566863c9c2228feb2ae987bd30dc793091ae98 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/decodefei4record.vhd @@ -0,0 +1,96 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity decodefei4record is +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + isrunning: out std_logic; + d_in: in std_logic_vector(7 downto 0); + k_in: in std_logic; + err_in: in std_logic; + d_out: out std_logic_vector(24 downto 0); + ldin: in std_logic; + ldout: out std_logic; + overflow: out std_logic +-- acounter: out std_logic_vector(15 downto 0) +); +end decodefei4record; + +-------------------------------------------------------------- + +architecture DECODEFEI4RECORD of decodefei4record is + +signal running: std_logic; +signal parity: natural range 0 to 2:=0; +signal wordcount: std_logic_vector(11 downto 0); +signal dint: std_logic_vector(23 downto 0):=(others => '0'); +signal nowrite: std_logic := '0'; + +begin + isrunning<=running; + process(rst, clk) + begin + if(rst='1') then + d_out<=(others => '0'); + running<='0'; + parity<=0; + ldout<='0'; + overflow<='0'; + wordcount<=(others =>'0'); + nowrite<='0'; + elsif (clk'event and clk='1') then + if(ldin='1')then + d_out(23 downto 0)<=dint; + if(running='0')then + if(enabled='1' and d_in=x"fc" and k_in='1')then -- SOF + d_out(24)<='0'; + running<='1'; + parity<=2; + ldout<='0'; + wordcount<=(others =>'0'); + nowrite<='1'; + end if; + else -- running + if(k_in='1' or err_in='1' or wordcount=x"800")then --EOF or idle or error + running<='0'; + if(wordcount=x"800")then + overflow<='1'; + end if; + ldout<='1'; + d_out(24)<='1'; + else-- data + dint(parity*8+7 downto parity*8)<=d_in; + if(parity=0)then + parity<=2; + wordcount<=unsigned(wordcount)+1; + elsif(parity=2)then + if(nowrite='0')then + ldout<='1'; + end if; + nowrite<='0'; + parity<=1; + else + parity<=0; + end if; + end if; + end if; + else + ldout<='0'; + end if; + end if; + + end process; + +end DECODEFEI4RECORD; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/deser.vhd b/rce/fw-hsio/modules/pixelcore/hdl/deser.vhd new file mode 100644 index 0000000000000000000000000000000000000000..c94c0bd55a14eb82a04e837f49a0c0ca705830f4 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/deser.vhd @@ -0,0 +1,131 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity deser is +generic( CHANNEL: std_logic_vector:="1111"); +port( clk: in std_logic; + rst: in std_logic; + d_in: in std_logic; + enabled: in std_logic; + replynow: in std_logic; + marker: in std_logic; + d_out: out std_logic_vector(15 downto 0); + ld: out std_logic; + sof: out std_logic; + eof: out std_logic +); +end deser; + +-------------------------------------------------------------- + +architecture DESER of deser is + +signal reg : std_logic_vector(15 downto 0); +signal parcounter: std_logic_vector(1 downto 0); +signal nodata: std_logic; +signal oldmarker: std_logic; +signal marked: std_logic; +signal eventmark: std_logic; + +begin + + + process(rst, clk) + + variable counter: std_logic_vector(3 downto 0); + variable zerocounter: std_logic_vector(6 downto 0); + variable headercounter: std_logic_vector(3 downto 0); + variable going: std_logic; + begin + if(rst='1') then + reg<=x"0000"; + d_out<=x"0000"; + going:='0'; + eof<='0'; + sof<='0'; + headercounter:="0000"; + ld<='0'; + parcounter<="00"; + oldmarker<='0'; + marked<='0'; + eventmark<='0'; + elsif (clk'event and clk='1') then + if (d_in='1')then + zerocounter:="0000000"; + else + zerocounter:=unsigned(zerocounter)+1; + end if; + oldmarker<=marker; + if(marker='1' and oldmarker='0')then + eventmark<='1'; + elsif(marked='1')then + eventmark<='0'; + end if; + if(going='0' and ((enabled='1' and d_in='1') or replynow='1'))then + going:='1'; + counter:="1111"; + eof<='0'; + zerocounter:="0000000"; + headercounter:="1111"; + parcounter<="00"; + nodata<=replynow; + elsif (going='1' and counter="1111") then + parcounter<=unsigned(parcounter)+1; + d_out<=reg; + if(nodata='1')then + going:='0'; + ld<='0'; + else + ld<='1'; + if(zerocounter>="0100000" and parcounter="11")then + eof<='1'; + going:='0'; + else + eof<='0'; + end if; + end if; + elsif(counter="1110" and headercounter="0000")then + ld<='0'; + end if; + if (unsigned(headercounter)>0)then -- we have to squeeze in the header + ld<='1'; -- before the first event + if(headercounter="1111")then + sof<='1'; + d_out<=(others=>'0'); + elsif(headercounter="1110")then + sof<='0'; + d_out(7 downto 0)<=(others=>'0'); + d_out(15 downto 8)<=x"0"&CHANNEL; + elsif(headercounter="1100")then + d_out<=eventmark&"000"&x"000"; + sof<='0'; + marked<='1'; + else + sof<='0'; + d_out<=(others=>'0'); + marked<='0'; + end if; + headercounter:=unsigned(headercounter)-1; + elsif(nodata='1' and headercounter="0000")then + eof<='1'; + d_out<=(others=>'0'); + end if; + reg(15 downto 1)<=reg(14 downto 0); + reg(0)<=d_in; + counter:=unsigned(counter)-1; + end if; + + end process; + +end DESER; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/deser10b.vhd b/rce/fw-hsio/modules/pixelcore/hdl/deser10b.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ad6260b62809c78cddc10b4a8130eaff7e255f31 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/deser10b.vhd @@ -0,0 +1,64 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity deser10b is +port( clk: in std_logic; + rst: in std_logic; + d_in: in std_logic; + align: in std_logic; + d_out: out std_logic_vector(9 downto 0); + ld: out std_logic +); +end deser10b; + +-------------------------------------------------------------- + +architecture DESER10B of deser10b is + +signal reg : std_logic_vector(9 downto 0); +signal index : std_logic_vector(3 downto 0); +signal aligned: std_logic; + +begin + process(rst, clk) + begin + if(rst='1') then + reg<=x"00"&"00"; + index<=x"0"; + ld<='0'; + aligned<='0'; + elsif (clk'event and clk='1') then + if(align='1' and (aligned='0' or index/=x"0"))then + index<=x"9"; + ld<='0'; + aligned<='1'; + elsif(index=x"0")then + index<=x"9"; + if(aligned='1')then + ld<='1'; + d_out<=reg; + else + ld<='0'; + end if; + else + index<=unsigned(index)-1; + ld<='0'; + end if; + reg(8 downto 0)<=reg(9 downto 1); + reg(9)<=d_in; + end if; + + end process; + +end DESER10B; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/deser4b.vhd b/rce/fw-hsio/modules/pixelcore/hdl/deser4b.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d0056def4e4608b6c04d21cea57d7ba635c2d2cd --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/deser4b.vhd @@ -0,0 +1,64 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity deser4b is +port( clk: in std_logic; + rst: in std_logic; + d_in: in std_logic; + align: in std_logic; + d_out: out std_logic_vector(3 downto 0); + ld: out std_logic +); +end deser4b; + +-------------------------------------------------------------- + +architecture DESER4B of deser4b is + +signal reg : std_logic_vector(3 downto 0); +signal index : std_logic_vector(3 downto 0); +signal aligned: std_logic; + +begin + process(rst, clk) + begin + if(rst='1') then + reg<=x"0"; + index<=x"0"; + ld<='0'; + aligned<='0'; + elsif (clk'event and clk='1') then + if(align='1' and (aligned='0' or index/=x"0"))then + index<=x"3"; + ld<='0'; + aligned<='1'; + elsif(index=x"0")then + index<=x"3"; + if(aligned='1')then + ld<='1'; + d_out<=reg; + else + ld<='0'; + end if; + else + index<=unsigned(index)-1; + ld<='0'; + end if; + reg(3 downto 1)<=reg(2 downto 0); + reg(0)<=d_in; + end if; + + end process; + +end DESER4B; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/encodepgp.vhd b/rce/fw-hsio/modules/pixelcore/hdl/encodepgp.vhd new file mode 100644 index 0000000000000000000000000000000000000000..16022f68a22214870ce5b53e492df5838385eefe --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/encodepgp.vhd @@ -0,0 +1,157 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity encodepgp is +generic( CHANNEL: std_logic_vector:="1111"); +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + isrunning: out std_logic; + d_in: in std_logic_vector(7 downto 0); + k_in: in std_logic; + err_in: in std_logic; + marker: in std_logic; + d_out: out std_logic_vector(17 downto 0); + ldin: in std_logic; + ldout: out std_logic; + overflow: out std_logic +-- acounter: out std_logic_vector(15 downto 0) +); +end encodepgp; + +-------------------------------------------------------------- + +architecture ENCODEPGP of encodepgp is + +signal running: std_logic; +signal headercounter: std_logic_vector(3 downto 0); +signal parity: std_logic_vector(1 downto 0); +signal trailer: std_logic; +signal msb: std_logic_vector(7 downto 0); +signal oldmarker: std_logic; +signal oldoldmarker: std_logic; +signal marked: std_logic; +signal eventmark: std_logic; +signal wordcount: std_logic_vector(11 downto 0); + +begin + isrunning<=running; + process(rst, clk) + begin + if(rst='1') then + d_out<=x"0000"&"00"; + --acounter<=x"0000"; + running<='0'; + headercounter<=x"0"; + parity<="00"; + trailer<='0'; + msb<=x"00"; + ldout<='0'; + oldmarker<='0'; + oldoldmarker<='0'; + marked<='0'; + eventmark<='0'; + overflow<='0'; + wordcount<=(others =>'0'); + elsif (clk'event and clk='1') then + oldmarker<=marker; + oldoldmarker<=oldmarker; + if(marker='1' and oldoldmarker='0')then + eventmark<='1'; + elsif(marked='1')then + eventmark<='0'; + end if; + if(ldin='1')then + if(running='0')then + if(enabled='1' and d_in=x"fc" and k_in='1')then -- SOF + headercounter<="1111"; + d_out<="01"&x"0000"; -- SOF + running<='1'; + parity<="01"; + ldout<='1'; + trailer<='0'; + wordcount<=(others =>'0'); + end if; + else -- running + if(k_in='1' or err_in='1' or wordcount=x"800")then --EOF or idle or error + --if((d_in=x"bc")and k_in='1')then --EOF or idle in case of failure + running<='0'; + if(wordcount=x"800")then + overflow<='1'; + end if; + if(headercounter/="0000")then -- sequence was SOF EOF + trailer<='1'; + ldout<='0'; + else + ldout<='1'; + if(parity(0)='0')then + d_out(15 downto 0)<=x"0000"; + else + d_out(15 downto 0)<= msb & x"00"; + end if; + if(parity(1)='0')then + trailer<='1'; + d_out(17 downto 16)<="00"; + else + trailer<='0'; + d_out(17 downto 16)<="10"; + end if; + end if; + --elsif(err_in='1' or k_in='1')then + -- acounter<=unsigned(acounter)+1; + else-- data + parity<=unsigned(parity)+1; + if(parity(0)='0')then --MSB + ldout<='0'; + msb<=d_in; + else -- LSB + wordcount<=unsigned(wordcount)+1; + ldout<='1'; + d_out(15 downto 0)<=msb & d_in; + d_out(17 downto 16)<="00"; + end if; + end if; + end if; + else + if(headercounter/="0000")then + ldout<='1'; + parity<=unsigned(parity)+1; + headercounter<=unsigned(headercounter)-1; + if(headercounter="1111")then + d_out(7 downto 0)<=(others=>'0'); + d_out(15 downto 8)<=x"0"&CHANNEL; + d_out(17 downto 16)<="00"; + elsif(headercounter="1101")then + d_out<="00"&eventmark&"000"&x"000"; + marked<='1'; + elsif(headercounter="0001" and trailer='1')then + d_out<="10"&x"0000"; --EOF + trailer<='0'; + else + d_out<=(others=>'0'); + marked<='0'; + end if; + elsif(trailer='1')then + ldout<='1'; + d_out<="10"&x"0000"; + trailer<='0'; + else + ldout<='0'; + end if; + end if; + end if; + + end process; + +end ENCODEPGP; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/encodepgp24bit.vhd b/rce/fw-hsio/modules/pixelcore/hdl/encodepgp24bit.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e4404966abbed1dae14345f1489f178d7e59f291 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/encodepgp24bit.vhd @@ -0,0 +1,197 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.StdRtlPkg.all; + +-------------------------------------------------------------- + +entity encodepgp24bit is +generic( CHANNEL: std_logic_vector:="1111"); +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + maxlength: in natural range 0 to 16383; + isrunning: out std_logic; + d_in: in std_logic_vector(24 downto 0); + d_next: in std_logic_vector(24 downto 0); + marker: in std_logic; + d_out: out std_logic_vector(17 downto 0); + ldin: in std_logic; + ldout: out std_logic; + dnextvalid: in std_logic; + dvalid: in std_logic; + datawaiting: in std_logic; + moredatawaiting: in std_logic; + overflow: out std_logic; + parout: out std_logic_vector(1 downto 0); + valid: out std_logic +); +end encodepgp24bit; + +-------------------------------------------------------------- + +architecture ENCODEPGP24BIT of encodepgp24bit is + +signal running: std_logic:='0'; +signal oldrunning: std_logic:='0'; +signal headercounter: std_logic_vector(3 downto 0); +signal parity: std_logic_vector(1 downto 0); +signal trailer: std_logic; +signal msb: std_logic_vector(15 downto 0); +signal oldmarker: std_logic; +signal oldoldmarker: std_logic; +signal marked: std_logic; +signal eventmark: std_logic; +signal wordcount: natural range 0 to 16383:=0; +signal enddata: std_logic := '0'; +signal skip: std_logic := '0'; +signal ldouts: std_logic := '0'; +signal nomore: std_logic := '0'; +signal init: std_logic := '0'; +signal olddatawaiting: std_logic := '0'; + +begin + isrunning<=running; + ldout<=ldouts; + parout<=parity; + ldouts<=(ldin and running and not uOr(headercounter) and (not parity(0) or skip) and not nomore) or init; + process(rst, clk) + begin + if(rst='1') then + d_out<=x"0000"&"00"; + --acounter<=x"0000"; + running<='0'; + headercounter<=x"0"; + parity<="00"; + trailer<='0'; + msb<=x"0000"; + valid<='0'; + oldmarker<='0'; + oldoldmarker<='0'; + marked<='0'; + eventmark<='0'; + overflow<='0'; + wordcount<=0; + skip<='0'; + enddata<='0'; + nomore<='0'; + init<='0'; + elsif (clk'event and clk='1') then + oldmarker<=marker; + oldoldmarker<=oldmarker; + olddatawaiting<=datawaiting; + if(marker='1' and oldoldmarker='0')then + eventmark<='1'; + elsif(marked='1')then + eventmark<='0'; + end if; + oldrunning<=running; + if(ldin='1')then + if(running='0')then + if(oldrunning='1')then + valid<='0'; + elsif(enabled='1' )then -- SOF + headercounter<="1111"; + d_out<="01"&x"0000"; -- SOF + running<='1'; + parity<="00"; + valid<='1'; + trailer<='0'; + wordcount<=0; + enddata<='0'; + skip<='0'; + nomore<='0'; + init<='1'; + end if; + else -- running + if(headercounter/="0000")then + valid<='1'; + headercounter<=unsigned(headercounter)-1; + if(headercounter="1111")then + init<='0'; + d_out(7 downto 0)<=(others=>'0'); + d_out(15 downto 8)<=x"0"&CHANNEL; + d_out(17 downto 16)<="00"; + elsif(headercounter="1101")then + d_out<="00"&eventmark&"000"&x"000"; + marked<='1'; + elsif(headercounter="0001") then + if(d_in(24)='1' and olddatawaiting='0' and (dnextvalid='0' or d_next(24)='0'))then + nomore<='1'; + end if; + else + d_out<=(others=>'0'); + marked<='0'; + end if; + elsif(trailer='1')then + valid<='1'; + d_out<="10"&x"0000"; + trailer<='0'; + running<='0'; + elsif(skip='1')then + valid<='1'; + d_out(15 downto 0)<=msb; + skip<='0'; + if(d_next(24)='1' and (moredatawaiting='0' or wordcount>MAXLENGTH))then + nomore<='1'; + end if; + elsif(enddata='1')then + valid<='1'; + if(parity(0)='1')then + d_out(15 downto 0)<= msb(7 downto 0) & x"00"; + else + d_out(15 downto 0)<=x"0000"; + end if; + if(parity="00" or parity="11")then + trailer<='1'; + d_out(17 downto 16)<="00"; + else + trailer<='0'; + d_out(17 downto 16)<="10"; + running<='0'; + end if; + else-- data + if(nomore='1')then + enddata<='1'; + elsif(moredatawaiting='0' or wordcount>MAXLENGTH)then + if(ldouts='1' and d_next(24)='1')then + nomore<='1'; + elsif(ldouts='0' and d_in(24)='1')then + nomore<='1'; + enddata<='1'; + end if; + if(wordcount>MAXLENGTH)then + overflow<='1'; + end if; + end if; + valid<='1'; + wordcount<=wordcount+1; + parity<=unsigned(parity)+1; + d_out(17 downto 16)<="00"; + if(parity(0)='0')then + msb(7 downto 0)<=d_in(7 downto 0); + d_out(15 downto 0)<=d_in(23 downto 8); + skip<='0'; + else + d_out(15 downto 0)<=msb(7 downto 0) & d_in(23 downto 16); + msb<=d_in(15 downto 0); + skip<='1'; + end if; + end if; + end if; + else + valid<='0'; + end if; + end if; + + end process; + +end ENCODEPGP24BIT; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/eofcounter.vhd b/rce/fw-hsio/modules/pixelcore/hdl/eofcounter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..bb5d635c8343c117d954b4c6842b90e3ef56bab3 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/eofcounter.vhd @@ -0,0 +1,113 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- You must compile the wrapper file eofcounter.vhd when simulating +-- the core, eofcounter. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + +-- The synthesis directives "translate_off/translate_on" specified +-- below are supported by Xilinx, Mentor Graphics and Synplicity +-- synthesis tools. Ensure they are correct for your synthesis tool(s). + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +-- synthesis translate_off +Library XilinxCoreLib; +-- synthesis translate_on +ENTITY eofcounter IS + port ( + clk: IN std_logic; + up: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(15 downto 0)); +END eofcounter; + +ARCHITECTURE eofcounter_a OF eofcounter IS +-- synthesis translate_off +component wrapped_eofcounter + port ( + clk: IN std_logic; + up: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(15 downto 0)); +end component; + +-- Configuration specification + for all : wrapped_eofcounter use entity XilinxCoreLib.c_counter_binary_v8_0(behavioral) + generic map( + c_count_mode => 2, + c_has_aset => 0, + c_load_enable => 0, + c_load_low => 0, + c_count_to => "1", + c_sync_priority => 1, + c_has_iv => 0, + c_has_sclr => 0, + c_restrict_count => 0, + c_width => 16, + c_has_q_thresh1 => 0, + c_enable_rlocs => 0, + c_has_q_thresh0 => 1, + c_thresh1_value => "0", + c_has_load => 0, + c_has_up => 1, + c_thresh_early => 1, + c_has_thresh1 => 0, + c_has_thresh0 => 0, + c_ainit_val => "0", + c_has_ce => 1, + c_pipe_stages => 0, + c_has_aclr => 1, + c_sync_enable => 1, + c_has_ainit => 0, + c_sinit_val => "0", + c_has_sset => 0, + c_has_sinit => 0, + c_count_by => "1", + c_has_l => 0, + c_thresh0_value => "0"); +-- synthesis translate_on +BEGIN +-- synthesis translate_off +U0 : wrapped_eofcounter + port map ( + clk => clk, + up => up, + ce => ce, + aclr => aclr, + q_thresh0 => q_thresh0, + q => q); +-- synthesis translate_on + +END eofcounter_a; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/eudaqTrigger.vhd b/rce/fw-hsio/modules/pixelcore/hdl/eudaqTrigger.vhd new file mode 100644 index 0000000000000000000000000000000000000000..02fbb4fc749a65235ed5e759290a1b672192833b --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/eudaqTrigger.vhd @@ -0,0 +1,86 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity eudaqTrigger is + port ( + clk : in std_logic; + rst : in std_logic; + busyin : in std_logic; + tdcready : in std_logic; + enabled : in std_logic; + l1a : in std_logic; + trg : in std_logic; + done : out std_logic; + extbusy : out std_logic; + trgword : out std_logic_vector(14 downto 0); + trgclk : out std_logic + ); +end eudaqTrigger; + +architecture EUDAQTRIGGER of eudaqTrigger is + + signal clkcounter: std_logic_vector(7 downto 0); + signal extbusyint: std_logic; + signal trgwords: std_logic_vector(14 downto 0); + + +begin + + trgword<=trgwords; + extbusy<=extbusyint; + + process (rst,clk) + begin + if(rst='1')then + clkcounter<="00000000"; + done<='0'; + trgclk<='0'; + trgwords<=x"000"&"000"; + elsif(rising_edge(clk))then + if(clkcounter/="00000000")then + clkcounter<=unsigned(clkcounter)-1; + --if(clkcounter="10000000")then + -- trgclk<='1'; + if(clkcounter(2 downto 0)="010")then -- every 4th tick + trgwords(13 downto 0) <= trgwords(14 downto 1); + trgwords(14)<=trg; + elsif(clkcounter(2 downto 0)="000")then -- every 4th tick + if(clkcounter(7)='0' )then + trgclk<='1'; + end if; + elsif(clkcounter(2 downto 0)="100")then + trgclk<='0'; + elsif(clkcounter="00000001")then + done<='1'; + end if; + elsif(enabled='1' and l1a='1')then + clkcounter<="11000000"; + extbusyint<='1'; + else + done<='0'; + if(busyin='0' and extbusyint='1')then + extbusyint<='0'; + trgclk<='0'; + elsif(extbusyint='0' and enabled='1' and busyin='1' )then --FIFO full + trgclk<='1'; -- eudaq uses trgclk as a veto + elsif(extbusyint='0' and busyin='0')then + trgclk<='0'; + end if; + end if; + end if; + end process; + +end EUDAQTRIGGER; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/framealign.vhd b/rce/fw-hsio/modules/pixelcore/hdl/framealign.vhd new file mode 100644 index 0000000000000000000000000000000000000000..39c2a90fddbb15557110e0c0bf945414fc8e2670 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/framealign.vhd @@ -0,0 +1,56 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity framealign is + port ( + clk : in std_logic; + rst : in std_logic; + d_in : in std_logic; + d_out : out std_logic; + aligned : out std_logic + ); +end framealign; + +architecture FRAMEALIGN of framealign is + + signal pipeline: std_logic_vector(19 downto 0); + +begin + + process (rst,clk) + begin + if(rst='1')then + pipeline<=(others=>'0'); + d_out<='0'; + elsif(rising_edge(clk))then + pipeline(19 downto 1)<= pipeline (18 downto 0); + pipeline(0)<=d_in; + d_out<=pipeline(19); + if(pipeline="00111110101100000111" or -- EOF SOF + pipeline="11000001010011111000" or -- EOF SOF + pipeline="00111110011100000111" or -- Idle SOF + pipeline="11000001100011111000" or -- Idle SOF + pipeline="00111110011100000110" or -- Idle Idle + pipeline="11000001100011111001" -- Idle Idle + )then + aligned<='1'; + else + aligned<='0'; + end if; + end if; + end process; + +end FRAMEALIGN; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/framealignhitbus.vhd b/rce/fw-hsio/modules/pixelcore/hdl/framealignhitbus.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a84b94e8962e93ac870e828385fa10a88d1c5123 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/framealignhitbus.vhd @@ -0,0 +1,51 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity framealignhitbus is + port ( + clk : in std_logic; + rst : in std_logic; + d_in : in std_logic; + d_out : out std_logic; + aligned : out std_logic + ); +end framealignhitbus; + +architecture FRAMEALIGNHITBUS of framealignhitbus is + + signal pipeline: std_logic_vector(7 downto 0); + +begin + + process (rst,clk) + begin + if(rst='1')then + pipeline<=(others=>'0'); + d_out<='0'; + elsif(rising_edge(clk))then + pipeline(7 downto 1)<= pipeline (6 downto 0); + pipeline(0)<=d_in; + d_out<=pipeline(7); + if(pipeline="10001000" -- No triggers 1 marker bit for two cycles + )then + aligned<='1'; + else + aligned<='0'; + end if; + end if; + end process; + +end FRAMEALIGNHITBUS; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/hitbuspipeline.vhd b/rce/fw-hsio/modules/pixelcore/hdl/hitbuspipeline.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b821070f534a556280b5ec4a4ce8127081d54d12 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/hitbuspipeline.vhd @@ -0,0 +1,59 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; +use work.arraytype.all; + +entity hitbuspipeline is + port ( + rst : in std_logic; + clk : in std_logic; + ld : in std_logic; + depth : in std_logic_vector(4 downto 0); + wordin : in std_logic_vector(2 downto 0); + wordout : out std_logic_vector(31 downto 0) + ); +end hitbuspipeline; + +architecture HITBUSPIPELINE of hitbuspipeline is + + signal pp: hbpipeline; + signal index: integer; + +begin + + process (rst,clk) + begin + if(rst='1')then + for I in 0 to 40 loop + pp(I)<="000"; + end loop; + wordout(31 downto 30)<="00"; + elsif(rising_edge(clk))then + if(ld='1') then + pp(0)<=wordin; + hbset: for I in 1 to 40 loop + pp(I)<=pp(I-1); + end loop; + end if; + for I in 0 to 9 loop + wordout(I*3+2)<=pp(conv_integer(unsigned(depth))+I)(2); + wordout(I*3+1)<=pp(conv_integer(unsigned(depth))+I)(1); + wordout(I*3)<=pp(conv_integer(unsigned(depth))+I)(0); + end loop; + end if; + end process; + +end HITBUSPIPELINE; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_bit_ctrl.vhd b/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_bit_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..357535e18d271d4ea4a0ce1f02fde8598ffebdbb --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_bit_ctrl.vhd @@ -0,0 +1,727 @@ +--------------------------------------------------------------------- +---- ---- +---- WISHBONE revB2 I2C Master Core; bit-controller ---- +---- ---- +---- ---- +---- Author: Richard Herveille ---- +---- richard@asics.ws ---- +---- www.asics.ws ---- +---- ---- +---- Downloaded from: http://www.opencores.org/projects/i2c/ ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2000 Richard Herveille ---- +---- richard@asics.ws ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +-- CVS Log +-- +-- $Id: i2c_master_bit_ctrl.vhd,v 1.14 2006/10/11 12:10:13 rherveille Exp $ +-- +-- $Date: 2006/10/11 12:10:13 $ +-- $Revision: 1.14 $ +-- $Author: rherveille $ +-- $Locker: $ +-- $State: Exp $ +-- +-- Change History: +-- $Log: i2c_master_bit_ctrl.vhd,v $ +-- Revision 1.14 2006/10/11 12:10:13 rherveille +-- Added missing semicolons ';' on endif +-- +-- Revision 1.13 2006/10/06 10:48:24 rherveille +-- fixed short scl high pulse after clock stretch +-- +-- Revision 1.12 2004/05/07 11:53:31 rherveille +-- Fixed previous fix :) Made a variable vs signal mistake. +-- +-- Revision 1.11 2004/05/07 11:04:00 rherveille +-- Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit. +-- +-- Revision 1.10 2004/02/27 07:49:43 rherveille +-- Fixed a bug in the arbitration-lost signal generation. VHDL version only. +-- +-- Revision 1.9 2003/08/12 14:48:37 rherveille +-- Forgot an 'end if' :-/ +-- +-- Revision 1.8 2003/08/09 07:01:13 rherveille +-- Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +-- Fixed a potential bug in the byte controller's host-acknowledge generation. +-- +-- Revision 1.7 2003/02/05 00:06:02 rherveille +-- Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles. +-- +-- Revision 1.6 2003/02/01 02:03:06 rherveille +-- Fixed a few 'arbitration lost' bugs. VHDL version only. +-- +-- Revision 1.5 2002/12/26 16:05:47 rherveille +-- Core is now a Multimaster I2C controller. +-- +-- Revision 1.4 2002/11/30 22:24:37 rherveille +-- Cleaned up code +-- +-- Revision 1.3 2002/10/30 18:09:53 rherveille +-- Fixed some reported minor start/stop generation timing issuess. +-- +-- Revision 1.2 2002/06/15 07:37:04 rherveille +-- Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment. +-- +-- Revision 1.1 2001/11/05 12:02:33 rherveille +-- Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version. +-- Code updated, is now up-to-date to doc. rev.0.4. +-- Added headers. +-- +-- Modified by Jan Andersson (jan@gaisler.com): +-- +-- * Added two start states to fulfill Set-up time for +-- repeated START condition. +-- * Modified synchronization of SCL and SDA. START and STOP detection +-- is now performed after a two stage synchronizer and is also +-- filtered. +-- * Changed evaluation order of 'slave_wait', 'en' and 'cnt' in +-- generation of clk_en signal to prevent clk_en assertion when +-- slave_wait is asserted. +-- * Needed to differentiate between slave clock stretching and master +-- clock synchronization. +-- * Added register s_state which contains the next state in case +-- of clock synchronization +-- * Incorporated change in wr_b state from SVN rev. 72 of +-- original OC version (delay check of SDA). +-- * Added 'filter' generic that determines length of filter. +-- Original OC core has a median filter implemented. The solution +-- implemented in this version is a plain shift register with a +-- length determined by the new generic. All samples in this +-- register must be equal, otherwise the SCL or SDA value used by +-- the core will not be changed. Every SCL/SDA transition that is +-- not stable for 'filter' system clock cycles is disregarded. +-- This solution is potentially more vulnerable against short +-- periods of relatively quick fluctuations on the line, however +-- it should do a better job of ignoring 50 ns pulses and still +-- allow us to respond quickly to events on the line - assuming +-- that the core has been correctly configured. +-- Core revision has been increased to 2 (in GRLIB PnP) +-- * Added 'dynfilt' generic to allow dynamic adjustment of the +-- filter. This component takes in a filt vector that is used to +-- reload a filter counter. The filt vector is assigned via the +-- core's APB interface. +-- Reorganized parts of the code, moving signals into blocks. +-- Core revision increased to 3. +-- +------------------------------------- +-- Bit controller section +------------------------------------ +-- +-- Translate simple commands into SCL/SDA transitions +-- Each command has 5 states, A/B/C/D/idle +-- +-- start: SCL ~~~~~~~~~~~~~~\____ +-- SDA XX/~~~~~~~\______ +-- x | A | B | C | D | i +-- +-- repstart SCL ______/~~~~~~~\___ +-- SDA __/~~~~~~~\______ +-- x | A | B | C | D | i +-- +-- stop SCL _______/~~~~~~~~~~~ +-- SDA ==\___________/~~~~~ +-- x | A | B | C | D | i +-- +--- write SCL ______/~~~~~~~\____ +-- SDA XXX===============XX +-- x | A | B | C | D | i +-- +--- read SCL ______/~~~~~~~\____ +-- SDA XXXXXXX=XXXXXXXXXXX +-- x | A | B | C | D | i +-- + +-- Timing: Normal mode Fast mode +----------------------------------------------------------------- +-- Fscl 100KHz 400KHz +-- Th_scl 4.0us 0.6us High period of SCL +-- Tl_scl 4.7us 1.3us Low period of SCL +-- Tsu:sta 4.7us 0.6us setup time for a repeated start condition +-- Tsu:sto 4.0us 0.6us setup time for a stop conditon +-- Tbuf 4.7us 1.3us Bus free time between a stop and start condition +-- + +library ieee; +use ieee.std_logic_1164.all; +--library grlib; +use work.stdlib.all; + +entity i2c_master_bit_ctrl is + generic (filter : integer; dynfilt : integer); + port ( + clk : in std_logic; + rst : in std_logic; + nReset : in std_logic; + ena : in std_logic; -- core enable signal + + clk_cnt : in std_logic_vector(15 downto 0); -- clock prescale value + + cmd : in std_logic_vector(3 downto 0); + cmd_ack : out std_logic; -- command completed + busy : out std_logic; -- i2c bus busy + al : out std_logic; -- arbitration lost + + din : in std_logic; + dout : out std_logic; + + filt : in std_logic_vector((filter-1)*dynfilt downto 0); + + -- i2c lines + scl_i : in std_logic; -- i2c clock line input + scl_o : out std_logic; -- i2c clock line output + scl_oen : out std_logic; -- i2c clock line output enable, active low + sda_i : in std_logic; -- i2c data line input + sda_o : out std_logic; -- i2c data line output + sda_oen : out std_logic -- i2c data line output enable, active low + ); +end entity i2c_master_bit_ctrl; + +architecture structural of i2c_master_bit_ctrl is + constant I2C_CMD_NOP : std_logic_vector(3 downto 0) := "0000"; + constant I2C_CMD_START : std_logic_vector(3 downto 0) := "0001"; + constant I2C_CMD_STOP : std_logic_vector(3 downto 0) := "0010"; + constant I2C_CMD_READ : std_logic_vector(3 downto 0) := "0100"; + constant I2C_CMD_WRITE : std_logic_vector(3 downto 0) := "1000"; + + type states is (idle, start_a, start_b, start_c, start_d, start_e, start_f, start_g, + stop_a, stop_b, stop_c, stop_d, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d); + signal c_state, s_state : states; + + signal iscl_oen, isda_oen : std_logic; -- internal I2C lines + signal sda_chk : std_logic; -- check SDA status (multi-master arbitration) + signal fSCL, fSDA : std_logic_vector(1 downto 0); -- Filtered SCL and SDA inputs + signal clk_en, slave_wait : std_logic; -- clock generation signals + signal ial : std_logic; -- internal arbitration lost signal + signal cnt : std_logic_vector(15 downto 0); -- clock divider counter + signal csync : std_logic; -- Need to synchronize clock with other master + +begin + -- generate clk enable signal + gen_clken: process(clk, nReset) + begin + if (nReset = '0') then + cnt <= (others => '0'); + clk_en <= '1'; + elsif (clk'event and clk = '1') then + if (rst = '1') then + cnt <= (others => '0'); + clk_en <= '1'; + elsif (ena = '0' or csync = '1') then + cnt <= clk_cnt; + clk_en <= '1'; + elsif (slave_wait = '1') then + cnt <= cnt; + clk_en <= '0'; + elsif (cnt = X"0000") then + cnt <= clk_cnt; + clk_en <= '1'; + else + cnt <= cnt -1; + clk_en <= '0'; + end if; + end if; + end process gen_clken; + + + -- generate bus status controller + bus_status_ctrl: block + signal sta_condition : std_logic; -- start detected + signal sto_condition : std_logic; -- stop detected + signal cmd_stop : std_logic; -- STOP command + signal ibusy : std_logic; -- internal busy signal + signal slvw_dis : std_logic; -- Slave wait disable; + begin + + -- Static filter + staticfilt : if dynfilt = 0 generate + sfblock : block + constant FR : integer := filter; -- Filter range MSb + constant DR : integer := filter + 1; -- Delayed SCL/SDA range MSb + + signal sSCL, sSDA : std_logic_vector(FR downto 0); -- synchronized SCL and SDA inputs + signal discl_oen : std_logic_vector(DR downto 0); -- delayed scl_oen signal + signal disda_oen : std_logic_vector(DR downto 0); -- delayed isda_oen + begin + -- synchronize SCL and SDA inputs + synch_scl_sda: process(clk, nReset) + begin + if (nReset = '0') then + sSCL <= (others => '1'); + sSDA <= (others => '1'); + fSCL <= (others => '1'); + fSDA <= (others => '1'); + elsif (clk'event and clk = '1') then + if (rst = '1') then + sSCL <= (others => '1'); + sSDA <= (others => '1'); + fSCL <= (others => '1'); + fSDA <= (others => '1'); + else + sSCL <= sSCL(FR-1 downto 0) & scl_i; + sSDA <= sSDA(FR-1 downto 0) & sda_i; + -- Filtering + if andv(sSCL(FR downto 1)) = '1' then + fSCL <= fSCL(0) & '1'; + elsif orv(sSCL(FR downto 1)) = '0' then + fSCL <= fSCL(0) & '0'; + else + fSCL <= fSCL; + end if; + if andv(sSDA(FR downto 1)) = '1' then + fSDA <= fSDA(0) & '1'; + elsif orv(sSDA(FR downto 1)) = '0' then + fSDA <= fSDA(0) & '0'; + else + fSDA <= fSDA; + end if; + end if; + end if; + end process synch_SCL_SDA; + + -- whenever the slave is not ready it can delay the cycle by pulling SCL low + -- delay scl_oen + process (clk) + begin + if (clk'event and clk = '1') then + if rst = '1' then + discl_oen <= (others => '1'); + slvw_dis <= '0'; + else + -- Keep SCL output enable values + discl_oen <= discl_oen(DR-1 downto 0) & iscl_oen; + -- Disable slave stretch detection when other device drives SCL + -- H->L (only a master should to this). + slvw_dis <= (slvw_dis or csync) and discl_oen(0); + end if; + end if; + end process; + -- SCL forced low after master tried to assert, slave is stretching clock + slave_wait <= andv(discl_oen(DR downto 1)) and not fSCL(0) and not (slvw_dis or fSCL(1)); + -- SCL HIGH time cut short, master clock synchronization + csync <= andv(discl_oen(DR downto 1)) and not fSCL(0) and fSCL(1); + + -- generate arbitration lost signal + -- aribitration lost when: + -- 1) master drives SDA high, but the i2c bus is low + -- 2) stop detected while not requested (detect during 'idle' state) + gen_al: process(clk, nReset) + begin + if (nReset = '0') then + cmd_stop <= '0'; + ial <= '0'; + disda_oen <= (others => '1'); + elsif (clk'event and clk = '1') then + if (rst = '1') then + cmd_stop <= '0'; + ial <= '0'; + disda_oen <= (others => '1'); + else + if (clk_en = '1') then + if (cmd = I2C_CMD_STOP) then + cmd_stop <= '1'; + else + cmd_stop <= '0'; + end if; + end if; + + if (c_state = idle) then + ial <= (sda_chk and not fSDA(0) and disda_oen(DR)); + else + ial <= (sda_chk and not fSDA(0) and disda_oen(DR)) or + (sto_condition and not cmd_stop); + end if; + end if; + disda_oen <= disda_oen(DR-1 downto 0) & isda_oen; + end if; + end process gen_al; + end block sfblock; + end generate staticfilt; + + -- Dynamic filter + dynamicfilt : if dynfilt /= 0 generate + -- Fixed window + dfblock : block + signal filtcnt : std_logic_vector(filter-1 downto 0); + signal sSCL, sSDA : std_logic_vector(1 downto 0); -- synchronized SCL and SDA inputs + signal fiscl_oen : std_logic_vector(1 downto 0); -- "filtered" scl_oen signal + signal fisda_oen : std_ulogic; -- "filtered" sda_oen signal + signal fSCL_chg, fSDA_chg, fiscl_oen_chg, fisda_oen_chg : std_ulogic; + signal discl_oen : std_ulogic; -- delayed scl_oen signal + signal disda_oen : std_ulogic; -- delayed sda_oen signal + begin + -- Provides filtered signals for SCL and SDA, and corresponding + -- output enable signals. + sync_scl_sda: process(clk, nReset, fSCL_chg, fSDA_chg, fiscl_oen_chg, fisda_oen_chg) + variable scl_chg, sda_chg, iscl_oen_chg, isda_oen_chg : std_ulogic; + begin + scl_chg := fSCL_chg; sda_chg := fSDA_chg; + iscl_oen_chg := fiscl_oen_chg; isda_oen_chg := fisda_oen_chg; + if (nReset = '0') then + filtcnt <= (others => '0'); + fSCL <= (others => '1'); fSDA <= (others => '1'); + fSCL_chg <= '0'; fSDA_chg <= '0'; + fiscl_oen <= (others => '1'); fiscl_oen_chg <= '0'; + fisda_oen <= '1'; fisda_oen_chg <= '0'; + elsif (clk'event and clk = '1') then + if (rst = '1') or (ena = '0') then + filtcnt <= (others => '0'); + fSCL <= (others => '1'); fSDA <= (others => '1'); + fSCL_chg <= '0'; fSDA_chg <= '0'; + fiscl_oen <= (others => '1'); fiscl_oen_chg <= '0'; + fisda_oen <= '1'; fisda_oen_chg <= '0'; + else + if (sSCL(1) xor fSCL(0)) = '0' then scl_chg := '0'; end if; + if (sSDA(1) xor fSDA(0)) = '0' then sda_chg := '0'; end if; + if (discl_oen xor fiscl_oen(0)) = '0' then iscl_oen_chg := '0'; end if; + if (disda_oen xor fisda_oen) = '0' then isda_oen_chg := '0'; end if; + if filtcnt = zero32((filter-1)*dynfilt downto 0) then + filtcnt <= filt; + fSCL <= fSCL(0) & (fSCL(0) xor scl_chg); + fSDA <= fSDA(0) & (fSDA(0) xor sda_chg); + fSCL_chg <= '1'; fSDA_chg <= '1'; + fiscl_oen <= fiscl_oen(0) & (fiscl_oen(0) xor iscl_oen_chg); + fiscl_oen_chg <= '1'; + fisda_oen <= fisda_oen xor isda_oen_chg; + fisda_oen_chg <= '1'; + else + filtcnt <= filtcnt - 1; + fSDA <= fSDA; fSCL <= fSCL; + fSCL_chg <= scl_chg; fSDA_chg <= sda_chg; + fiscl_oen <= fiscl_oen; + fiscl_oen_chg <= iscl_oen_chg; + fisda_oen <= fisda_oen; + fisda_oen_chg <= isda_oen_chg; + end if; + end if; + sSCL <= sSCL(0) & scl_i; + sSDA <= sSDA(0) & sda_i; + end if; + end process sync_SCL_SDA; + + -- whenever the slave is not ready it can delay the cycle by pulling SCL low + -- delay scl_oen + process (clk) + begin + if (clk'event and clk = '1') then + if rst = '1' then + discl_oen <= '1'; + slvw_dis <= '0'; + else + -- Keep SCL output enable values + discl_oen <= iscl_oen; + -- Disable slave stretch detection when other device drives SCL + -- H->L (only a master should to this). + slvw_dis <= (slvw_dis or csync) and discl_oen; + end if; + end if; + end process; + -- SCL forced low after master tried to assert, slave is stretching clock + slave_wait <= andv(fiscl_oen) and not fSCL(0) and not (slvw_dis or fSCL(1)); + -- SCL HIGH time cut short, master clock synchronization + csync <= andv(fiscl_oen) and not fSCL(0) and fSCL(1); + + -- generate arbitration lost signal + -- aribitration lost when: + -- 1) master drives SDA high, but the i2c bus is low + -- 2) stop detected while not requested (detect during 'idle' state) + gen_ald: process(clk, nReset) + begin + if (nReset = '0') then + cmd_stop <= '0'; + ial <= '0'; + disda_oen <= '1'; + elsif (clk'event and clk = '1') then + if (rst = '1') then + cmd_stop <= '0'; + ial <= '0'; + disda_oen <= '1'; + else + if (clk_en = '1') then + if (cmd = I2C_CMD_STOP) then + cmd_stop <= '1'; + else + cmd_stop <= '0'; + end if; + end if; + if (c_state = idle) then + ial <= (sda_chk and not fSDA(0) and fisda_oen); + else + ial <= (sda_chk and not fSDA(0) and fisda_oen) or + (sto_condition and not cmd_stop); + end if; + disda_oen <= isda_oen; + end if; + end if; + end process gen_ald; + end block dfblock; + end generate dynamicfilt; + + al <= ial; + + -- detect start condition => detect falling edge on SDA while SCL is high + -- detect stop condition => detect rising edge on SDA while SCL is high + detect_sta_sto: process(clk, nReset) + begin + if (nReset = '0') then + sta_condition <= '0'; + sto_condition <= '0'; + elsif (clk'event and clk = '1') then + if (rst = '1') then + sta_condition <= '0'; + sto_condition <= '0'; + else + if fSCL = "11" and fSDA = "10" then + sta_condition <= '1'; + else + sta_condition <= '0'; + end if; + if fSCL = "11" and fSDA = "01" then + sto_condition <= '1'; + else + sto_condition <= '0'; + end if; + end if; + end if; + end process detect_sta_sto; + + -- generate i2c-bus busy signal + gen_busy: process(clk, nReset) + begin + if (nReset = '0') then + ibusy <= '0'; + elsif (clk'event and clk = '1') then + if (rst = '1') then + ibusy <= '0'; + else + ibusy <= (sta_condition or ibusy) and not sto_condition; + end if; + end if; + end process gen_busy; + busy <= ibusy; + + -- generate dout signal, store dout on rising edge of SCL + gen_dout: process(clk) + begin + if (clk'event and clk = '1') then + if fSCL = "01" then + dout <= fSDA(1); + end if; + end if; + end process gen_dout; + end block bus_status_ctrl; + + + -- generate statemachine + nxt_state_decoder : process (clk, nReset, c_state, cmd) + begin + if (nReset = '0') then + c_state <= idle; + s_state <= idle; + cmd_ack <= '0'; + iscl_oen <= '1'; + isda_oen <= '1'; + sda_chk <= '0'; + elsif (clk'event and clk = '1') then + if (rst = '1' or ial = '1') then + c_state <= idle; + cmd_ack <= '0'; + iscl_oen <= '1'; + isda_oen <= '1'; + sda_chk <= '0'; + elsif csync = '1' then + c_state <= s_state; + else + + cmd_ack <= '0'; -- default no acknowledge + + -- csync is always '0' here, but including it in the expression + -- appears to let some compilers optimize the design more... + if (clk_en or csync) = '1' then + + case (c_state) is + -- idle + when idle => + case cmd is + when I2C_CMD_START => c_state <= start_a; + s_state <= start_g; + when I2C_CMD_STOP => c_state <= stop_a; + s_state <= stop_d; + when I2C_CMD_WRITE => c_state <= wr_a; + s_state <= wr_d; + when I2C_CMD_READ => c_state <= rd_a; + s_state <= rd_d; + when others => c_state <= idle; -- NOP command + s_state <= idle; + end case; + + iscl_oen <= iscl_oen; -- keep SCL in same state + isda_oen <= isda_oen; -- keep SDA in same state + sda_chk <= '0'; -- don't check SDA + + -- start + when start_a => + c_state <= start_b; + iscl_oen <= iscl_oen; -- keep SCL in same state (for repeated start) + isda_oen <= '1'; -- set SDA high + sda_chk <= '0'; -- don't check SDA + + when start_b => + c_state <= start_c; + iscl_oen <= '1'; -- set SCL high + isda_oen <= '1'; -- keep SDA high + sda_chk <= '0'; -- don't check SDA + + when start_c => + c_state <= start_d; + iscl_oen <= '1'; -- set SCL high + isda_oen <= '1'; -- keep SDA high + sda_chk <= '0'; -- don't check SDA + + when start_d => + c_state <= start_e; + iscl_oen <= '1'; -- set SCL high + isda_oen <= '1'; -- keep SDA high + sda_chk <= '0'; -- don't check SDA + + when start_e => + c_state <= start_f; + iscl_oen <= '1'; -- keep SCL high + isda_oen <= '0'; -- set SDA low + sda_chk <= '0'; -- don't check SDA + + when start_f => + c_state <= start_g; + iscl_oen <= '1'; -- keep SCL high + isda_oen <= '0'; -- keep SDA low + sda_chk <= '0'; -- don't check SDA + + when start_g => + c_state <= idle; + cmd_ack <= '1'; -- command completed + iscl_oen <= '0'; -- set SCL low + isda_oen <= '0'; -- keep SDA low + sda_chk <= '0'; -- don't check SDA + s_state <= idle; + + -- stop + when stop_a => + c_state <= stop_b; + iscl_oen <= '0'; -- keep SCL low + isda_oen <= '0'; -- set SDA low + sda_chk <= '0'; -- don't check SDA + + when stop_b => + c_state <= stop_c; + iscl_oen <= '1'; -- set SCL high + isda_oen <= '0'; -- keep SDA low + sda_chk <= '0'; -- don't check SDA + + when stop_c => + c_state <= stop_d; + iscl_oen <= '1'; -- keep SCL high + isda_oen <= '0'; -- keep SDA low + sda_chk <= '0'; -- don't check SDA + + when stop_d => + c_state <= idle; + cmd_ack <= '1'; -- command completed + iscl_oen <= '1'; -- keep SCL high + isda_oen <= '1'; -- set SDA high + sda_chk <= '0'; -- don't check SDA + s_state <= idle; + + -- read + when rd_a => + c_state <= rd_b; + iscl_oen <= '0'; -- keep SCL low + isda_oen <= '1'; -- tri-state SDA + sda_chk <= '0'; -- don't check SDA + + when rd_b => + c_state <= rd_c; + iscl_oen <= '1'; -- set SCL high + isda_oen <= '1'; -- tri-state SDA + sda_chk <= '0'; -- don't check SDA + + when rd_c => + c_state <= rd_d; + iscl_oen <= '1'; -- keep SCL high + isda_oen <= '1'; -- tri-state SDA + sda_chk <= '0'; -- don't check SDA + + when rd_d => + c_state <= idle; + cmd_ack <= '1'; -- command completed + iscl_oen <= '0'; -- set SCL low + isda_oen <= '1'; -- tri-state SDA + sda_chk <= '0'; -- don't check SDA + s_state <= idle; + + -- write + when wr_a => + c_state <= wr_b; + iscl_oen <= '0'; -- keep SCL low + isda_oen <= din; -- set SDA + sda_chk <= '0'; -- don't check SDA (SCL low) + + when wr_b => + c_state <= wr_c; + iscl_oen <= '1'; -- set SCL high + isda_oen <= din; -- keep SDA + sda_chk <= '0'; -- don't check SDA (allow signals to settle) + + when wr_c => + c_state <= wr_d; + iscl_oen <= '1'; -- keep SCL high + isda_oen <= din; -- keep SDA + sda_chk <= '1'; -- check SDA + + when wr_d => + c_state <= idle; + cmd_ack <= '1'; -- command completed + iscl_oen <= '0'; -- set SCL low + isda_oen <= din; -- keep SDA + sda_chk <= '0'; -- don't check SDA (SCL low) + s_state <= idle; + + when others => + + end case; + end if; + end if; + end if; + end process nxt_state_decoder; + + + -- assign outputs + scl_o <= '0'; + scl_oen <= iscl_oen; + sda_o <= '0'; + sda_oen <= isda_oen; +end architecture structural; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_byte_ctrl.vhd b/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_byte_ctrl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..dce9332dd308c0b04762a6997f07c3063456c427 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/i2c_master_byte_ctrl.vhd @@ -0,0 +1,388 @@ +--------------------------------------------------------------------- +---- ---- +---- WISHBONE revB2 compl. I2C Master Core; byte-controller ---- +---- ---- +---- ---- +---- Author: Richard Herveille ---- +---- richard@asics.ws ---- +---- www.asics.ws ---- +---- ---- +---- Downloaded from: http://www.opencores.org/projects/i2c/ ---- +---- ---- +--------------------------------------------------------------------- +---- ---- +---- Copyright (C) 2000 Richard Herveille ---- +---- richard@asics.ws ---- +---- ---- +---- This source file may be used and distributed without ---- +---- restriction provided that this copyright statement is not ---- +---- removed from the file and that any derivative work contains ---- +---- the original copyright notice and the associated disclaimer.---- +---- ---- +---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ---- +---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ---- +---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ---- +---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ---- +---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ---- +---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ---- +---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ---- +---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ---- +---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ---- +---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ---- +---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ---- +---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ---- +---- POSSIBILITY OF SUCH DAMAGE. ---- +---- ---- +--------------------------------------------------------------------- + +-- CVS Log +-- +-- $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $ +-- +-- $Date: 2004/02/18 11:41:48 $ +-- $Revision: 1.5 $ +-- $Author: rherveille $ +-- $Locker: $ +-- $State: Exp $ +-- +-- Change History: +-- $Log: i2c_master_byte_ctrl.vhd,v $ +-- Revision 1.5 2004/02/18 11:41:48 rherveille +-- Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. +-- +-- Revision 1.4 2003/08/09 07:01:13 rherveille +-- Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +-- Fixed a potential bug in the byte controller's host-acknowledge generation. +-- +-- Revision 1.3 2002/12/26 16:05:47 rherveille +-- Core is now a Multimaster I2C controller. +-- +-- Revision 1.2 2002/11/30 22:24:37 rherveille +-- Cleaned up code +-- +-- Revision 1.1 2001/11/05 12:02:33 rherveille +-- Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version. +-- Code updated, is now up-to-date to doc. rev.0.4. +-- Added headers. +-- + +-- Modified by Jan Andersson (jan@gaisler.com:. +-- Changed std_logic_arith to numeric_std. +-- Propagate filter generic + +-- +------------------------------------------ +-- Byte controller section +------------------------------------------ +-- +library ieee; +use ieee.std_logic_1164.all; +--library grlib; +use work.stdlib.all; + +entity i2c_master_byte_ctrl is + generic (filter : integer; dynfilt : integer); + port ( + clk : in std_logic; + rst : in std_logic; -- synchronous active high reset (WISHBONE compatible) + nReset : in std_logic; -- asynchornous active low reset (FPGA compatible) + ena : in std_logic; -- core enable signal + + clk_cnt : in std_logic_vector(15 downto 0); -- 4x SCL + + -- input signals + start, + stop, + read, + write, + ack_in : std_logic; + din : in std_logic_vector(7 downto 0); + filt : in std_logic_vector((filter-1)*dynfilt downto 0); + + -- output signals + cmd_ack : out std_logic; -- command done + ack_out : out std_logic; + i2c_busy : out std_logic; -- arbitration lost + i2c_al : out std_logic; -- i2c bus busy + dout : out std_logic_vector(7 downto 0); + + -- i2c lines + scl_i : in std_logic; -- i2c clock line input + scl_o : out std_logic; -- i2c clock line output + scl_oen : out std_logic; -- i2c clock line output enable, active low + sda_i : in std_logic; -- i2c data line input + sda_o : out std_logic; -- i2c data line output + sda_oen : out std_logic -- i2c data line output enable, active low + ); +end entity i2c_master_byte_ctrl; + +architecture structural of i2c_master_byte_ctrl is + component i2c_master_bit_ctrl is + generic (filter : integer; dynfilt : integer); + port ( + clk : in std_logic; + rst : in std_logic; + nReset : in std_logic; + ena : in std_logic; -- core enable signal + + clk_cnt : in std_logic_vector(15 downto 0); -- clock prescale value + + cmd : in std_logic_vector(3 downto 0); + cmd_ack : out std_logic; -- command done + busy : out std_logic; -- i2c bus busy + al : out std_logic; -- arbitration lost + + din : in std_logic; + dout : out std_logic; + + filt : in std_logic_vector((filter-1)*dynfilt downto 0); + + -- i2c lines + scl_i : in std_logic; -- i2c clock line input + scl_o : out std_logic; -- i2c clock line output + scl_oen : out std_logic; -- i2c clock line output enable, active low + sda_i : in std_logic; -- i2c data line input + sda_o : out std_logic; -- i2c data line output + sda_oen : out std_logic -- i2c data line output enable, active low + ); + end component i2c_master_bit_ctrl; + + -- commands for bit_controller block + constant I2C_CMD_NOP : std_logic_vector(3 downto 0) := "0000"; + constant I2C_CMD_START : std_logic_vector(3 downto 0) := "0001"; + constant I2C_CMD_STOP : std_logic_vector(3 downto 0) := "0010"; + constant I2C_CMD_READ : std_logic_vector(3 downto 0) := "0100"; + constant I2C_CMD_WRITE : std_logic_vector(3 downto 0) := "1000"; + + -- signals for bit_controller + signal core_cmd : std_logic_vector(3 downto 0); + signal core_ack, core_txd, core_rxd : std_logic; + signal al : std_logic; + + -- signals for shift register + signal sr : std_logic_vector(7 downto 0); -- 8bit shift register + signal shift, ld : std_logic; + + -- signals for state machine + signal go, host_ack : std_logic; + -- Added init value to dcnt to prevent simulation meta-value + -- - jan@gaisler.com + -- removed init value as it is not compatible with Formality + -- - jiri@gaisler.com + signal dcnt : std_logic_vector(2 downto 0) +-- pragma translate_off + := (others => '0') +-- pragma translate_on + ; -- data counter + signal cnt_done : std_logic; + +begin + -- hookup bit_controller + bit_ctrl: i2c_master_bit_ctrl + generic map (filter, dynfilt) + port map( + clk => clk, + rst => rst, + nReset => nReset, + ena => ena, + clk_cnt => clk_cnt, + cmd => core_cmd, + cmd_ack => core_ack, + busy => i2c_busy, + al => al, + din => core_txd, + dout => core_rxd, + filt => filt, + scl_i => scl_i, + scl_o => scl_o, + scl_oen => scl_oen, + sda_i => sda_i, + sda_o => sda_o, + sda_oen => sda_oen + ); + i2c_al <= al; + + -- generate host-command-acknowledge + cmd_ack <= host_ack; + + -- generate go-signal + go <= (read or write or stop) and not host_ack; + + -- assign Dout output to shift-register + dout <= sr; + + -- generate shift register + shift_register: process(clk, nReset) + begin + if (nReset = '0') then + sr <= (others => '0'); + elsif (clk'event and clk = '1') then + if (rst = '1') then + sr <= (others => '0'); + elsif (ld = '1') then + sr <= din; + elsif (shift = '1') then + sr <= (sr(6 downto 0) & core_rxd); + end if; + end if; + end process shift_register; + + -- generate data-counter + data_cnt: process(clk, nReset) + begin + if (nReset = '0') then + dcnt <= (others => '0'); + elsif (clk'event and clk = '1') then + if (rst = '1') then + dcnt <= (others => '0'); + elsif (ld = '1') then + dcnt <= (others => '1'); -- load counter with 7 + elsif (shift = '1') then + dcnt <= dcnt -1; + end if; + end if; + end process data_cnt; + + cnt_done <= '1' when (dcnt = "000") else '0'; + + -- + -- state machine + -- + statemachine : block + type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop); + signal c_state : states; + begin + -- + -- command interpreter, translate complex commands into simpler I2C commands + -- + nxt_state_decoder: process(clk, nReset) + begin + if (nReset = '0') then + core_cmd <= I2C_CMD_NOP; + core_txd <= '0'; + shift <= '0'; + ld <= '0'; + host_ack <= '0'; + c_state <= st_idle; + ack_out <= '0'; + elsif (clk'event and clk = '1') then + if (rst = '1' or al = '1') then + core_cmd <= I2C_CMD_NOP; + core_txd <= '0'; + shift <= '0'; + ld <= '0'; + host_ack <= '0'; + c_state <= st_idle; + ack_out <= '0'; + else + -- initialy reset all signal + core_txd <= sr(7); + shift <= '0'; + ld <= '0'; + host_ack <= '0'; + + case c_state is + when st_idle => + if (go = '1') then + if (start = '1') then + c_state <= st_start; + core_cmd <= I2C_CMD_START; + elsif (read = '1') then + c_state <= st_read; + core_cmd <= I2C_CMD_READ; + elsif (write = '1') then + c_state <= st_write; + core_cmd <= I2C_CMD_WRITE; + else -- stop + c_state <= st_stop; + core_cmd <= I2C_CMD_STOP; + end if; + + ld <= '1'; + end if; + + when st_start => + if (core_ack = '1') then + if (read = '1') then + c_state <= st_read; + core_cmd <= I2C_CMD_READ; + else + c_state <= st_write; + core_cmd <= I2C_CMD_WRITE; + end if; + + ld <= '1'; + end if; + + when st_write => + if (core_ack = '1') then + if (cnt_done = '1') then + c_state <= st_ack; + core_cmd <= I2C_CMD_READ; + else + c_state <= st_write; -- stay in same state + core_cmd <= I2C_CMD_WRITE; -- write next bit + shift <= '1'; + end if; + end if; + + when st_read => + if (core_ack = '1') then + if (cnt_done = '1') then + c_state <= st_ack; + core_cmd <= I2C_CMD_WRITE; + else + c_state <= st_read; -- stay in same state + core_cmd <= I2C_CMD_READ; -- read next bit + end if; + + shift <= '1'; + core_txd <= ack_in; + end if; + + when st_ack => + if (core_ack = '1') then + -- check for stop; Should a STOP command be generated ? + if (stop = '1') then + c_state <= st_stop; + core_cmd <= I2C_CMD_STOP; + else + c_state <= st_idle; + core_cmd <= I2C_CMD_NOP; + + -- generate command acknowledge signal + host_ack <= '1'; + end if; + + -- assign ack_out output to core_rxd (contains last received bit) + ack_out <= core_rxd; + + core_txd <= '1'; + else + core_txd <= ack_in; + end if; + + when st_stop => + if (core_ack = '1') then + c_state <= st_idle; + core_cmd <= I2C_CMD_NOP; + + -- generate command acknowledge signal + host_ack <= '1'; + end if; + + when others => -- illegal states + c_state <= st_idle; + core_cmd <= I2C_CMD_NOP; + --report ("Byte controller entered illegal state."); + + end case; + + end if; + end if; + end process nxt_state_decoder; + + end block statemachine; + +end architecture structural; + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/lookaheadfifo.vhd b/rce/fw-hsio/modules/pixelcore/hdl/lookaheadfifo.vhd new file mode 100644 index 0000000000000000000000000000000000000000..87c88f4b6a82e4f233780978bba0e12042d7e136 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/lookaheadfifo.vhd @@ -0,0 +1,136 @@ +-------------------------------------------------------------- +-- Look ahead fifo +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.StdRtlPkg.all; +use work.all; + +-------------------------------------------------------------- + +entity lookaheadfifo is + generic ( + buffersize : integer :=8192 -- FIFO size + ); +port( wr_clk: in std_logic; + rd_clk: in std_logic; + rst: in std_logic; + din: in std_logic_vector(24 downto 0); + dout: out std_logic_vector(24 downto 0):=(others =>'0'); + dnext: out std_logic_vector(24 downto 0); + wr_en: in std_logic; + rd_en: in std_logic; + dnextvalid: out std_logic; + empty: out std_logic; + full: out std_logic; + overflow: out std_logic; + prog_full: out std_logic; + underflow: out std_logic; + valid: out std_logic := '0' +); +end lookaheadfifo; + +-------------------------------------------------------------- + +architecture LOOKAHEADFIFO of lookaheadfifo is + +COMPONENT data24bitfifo4096 + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(24 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(24 DOWNTO 0); + full : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + underflow : OUT STD_LOGIC; + prog_full : OUT STD_LOGIC + ); +END COMPONENT; +COMPONENT data24bitfifo8192 + PORT ( + rst : IN STD_LOGIC; + wr_clk : IN STD_LOGIC; + rd_clk : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(24 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + dout : OUT STD_LOGIC_VECTOR(24 DOWNTO 0); + full : OUT STD_LOGIC; + overflow : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + underflow : OUT STD_LOGIC; + prog_full : OUT STD_LOGIC + ); +END COMPONENT; + +signal frd_en: std_logic:='0'; +signal buffervalid: std_logic:='0'; +signal doutvalid: std_logic:='0'; +signal fdout: slv(24 downto 0); + +begin + dnextvalid<=buffervalid; + dnext<=fdout; + frd_en<=buffervalid and rd_en; + valid<=doutvalid; + process begin + wait until rising_edge(rd_clk); + if(frd_en='1')then + dout<=fdout; + doutvalid<='1'; + elsif(rd_en='1')then + if(doutvalid='1')then + doutvalid<='0'; + end if; + end if; + end process; + + buf_4096: if (buffersize=4096) generate + fei4fifo : data24bitfifo4096 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => frd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => fdout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => buffervalid, + underflow => underflow); + end generate; + buf_8192: if (buffersize=8192) generate + fei4fifo : data24bitfifo8192 + port map ( + din => din, + rd_clk => rd_clk, + rd_en => frd_en, + rst => rst, + wr_clk => wr_clk, + wr_en => wr_en, + dout => fdout, + empty => empty, + full => full, + overflow => overflow, + prog_full => prog_full, + valid => buffervalid, + underflow => underflow); + end generate; + +end LOOKAHEADFIFO; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/multiplexdata.vhd b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdata.vhd new file mode 100644 index 0000000000000000000000000000000000000000..888f5218eec6a52aa9b53090ab067c21ebfd6e53 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdata.vhd @@ -0,0 +1,250 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.arraytype.all; + +-------------------------------------------------------------- + + +entity multiplexdata is + +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + channelmask: in std_logic_vector(15 downto 0); + datawaiting: in std_logic_vector(15 downto 0); + indatavalid: in std_logic_vector(15 downto 0); + datain: in dataarray; + dataout: out std_logic_vector(15 downto 0); + eofout: out std_logic; + sofout: out std_logic; + datavalid: out std_logic; + reqdata: out std_logic_vector(15 downto 0); + counter4: out std_logic_vector(31 downto 0); + counter10b: out std_logic_vector(31 downto 0); + counter10: out std_logic_vector(31 downto 0) +); +end multiplexdata; + +-------------------------------------------------------------- + +architecture MULTIPLEXDATA of multiplexdata is + signal index: integer; + signal eof: std_logic; + signal sof: std_logic; + signal pdata: dataarray; + signal pvalid: std_logic_vector(15 downto 0); + type state_type is (idle, first, sending, paused, switch, kludge1, kludge2, kludge3, mwait); + signal state: state_type; + signal wcounter: std_logic_vector(8 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(7 downto 0); + signal ccontrol: std_logic_vector(35 downto 0); + signal dwcounter: std_logic_vector(3 downto 0); + signal eofouts: std_logic; + signal sofouts: std_logic; + signal datavalids: std_logic; + signal reqdatas: std_logic_vector(15 downto 0); +component chipscope_ila_new + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); + +end component; + component chipscope_icon_new + PORT ( + CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); + + end component; +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + +begin + + eofout<=eofouts; + sofout<=sofouts; + datavalid<=datavalids; + reqdata<=reqdatas; + + process (rst,clk) + begin + if(rst='1')then + index<=0; + reqdatas<=x"0000"; + eofouts<='0'; + sofouts<='0'; + dataout<=x"0000"; + pvalid<=x"0000"; + pdata(0)<="00"&x"0000"; + pdata(1)<="00"&x"0000"; + pdata(2)<="00"&x"0000"; + pdata(3)<="00"&x"0000"; + pdata(4)<="00"&x"0000"; + pdata(5)<="00"&x"0000"; + pdata(6)<="00"&x"0000"; + pdata(7)<="00"&x"0000"; + pdata(8)<="00"&x"0000"; + pdata(9)<="00"&x"0000"; + pdata(10)<="00"&x"0000"; + pdata(11)<="00"&x"0000"; + pdata(12)<="00"&x"0000"; + pdata(13)<="00"&x"0000"; + pdata(14)<="00"&x"0000"; + pdata(15)<="00"&x"0000"; + wcounter<='0'&x"00"; + counter4<=x"00000000"; + dwcounter<="0000"; + state<= idle; + elsif(rising_edge(clk))then + case state is + when kludge1 => + dataout<=x"0000"; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + state<=kludge2; + when kludge2 => + eofouts<='1'; + state<=kludge3; + when kludge3 => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + dwcounter<="1010"; + state<=mwait; + when switch => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + dwcounter<="1010"; + state<=mwait; + when mwait => + if(dwcounter/="0000")then + dwcounter<=unsigned(dwcounter)-1; + state<=mwait; + else + state<=idle; + end if; + when idle => + if(enabled='1' and channelmask(index)='1' and datawaiting(index)='1')then + reqdatas(index)<='1'; + state<=first; + wcounter<='0'&x"00"; + elsif(enabled='0')then + state<=idle; + else + state<=idle; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + end if; + when first => + if(pvalid(index)='1')then + sofouts<='1'; + dataout<=pdata(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + pvalid(index)<='0'; + end if; + state<= sending; + when sending => + dataout <= datain(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + sofouts <=datain(index)(16); + if(datain(index)(17)='1') then --EOF + reqdatas(index)<='0'; + if(wcounter(8)='1' or wcounter(7)='1')then + counter4(8 downto 0)<=wcounter; + end if; + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=switch; + eofouts<='1'; + end if; + elsif(enabled='0')then + reqdatas(index)<='0'; + state<=paused;-- pause transmission + else + state<=sending; + end if; + when paused => + if(indatavalid(index)='1')then + dataout <= datain(index)(15 downto 0); + wcounter<=unsigned(wcounter)+1; + if(datain(index)(17)='1') then --EOF + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=switch; + eofouts<='1'; + end if; + end if; + else + datavalids<='0'; + if(enabled='1')then + reqdatas(index)<='1'; + state<=first; + else + state<=paused; + end if; + end if; + end case; + end if; + + cdata(6)<=datain(index)(17); + cdata(7)<=eofouts; + cdata(8)<=datain(index)(16); + cdata(9)<=sofouts; + cdata(5)<=datavalids; + cdata(4)<=indatavalid(index); + cdata(3 downto 0)<=conv_std_logic_vector(index, 4); + cdata(17 downto 10)<=reqdatas(7 downto 0); + cdata(18)<=channelmask(index) and datawaiting(index) and enabled; + ctrig(0)<=channelmask(index) and datawaiting(index) and enabled; + + end process; + + --chipscope : chipscope_ila_new + -- port map ( + -- CONTROL => ccontrol, + -- CLK => clk, + -- DATA => cdata, + -- TRIG0 => ctrig); +-- chipscopeicon : chipscope_icon_new +-- port map ( +-- CONTROL0 => ccontrol); +-- + +end MULTIPLEXDATA; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/multiplexdataopt.vhd b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdataopt.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1a82bd60777cdd8c17ad816525d143063327b21f --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdataopt.vhd @@ -0,0 +1,265 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.arraytype.all; + +-------------------------------------------------------------- + + +entity multiplexdata is +generic( + maxchannel: integer:=28); +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + channelmask: in std_logic_vector(31 downto 0); + datawaiting: in std_logic_vector(31 downto 0); + moredatawaiting: in std_logic_vector(31 downto 0); + indatavalid: in std_logic_vector(31 downto 0); + datain: in dataarray; + dataout: out std_logic_vector(15 downto 0); + eofout: out std_logic; + sofout: out std_logic; + datavalid: out std_logic; + reqdata: out std_logic_vector(31 downto 0); + multiplicity: in std_logic_vector(63 downto 0); + counter4: out std_logic_vector(31 downto 0); + counter10b: out std_logic_vector(31 downto 0); + counter10: out std_logic_vector(31 downto 0) +); +end multiplexdata; + +-------------------------------------------------------------- + +architecture MULTIPLEXDATA of multiplexdata is + signal index: integer; + signal eof: std_logic; + signal sof: std_logic; + signal pdata: dataarray; + signal pvalid: std_logic_vector(31 downto 0); + type state_type is (idle, first, sending, paused, switch, kludge1, kludge2, kludge3, mwait); + signal state: state_type; + signal wcounter: std_logic_vector(8 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(7 downto 0); + signal ccontrol: std_logic_vector(35 downto 0); + signal dwcounter: std_logic_vector(3 downto 0); + signal eofouts: std_logic; + signal sofouts: std_logic; + signal datavalids: std_logic; + signal reqdatas: std_logic_vector(31 downto 0); + signal repcounter: std_logic_vector(3 downto 0); +component chipscope_ila_new + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); + +end component; + component chipscope_icon_new + PORT ( + CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); + + end component; + + function reps(w:std_logic_vector; i:integer) return std_logic_vector is + begin + if(i=30)then + return w(63 downto 60); + else + return w(i*4+3 downto i*4); + end if; + end; +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + +begin + + eofout<=eofouts; + sofout<=sofouts; + datavalid<=datavalids; + reqdata<=reqdatas; + + process (rst,clk) + begin + if(rst='1')then + index<=0; + reqdatas<=(others=>'0'); + eofouts<='0'; + sofouts<='0'; + dataout<=x"0000"; + pvalid<=(others=>'0'); + pdata<= (others => (others=>'0')); + wcounter<='0'&x"00"; + counter4<=x"00000000"; + dwcounter<="0000"; + state<= idle; + repcounter<=x"0"; + elsif(rising_edge(clk))then + case state is + when kludge1 => + dataout<=x"0000"; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + state<=kludge2; + when kludge2 => + eofouts<='1'; + state<=kludge3; + when kludge3 => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(moredatawaiting(index)='1' and repcounter/=reps(multiplicity, index))then + repcounter<=unsigned(repcounter)+1; + else + repcounter<=x"0"; + if(index=maxchannel)then + index<=29; + elsif(index=31)then + index<=0; + else + index<=index+1; + end if; + end if; + dwcounter<="1010"; + state<=mwait; + when switch => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + if(moredatawaiting(index)='1' and repcounter/=reps(multiplicity, index))then + repcounter<=unsigned(repcounter)+1; + else + repcounter<=x"0"; + if(index=maxchannel)then + index<=29; + elsif(index=31)then + index<=0; + else + index<=index+1; + end if; + end if; + dwcounter<="1010"; + state<=mwait; + when mwait => + if(dwcounter/="0000")then + dwcounter<=unsigned(dwcounter)-1; + state<=mwait; + else + state<=idle; + end if; + when idle => + if(enabled='1' and channelmask(index)='1' and datawaiting(index)='1')then + reqdatas(index)<='1'; + state<=first; + wcounter<='0'&x"00"; + elsif(enabled='0')then + state<=idle; + else + if(index=maxchannel)then + index<=29; + elsif(index=31)then + index<=0; + else + index<=index+1; + end if; + state<=idle; + end if; + when first => + if(pvalid(index)='1')then + sofouts<='1'; + dataout<=pdata(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + pvalid(index)<='0'; + end if; + state<= sending; + when sending => + dataout <= datain(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + sofouts <=datain(index)(16); + if(datain(index)(17)='1') then --EOF + reqdatas(index)<='0'; + if(wcounter(8)='1' or wcounter(7)='1')then + counter4(8 downto 0)<=wcounter; + end if; + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=switch; + eofouts<='1'; + end if; + elsif(enabled='0')then + reqdatas(index)<='0'; + state<=paused;-- pause transmission + else + state<=sending; + end if; + when paused => + if(indatavalid(index)='1')then + dataout <= datain(index)(15 downto 0); + wcounter<=unsigned(wcounter)+1; + if(datain(index)(17)='1') then --EOF + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=switch; + eofouts<='1'; + end if; + end if; + else + datavalids<='0'; + if(enabled='1')then + reqdatas(index)<='1'; + state<=first; + else + state<=paused; + end if; + end if; + end case; + end if; + + cdata(6)<=datain(index)(17); + cdata(7)<=eofouts; + cdata(8)<=datain(index)(16); + cdata(9)<=sofouts; + cdata(5)<=datavalids; + cdata(4)<=indatavalid(index); + cdata(3 downto 0)<=conv_std_logic_vector(index, 4); + cdata(17 downto 10)<=reqdatas(7 downto 0); + cdata(18)<=channelmask(index) and datawaiting(index) and enabled; + ctrig(0)<=channelmask(index) and datawaiting(index) and enabled; + + end process; + + --chipscope : chipscope_ila_new + -- port map ( + -- CONTROL => ccontrol, + -- CLK => clk, + -- DATA => cdata, + -- TRIG0 => ctrig); +-- chipscopeicon : chipscope_icon_new +-- port map ( +-- CONTROL0 => ccontrol); +-- + +end MULTIPLEXDATA; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/multiplexdatapgp2.vhd b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdatapgp2.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a1f5fe8d0656a8cb6acff66aac588c28d21506d8 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/multiplexdatapgp2.vhd @@ -0,0 +1,252 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.arraytype.all; + +-------------------------------------------------------------- + + +entity multiplexdata is +generic(maxchannel: integer:=28); +port( clk: in std_logic; + rst: in std_logic; + enabled: in std_logic; + channelmask: in std_logic_vector(31 downto 0); + datawaiting: in std_logic_vector(31 downto 0); + moredatawaiting: in std_logic_vector(31 downto 0); + indatavalid: in std_logic_vector(31 downto 0); + datain: in dataarray; + dataout: out std_logic_vector(31 downto 0); + eofout: out std_logic; + sofout: out std_logic; + datavalid: out std_logic; + reqdata: out std_logic_vector(31 downto 0); + multiplicity: in std_logic_vector(63 downto 0); + counter4: out std_logic_vector(31 downto 0); + counter10b: out std_logic_vector(31 downto 0); + counter10: out std_logic_vector(31 downto 0) +); +end multiplexdata; + +-------------------------------------------------------------- + +architecture MULTIPLEXDATA of multiplexdata is + signal index: integer; + signal eof: std_logic; + signal sof: std_logic; + signal pdata: dataarray; + signal pvalid: std_logic_vector(31 downto 0); + type state_type is (idle, first, sending, paused, switch, kludge1, kludge2, kludge3, mwait); + signal state: state_type; + signal wcounter: std_logic_vector(8 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(7 downto 0); + signal ccontrol: std_logic_vector(35 downto 0); + signal dwcounter: std_logic_vector(3 downto 0); + signal eofouts: std_logic; + signal sofouts: std_logic; + signal datavalids: std_logic; + signal reqdatas: std_logic_vector(31 downto 0); +component chipscope_ila_new + PORT ( + CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + CLK : IN STD_LOGIC; + DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); + +end component; + component chipscope_icon_new + PORT ( + CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); + + end component; +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + +begin + + eofout<=eofouts; + sofout<=sofouts; + datavalid<=datavalids; + reqdata<=reqdatas; + + process (rst,clk) + begin + if(rst='1')then + index<=0; + reqdatas<=x"0000"; + eofouts<='0'; + sofouts<='0'; + dataout<=x"0000"; + pvalid<=x"0000"; + pdata(0)<="00"&x"0000"; + pdata(1)<="00"&x"0000"; + pdata(2)<="00"&x"0000"; + pdata(3)<="00"&x"0000"; + pdata(4)<="00"&x"0000"; + pdata(5)<="00"&x"0000"; + pdata(6)<="00"&x"0000"; + pdata(7)<="00"&x"0000"; + pdata(8)<="00"&x"0000"; + pdata(9)<="00"&x"0000"; + pdata(10)<="00"&x"0000"; + pdata(11)<="00"&x"0000"; + pdata(12)<="00"&x"0000"; + pdata(13)<="00"&x"0000"; + pdata(14)<="00"&x"0000"; + pdata(15)<="00"&x"0000"; + wcounter<='0'&x"00"; + counter4<=x"00000000"; + dwcounter<="0000"; + state<= idle; + elsif(rising_edge(clk))then + case state is + when kludge1 => + dataout<=x"0000"; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + state<=kludge2; + when kludge2 => + eofouts<='1'; + state<=kludge3; + when kludge3 => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + dwcounter<="1010"; + state<=mwait; + when switch => + eofouts<='0'; + datavalids<='0'; + sofouts<='0'; + if(indatavalid(index)='1')then + pvalid(index)<='1'; + pdata(index)<=datain(index); + else + pvalid(index)<='0'; + end if; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + dwcounter<="1010"; + state<=mwait; + when mwait => + if(dwcounter/="0000")then + dwcounter<=unsigned(dwcounter)-1; + state<=mwait; + else + state<=idle; + end if; + when idle => + if(enabled='1' and channelmask(index)='1' and datawaiting(index)='1')then + reqdatas(index)<='1'; + state<=first; + wcounter<='0'&x"00"; + elsif(enabled='0')then + state<=idle; + else + state<=idle; + if(index=15)then + index<=0; + else + index<=index+1; + end if; + end if; + when first => + if(pvalid(index)='1')then + sofouts<='1'; + dataout<=pdata(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + pvalid(index)<='0'; + end if; + state<= sending; + when sending => + dataout <= datain(index)(15 downto 0); + datavalids<='1'; + wcounter<=unsigned(wcounter)+1; + sofouts <=datain(index)(16); + if(datain(index)(17)='1') then --EOF + reqdatas(index)<='0'; + if(wcounter(8)='1' or wcounter(7)='1')then + counter4(8 downto 0)<=wcounter; + end if; + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=kludge1; + --eofouts<='1'; + end if; + elsif(enabled='0')then + reqdatas(index)<='0'; + state<=paused;-- pause transmission + else + state<=sending; + end if; + when paused => + if(indatavalid(index)='1')then + dataout <= datain(index)(15 downto 0); + wcounter<=unsigned(wcounter)+1; + if(datain(index)(17)='1') then --EOF + if(wcounter(7 downto 0)=x"01")then -- pgp kludge, add an extra 2 words + state<=kludge1; + else + state<=kludge1; + --eofouts<='1'; + end if; + end if; + else + datavalids<='0'; + if(enabled='1')then + reqdatas(index)<='1'; + state<=first; + else + state<=paused; + end if; + end if; + end case; + end if; + + cdata(6)<=datain(index)(17); + cdata(7)<=eofouts; + cdata(8)<=datain(index)(16); + cdata(9)<=sofouts; + cdata(5)<=datavalids; + cdata(4)<=indatavalid(index); + cdata(3 downto 0)<=conv_std_logic_vector(index, 4); + cdata(17 downto 10)<=reqdatas(7 downto 0); + cdata(18)<=channelmask(index) and datawaiting(index) and enabled; + ctrig(0)<=channelmask(index) and datawaiting(index) and enabled; + + end process; + + --chipscope : chipscope_ila_new + -- port map ( + -- CONTROL => ccontrol, + -- CLK => clk, + -- DATA => cdata, + -- TRIG0 => ctrig); +-- chipscopeicon : chipscope_icon_new +-- port map ( +-- CONTROL0 => ccontrol); +-- + +end MULTIPLEXDATA; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/phaseshift.vhd b/rce/fw-hsio/modules/pixelcore/hdl/phaseshift.vhd new file mode 100644 index 0000000000000000000000000000000000000000..eac874a4139447f89a7daa7464bc9480a1fe85ad --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/phaseshift.vhd @@ -0,0 +1,131 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. +-------------------------------------------------------------------------------- +-- ____ ____ +-- / /\/ / +-- /___/ \ / Vendor: Xilinx +-- \ \ \/ Version : 10.1.03 +-- \ \ Application : xaw2vhdl +-- / / Filename : phaseshift.vhd +-- /___/ /\ Timestamp : 08/24/2009 10:21:32 +-- \ \ / \ +-- \___\/\___\ +-- +--Command: xaw2vhdl-st /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores//phaseshift.xaw /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores//phaseshift +--Design Name: phaseshift +--Device: xc4vfx60-10ff1152 +-- +-- Module phaseshift +-- Generated by Xilinx Architecture Wizard +-- Written for synthesis tool: Synplify + +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; +library UNISIM; +use UNISIM.Vcomponents.ALL; + +entity phaseshift is + port ( CLKIN_IN : in std_logic; + DADDR_IN : in std_logic_vector (6 downto 0); + DCLK_IN : in std_logic; + DEN_IN : in std_logic; + DI_IN : in std_logic_vector (15 downto 0); + DWE_IN : in std_logic; + RST_IN : in std_logic; + CLK0_OUT : out std_logic; + CLK90_OUT : out std_logic; + CLK180_OUT : out std_logic; + CLK270_OUT : out std_logic; + CLKFX_OUT : out std_logic; + CLK2X_OUT : out std_logic; + DRDY_OUT : out std_logic; + LOCKED_OUT : out std_logic; + + pclkUnbuf : out std_logic; + pclk90Unbuf : out std_logic; + pclk180Unbuf: out std_logic; + pclk270Unbuf: out std_logic + ); + +end phaseshift; + +architecture BEHAVIORAL of phaseshift is + signal CLKFB_IN : std_logic; + signal CLK0_BUF : std_logic; + signal CLK90_BUF : std_logic; + signal CLK180_BUF : std_logic; + signal CLK270_BUF : std_logic; + signal CLKFX_BUF : std_logic; + signal CLK2X_BUF : std_logic; +begin + CLK0_OUT <= CLKFB_IN; + pclkUnbuf <= CLK0_BUF; + pclk90Unbuf <= CLK90_BUF; + pclk180Unbuf <= CLK180_BUF; + pclk270Unbuf <= CLK270_BUF; + + CLK0_BUFG_INST : BUFG + port map (I=>CLK0_BUF, + O=>CLKFB_IN); + CLKFX_BUFG_INST : BUFG + port map (I=>CLKFX_BUF, + O=>CLKFX_OUT); + CLK2X_BUFG_INST : BUFG + port map (I=>CLK2X_BUF, + O=>CLK2X_OUT); + CLK90_BUFG_INST : BUFG + port map (I=>CLK90_BUF, + O=>CLK90_OUT); + CLK180_BUFG_INST : BUFG + port map (I=>CLK180_BUF, + O=>CLK180_OUT); + CLK270_BUFG_INST : BUFG + port map (I=>CLK270_BUF, + O=>CLK270_OUT); + + DCM_ADV_INST : DCM_ADV + generic map( CLK_FEEDBACK => "1X", + CLKDV_DIVIDE => 2.0, + CLKFX_DIVIDE => 32, + CLKFX_MULTIPLY => 16, + CLKIN_DIVIDE_BY_2 => FALSE, + CLKIN_PERIOD => 6.250, + CLKOUT_PHASE_SHIFT => "DIRECT", + DCM_AUTOCALIBRATION => TRUE, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "LOW", + DUTY_CYCLE_CORRECTION => TRUE, + FACTORY_JF => x"F0F0", + PHASE_SHIFT => 0, + STARTUP_WAIT => FALSE) + port map (CLKFB=>CLKFB_IN, + CLKIN=>CLKIN_IN, + DADDR(6 downto 0)=>DADDR_IN(6 downto 0), + DCLK=>DCLK_IN, + DEN=>DEN_IN, + DI(15 downto 0)=>DI_IN(15 downto 0), + DWE=>DWE_IN, + PSCLK=>'0', + PSEN=>'0', + PSINCDEC=>'0', + RST=>RST_IN, + CLKDV=>open, + CLKFX=>CLKFX_BUF, + CLKFX180=>open, + CLK0=>CLK0_BUF, + CLK2X=>CLK2X_BUF, + CLK2X180=>open, + CLK90=>CLK90_BUF, + CLK180=>CLK180_BUF, + CLK270=>CLK270_BUF, + DO=>open, + DRDY=>DRDY_OUT, + LOCKED=>LOCKED_OUT, + PSDONE=>open); + +end BEHAVIORAL; + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/ser.vhd b/rce/fw-hsio/modules/pixelcore/hdl/ser.vhd new file mode 100644 index 0000000000000000000000000000000000000000..820fe7138901cfcae935f7798ed56579a3e72524 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/ser.vhd @@ -0,0 +1,96 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity ser is + +port( clk: in std_logic; + ld: out std_logic; + l1a: in std_logic; + go: in std_logic; + busy: out std_logic; + stop: in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(15 downto 0); + d_out: out std_logic +); +end ser; + +-------------------------------------------------------------- + +architecture SER of ser is + +signal reg : std_logic_vector(15 downto 0); +signal busys: std_logic; +signal counter: std_logic_vector(3 downto 0); +signal l1acounter: std_logic_vector(2 downto 0); +signal going: std_logic; +signal oldl1a: std_logic; + +begin + + busy<=busys; + + process(rst, clk) + + begin + if(rst='1') then + reg<=x"0000"; + d_out<='0'; + going<='0'; + ld<='0'; + l1acounter<="000"; + oldl1a<='0'; + busys<='0'; + elsif (clk'event and clk='1') then + if (go='1' and stop='0' and busys='0')then + going<='1'; + counter<="0010"; + busys<='1'; + else + if (stop='1' and counter="0011") then + going<='0'; + end if; + if(counter="0010" and going='1') then -- it takes 2 cycles to + ld<='1'; -- get data from the FIFO; + elsif(counter="0001" and going='1') then + ld<='0'; -- Request is only 1 cycle long. + end if; + if (counter="0000" and going='1') then + reg<=d_in; + elsif (l1acounter="101")then + reg<=x"e800"; + else + reg(15 downto 1)<=reg(14 downto 0); + reg(0)<='0'; + end if; + if(l1acounter="010")then + busys<='0'; + elsif(going='0' and counter="0000" and l1acounter="000") then + busys<='0'; + end if; + if(l1a='1' and oldl1a='0' and busys='0')then + l1acounter<="101"; + busys<='1'; + elsif(l1acounter/="000")then + l1acounter<=unsigned(l1acounter)-1; + end if; + counter<=unsigned(counter)-1; + d_out<=reg(15); + end if; + oldl1a<=l1a; + end if; + + end process; + +end SER; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/ser32.vhd b/rce/fw-hsio/modules/pixelcore/hdl/ser32.vhd new file mode 100644 index 0000000000000000000000000000000000000000..af9a1e8723bdcfa6cf94de866d4ea7035094124d --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/ser32.vhd @@ -0,0 +1,72 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity ser32 is + +port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + busy: out std_logic; + stop: in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic +); +end ser32; + +-------------------------------------------------------------- + +architecture SER of ser32 is + +signal reg : std_logic_vector(31 downto 0); +signal counter: std_logic_vector(4 downto 0); +signal going: std_logic; + +begin + + busy<=going; + d_out<=reg(31); + process(rst, clk) + + begin + if(rst='1') then + reg<=x"00000000"; + going<='0'; + ld<='0'; + elsif (clk'event and clk='1') then + if (go='1')then + going<='1'; + counter<="00000"; + else + if (stop='1' and counter="00011") then + going<='0'; + end if; + if(counter="00010" and going='1') then -- it takes 2 cycles to + ld<='1'; -- get data from the FIFO; + elsif(counter="00001" and going='1') then + ld<='0'; -- Request is only 1 cycle long. + end if; + if (counter="00000" and going='1') then + reg<=d_in; + else + reg(31 downto 1)<=reg(30 downto 0); + reg(0)<='0'; + end if; + counter<=unsigned(counter)-1; + end if; + end if; + + end process; + +end SER; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/stdlib.vhd b/rce/fw-hsio/modules/pixelcore/hdl/stdlib.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2e724fd71a185aa8a546f784f5c8e3b6ab7fc03c --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/stdlib.vhd @@ -0,0 +1,603 @@ +------------------------------------------------------------------------------ +-- This file is a part of the GRLIB VHDL IP LIBRARY +-- Copyright (C) 2003 - 2008, Gaisler Research +-- Copyright (C) 2008 - 2012, Aeroflex Gaisler +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +----------------------------------------------------------------------------- +-- Package: stdlib +-- File: stdlib.vhd +-- Author: Jiri Gaisler - Gaisler Research +-- Description: Package for common VHDL functions +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +-- pragma translate_off +use std.textio.all; +-- pragma translate_on +--library grlib; +--use grlib.version.all; + +package stdlib is + +--constant LIBVHDL_VERSION : integer := grlib_version; +--constant LIBVHDL_BUILD : integer := grlib_build; +---- pragma translate_off +--constant LIBVHDL_DATE : string := grlib_date; +---- pragma translate_on +constant zero32 : std_logic_vector(31 downto 0) := (others => '0'); +constant zero64 : std_logic_vector(63 downto 0) := (others => '0'); +constant zero128 : std_logic_vector(127 downto 0) := (others => '0'); +constant one32 : std_logic_vector(31 downto 0) := (others => '1'); +constant one64 : std_logic_vector(63 downto 0) := (others => '1'); +constant one128 : std_logic_vector(127 downto 0) := (others => '1'); + +type log2arr is array(0 to 512) of integer; +constant log2 : log2arr := ( +0,0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + others => 9); +constant log2x : log2arr := ( +0,1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + others => 9); + +function decode(v : std_logic_vector) return std_logic_vector; +function genmux(s,v : std_logic_vector) return std_ulogic; +function xorv(d : std_logic_vector) return std_ulogic; +function orv(d : std_logic_vector) return std_ulogic; +function andv(d : std_logic_vector) return std_ulogic; +function notx(d : std_logic_vector) return boolean; +function notx(d : std_ulogic) return boolean; +function "-" (d : std_logic_vector; i : integer) return std_logic_vector; +function "-" (i : integer; d : std_logic_vector) return std_logic_vector; +function "+" (d : std_logic_vector; i : integer) return std_logic_vector; +function "+" (i : integer; d : std_logic_vector) return std_logic_vector; +function "-" (d : std_logic_vector; i : std_ulogic) return std_logic_vector; +function "+" (d : std_logic_vector; i : std_ulogic) return std_logic_vector; +function "-" (a, b : std_logic_vector) return std_logic_vector; +function "+" (a, b : std_logic_vector) return std_logic_vector; +function "*" (a, b : std_logic_vector) return std_logic_vector; +function unsigned_mul (a, b : std_logic_vector) return std_logic_vector; +function signed_mul (a, b : std_logic_vector) return std_logic_vector; +function mixed_mul (a, b : std_logic_vector; sign : std_logic) return std_logic_vector; +--function ">" (a, b : std_logic_vector) return boolean; +function "<" (i : integer; b : std_logic_vector) return boolean; +function conv_integer(v : std_logic_vector) return integer; +function conv_integer(v : std_logic) return integer; +function conv_std_logic_vector(i : integer; w : integer) return std_logic_vector; +function conv_std_logic_vector_signed(i : integer; w : integer) return std_logic_vector; +function conv_std_logic(b : boolean) return std_ulogic; +attribute sync_set_reset : string; +attribute async_set_reset : string; + +-- Reporting and diagnostics + +-- pragma translate_off + +function tost(v:std_logic_vector) return string; +function tost(v:std_logic) return string; +function tost(i : integer) return string; +function tost_any(s: std_ulogic) return string; +function tost_bits(s: std_logic_vector) return string; +function tost(b: boolean) return string; +function tost(r: real) return string; +procedure print(s : string); + +component report_version + generic (msg1, msg2, msg3, msg4 : string := ""; mdel : integer := 4); +end component; + +-- pragma translate_on + +end; + +package body stdlib is + +function notx(d : std_logic_vector) return boolean is +variable res : boolean; +begin + res := true; +-- pragma translate_off + res := not is_x(d); +-- pragma translate_on + return (res); +end; + +function notx(d : std_ulogic) return boolean is +variable res : boolean; +begin + res := true; +-- pragma translate_off + res := not is_x(d); +-- pragma translate_on + return (res); +end; + +-- generic decoder + +function decode(v : std_logic_vector) return std_logic_vector is +variable res : std_logic_vector((2**v'length)-1 downto 0); +variable i : integer range res'range; +begin + res := (others => '0'); i := 0; + if notx(v) then i := to_integer(unsigned(v)); end if; + res(i) := '1'; + return(res); +end; + +-- generic multiplexer + +function genmux(s,v : std_logic_vector) return std_ulogic is +variable res : std_logic_vector(v'length-1 downto 0); +variable i : integer range res'range; +begin + res := v; i := 0; + if notx(s) then i := to_integer(unsigned(s)); end if; + return(res(i)); +end; + +-- vector XOR + +function xorv(d : std_logic_vector) return std_ulogic is +variable tmp : std_ulogic; +begin + tmp := '0'; + for i in d'range loop tmp := tmp xor d(i); end loop; + return(tmp); +end; + +-- vector OR + +function orv(d : std_logic_vector) return std_ulogic is +variable tmp : std_ulogic; +begin + tmp := '0'; + for i in d'range loop tmp := tmp or d(i); end loop; + return(tmp); +end; + +-- vector AND + +function andv(d : std_logic_vector) return std_ulogic is +variable tmp : std_ulogic; +begin + tmp := '1'; + for i in d'range loop tmp := tmp and d(i); end loop; + return(tmp); +end; + +-- unsigned multiplication + +function "*" (a, b : std_logic_vector) return std_logic_vector is +variable z : std_logic_vector(a'length+b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + return(std_logic_vector(unsigned(a) * unsigned(b))); +-- pragma translate_off + else + z := (others =>'X'); return(z); + end if; +-- pragma translate_on +end; + +-- signed multiplication + +function signed_mul (a, b : std_logic_vector) return std_logic_vector is +variable z : std_logic_vector(a'length+b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + return(std_logic_vector(signed(a) * signed(b))); +-- pragma translate_off + else + z := (others =>'X'); return(z); + end if; +-- pragma translate_on +end; + +-- unsigned multiplication + +function unsigned_mul (a, b : std_logic_vector) return std_logic_vector is +variable z : std_logic_vector(a'length+b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + return(std_logic_vector(unsigned(a) * unsigned(b))); +-- pragma translate_off + else + z := (others =>'X'); return(z); + end if; +-- pragma translate_on +end; + +-- signed/unsigned multiplication + +function mixed_mul (a, b : std_logic_vector; sign : std_logic) return std_logic_vector is +variable z : std_logic_vector(a'length+b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + if sign = '0' then + return(std_logic_vector(unsigned(a) * unsigned(b))); + else + return(std_logic_vector(signed(a) * signed(b))); + end if; +-- pragma translate_off + else + z := (others =>'X'); return(z); + end if; +-- pragma translate_on +end; + +-- unsigned addition + +function "+" (a, b : std_logic_vector) return std_logic_vector is +variable x : std_logic_vector(a'length-1 downto 0); +variable y : std_logic_vector(b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + return(std_logic_vector(unsigned(a) + unsigned(b))); +-- pragma translate_off + else + x := (others =>'X'); y := (others =>'X'); + if (x'length > y'length) then return(x); else return(y); end if; + end if; +-- pragma translate_on +end; + +function "+" (i : integer; d : std_logic_vector) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +begin +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(unsigned(d) + i)); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +function "+" (d : std_logic_vector; i : integer) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +begin +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(unsigned(d) + i)); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +function "+" (d : std_logic_vector; i : std_ulogic) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +variable y : std_logic_vector(0 downto 0); +begin + y(0) := i; +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(unsigned(d) + unsigned(y))); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +-- unsigned subtraction + +function "-" (a, b : std_logic_vector) return std_logic_vector is +variable x : std_logic_vector(a'length-1 downto 0); +variable y : std_logic_vector(b'length-1 downto 0); +begin +-- pragma translate_off + if notx(a&b) then +-- pragma translate_on + return(std_logic_vector(unsigned(a) - unsigned(b))); +-- pragma translate_off + else + x := (others =>'X'); y := (others =>'X'); + if (x'length > y'length) then return(x); else return(y); end if; + end if; +-- pragma translate_on +end; + +function "-" (d : std_logic_vector; i : integer) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +begin +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(unsigned(d) - i)); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +function "-" (i : integer; d : std_logic_vector) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +begin +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(i - unsigned(d))); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +function "-" (d : std_logic_vector; i : std_ulogic) return std_logic_vector is +variable x : std_logic_vector(d'length-1 downto 0); +variable y : std_logic_vector(0 downto 0); +begin + y(0) := i; +-- pragma translate_off + if notx(d) then +-- pragma translate_on + return(std_logic_vector(unsigned(d) - unsigned(y))); +-- pragma translate_off + else x := (others =>'X'); return(x); + end if; +-- pragma translate_on +end; + +function ">=" (a, b : std_logic_vector) return boolean is +begin + return(unsigned(a) >= unsigned(b)); +end; + +function "<" (i : integer; b : std_logic_vector) return boolean is +begin + return( i < to_integer(unsigned(b))); +end; + +function ">" (a, b : std_logic_vector) return boolean is +begin + return(unsigned(a) > unsigned(b)); +end; + +function conv_integer(v : std_logic_vector) return integer is +begin + if notx(v) then return(to_integer(unsigned(v))); + else return(0); end if; +end; + +function conv_integer(v : std_logic) return integer is +begin + if notx(v) then + if v = '1' then return(1); + else return(0); end if; + else return(0); end if; +end; + +function conv_std_logic_vector(i : integer; w : integer) return std_logic_vector is +variable tmp : std_logic_vector(w-1 downto 0); +begin + tmp := std_logic_vector(to_unsigned(i, w)); + return(tmp); +end; + +function conv_std_logic_vector_signed(i : integer; w : integer) return std_logic_vector is +variable tmp : std_logic_vector(w-1 downto 0); +begin + tmp := std_logic_vector(to_signed(i, w)); + return(tmp); +end; + +function conv_std_logic(b : boolean) return std_ulogic is +begin + if b then return('1'); else return('0'); end if; +end; + +-- pragma translate_off +subtype nibble is std_logic_vector(3 downto 0); + +function todec(i:integer) return character is +begin + case i is + when 0 => return('0'); + when 1 => return('1'); + when 2 => return('2'); + when 3 => return('3'); + when 4 => return('4'); + when 5 => return('5'); + when 6 => return('6'); + when 7 => return('7'); + when 8 => return('8'); + when 9 => return('9'); + when others => return('0'); + end case; +end; + +function tohex(n:nibble) return character is +begin + case n is + when "0000" => return('0'); + when "0001" => return('1'); + when "0010" => return('2'); + when "0011" => return('3'); + when "0100" => return('4'); + when "0101" => return('5'); + when "0110" => return('6'); + when "0111" => return('7'); + when "1000" => return('8'); + when "1001" => return('9'); + when "1010" => return('a'); + when "1011" => return('b'); + when "1100" => return('c'); + when "1101" => return('d'); + when "1110" => return('e'); + when "1111" => return('f'); + when others => return('X'); + end case; +end; + +function tost(v:std_logic_vector) return string is +constant vlen : natural := v'length; --' +constant slen : natural := (vlen+3)/4; +variable vv : std_logic_vector(0 to slen*4-1) := (others => '0'); +variable s : string(1 to slen); +variable nz : boolean := false; +variable index : integer := -1; +begin + vv(slen*4-vlen to slen*4-1) := v; + for i in 0 to slen-1 loop + if (vv(i*4 to i*4+3) = "0000") and nz and (i /= (slen-1)) then + index := i; + else + nz := false; + s(i+1) := tohex(vv(i*4 to i*4+3)); + end if; + end loop; + if ((index +2) = slen) then return(s(slen to slen)); + else return(string'("0x") & s(index+2 to slen)); end if; --' +end; + +function tost(v:std_logic) return string is +begin + if to_x01(v) = '1' then return("1"); else return("0"); end if; +end; + +function tost_any(s: std_ulogic) return string is +begin + case s is + when '1' => return "1"; + when '0' => return "0"; + when '-' => return "-"; + when 'U' => return "U"; + when 'X' => return "X"; + when 'Z' => return "Z"; + when 'H' => return "H"; + when 'L' => return "L"; + when 'W' => return "W"; + end case; +end; + +function tost_bits(s: std_logic_vector) return string is + constant len: natural := s'length; + variable str: string(1 to len); + variable i: integer; +begin + i := 1; + for x in s'range loop + str(i to i) := tost_any(s(x)); + i := i+1; + end loop; + return str; +end; + +function tost(b: boolean) return string is +begin + if b then return "true"; else return "false"; end if; +end tost; + +function tost(i : integer) return string is +variable L : line; +variable s, x : string(1 to 128); +variable n, tmp : integer := 0; +begin + tmp := i; + if i < 0 then tmp := -i; end if; + loop + s(128-n) := todec(tmp mod 10); + tmp := tmp / 10; + n := n+1; + if tmp = 0 then exit; end if; + end loop; + x(1 to n) := s(129-n to 128); + if i < 0 then return "-" & x(1 to n); end if; + return(x(1 to n)); +end; + +function tost(r: real) return string is + variable x: real; + variable i,j: integer; + variable s: string(1 to 30); + variable c: character; +begin + if r = 0.0 then + return "0.0000"; + elsif r < 0.0 then + return "-" & tost(-r); + elsif r < 0.001 then + x:=r; i:=0; + while x<1.0 loop x:=x*10.0; i:=i+1; end loop; + return tost(x) & "e-" & tost(i); + elsif r >= 1000000.0 then + x:=10000000.0; i:=6; + while r>=x loop x:=x*10.0; i:=i+1; end loop; + return tost(10.0*r/x) & "e+" & tost(i); + else + i:=0; x:=r+0.00005; + while x >= 10.0 loop x:=x/10.0; i:=i+1; end loop; + j := 1; + while i > -5 loop + if x >= 9.0 then c:='9'; x:=x-9.0; + elsif x >= 8.0 then c:='8'; x:=x-8.0; + elsif x >= 7.0 then c:='7'; x:=x-7.0; + elsif x >= 6.0 then c:='6'; x:=x-6.0; + elsif x >= 5.0 then c:='5'; x:=x-5.0; + elsif x >= 4.0 then c:='4'; x:=x-4.0; + elsif x >= 3.0 then c:='3'; x:=x-3.0; + elsif x >= 2.0 then c:='2'; x:=x-2.0; + elsif x >= 1.0 then c:='1'; x:=x-1.0; + else c:='0'; + end if; + s(j) := c; + j:=j+1; + if i=0 then s(j):='.'; j:=j+1; end if; + i:=i-1; + x := x * 10.0; + end loop; + return s(1 to j-1); + end if; +end tost; + +procedure print(s : string) is + variable L : line; +begin + L := new string'(s); writeline(output, L); +end; + +-- pragma translate_on +end; + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/syncdatac.vhd b/rce/fw-hsio/modules/pixelcore/hdl/syncdatac.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ad8b92078310fee85bdca43fa323c21d182f0ba5 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/syncdatac.vhd @@ -0,0 +1,317 @@ +------------------------------------------------------------------------------ +-- +-- Xilinx, Inc. 2002 www.xilinx.com +-- +-- XAPP 225 +-- +------------------------------------------------------------------------------ +-- +-- File name : sync_master_v2.vhd +-- +-- Description : Master phase aligner module for Virtex2 (2 bits) +-- +-- Date - revision : January 6th 2009 - v 1.2 +-- +-- Author : NJS +-- +-- Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are +-- provided to you "as is". Xilinx and its licensors make and you +-- receive no warranties or conditions, express, implied, +-- statutory or otherwise, and Xilinx specifically disclaims any +-- implied warranties of merchantability, non-infringement,or +-- fitness for a particular purpose. Xilinx does not warrant that +-- the functions contained in these designs will meet your +-- requirements, or that the operation of these designs will be +-- uninterrupted or error free, or that defects in the Designs +-- will be corrected. Furthermore, Xilinx does not warrantor +-- make any representations regarding use or the results of the +-- use of the designs in terms of correctness, accuracy, +-- reliability, or otherwise. +-- +-- LIMITATION OF LIABILITY. In no event will Xilinx or its +-- licensors be liable for any loss of data, lost profits,cost +-- or procurement of substitute goods or services, or for any +-- special, incidental, consequential, or indirect d[DX] Dependencies for CalibGui.cc +-- arising from the use or operation of the designs or +-- accompanying documentation, however caused and on any theory +-- of liability. This limitation will apply even if Xilinx +-- has been advised of the possibility of such damage. This +-- limitation shall apply not-withstanding the failure of the +-- essential purpose of any limited remedies herein. +-- +-- Copyright ยฉ 2002 Xilinx, Inc. +-- All rights reserved +-- +------------------------------------------------------------------------------ +-- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +library unisim ; +use unisim.vcomponents.all ; + +entity syncdatac is port ( + clk : in std_logic ; -- clock input + clk90 : in std_logic ; -- clock 90 input + rdatain : in std_logic; -- data input + rst : in std_logic ; -- reset input + useaout : out std_logic ; -- useA output for cascade + usebout : out std_logic ; -- useB output for cascade + usecout : out std_logic ; -- useC output for cascade + usedout : out std_logic ; -- useD output for cascade +-- useain : in std_logic ; -- useA output for cascade +-- usebin : in std_logic ; -- useB output for cascade +-- usecin : in std_logic ; -- useC output for cascade +-- usedin : in std_logic ; -- useD output for cascade + sdataout : out std_logic; -- data out + phaseConfig : in std_logic); -- Flag for calibration +end syncdatac; + +architecture arch_syncdata of syncdatac is + +-- component chipscope_ila +-- PORT ( +-- CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); +-- CLK : IN STD_LOGIC; +-- DATA : IN STD_LOGIC_VECTOR(15 DOWNTO 0); +-- TRIG0 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)); + +-- end component; + +-- component chipscope_icon +-- PORT ( +-- CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- end component; + +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of ila : label is true; +-- attribute syn_noprune of icon : label is true; + + +signal aa0 : std_logic; +signal bb0 : std_logic; +signal cc0 : std_logic; +signal dd0 : std_logic; +signal usea : std_logic; +signal useb : std_logic; +signal usec : std_logic; +signal used : std_logic; +signal useaint : std_logic; +signal usebint : std_logic; +signal usecint : std_logic; +signal usedint : std_logic; +signal ctrlint : std_logic_vector(1 downto 0); +signal sdataa : std_logic; +signal sdatab : std_logic; +signal sdatac : std_logic; +signal sdatad : std_logic; +signal az : std_logic_vector(2 downto 0) ; +signal bz : std_logic_vector(2 downto 0) ; +signal cz : std_logic_vector(2 downto 0) ; +signal dz : std_logic_vector(2 downto 0) ; +signal aap, bbp : std_logic; +signal aan, bbn : std_logic; +signal ccp, ddp : std_logic; +signal ccn, ddn : std_logic; +signal pipe_ce0 : std_logic; +signal notclk : std_logic; +signal notclk90 : std_logic; + +-- signal control : std_logic_vector(35 downto 0) ; + + +-- FS: Counters to determine most likely phase +signal countera : std_logic_vector(7 downto 0); +signal counterb : std_logic_vector(7 downto 0); +signal counterc : std_logic_vector(7 downto 0); +signal counterd : std_logic_vector(7 downto 0); + +signal useatemp : std_logic; +signal usebtemp : std_logic; +signal usectemp : std_logic; +signal usedtemp : std_logic; + +-- signal data : std_logic_vector(15 downto 0); +-- signal trigger : std_logic_vector(7 downto 0); +signal count : std_logic; +signal changed : std_logic; + + + + +attribute RLOC : string ; +attribute RLOC of ff_az0 : label is "X0Y2"; +attribute RLOC of ff_az1 : label is "X0Y2"; + +attribute RLOC of ff_bz0 : label is "X0Y1"; +attribute RLOC of ff_bz1 : label is "X1Y1"; + +attribute RLOC of ff_cz0 : label is "X1Y0"; +attribute RLOC of ff_cz1 : label is "X1Y1"; + +attribute RLOC of ff_dz0 : label is "X0Y0"; +attribute RLOC of ff_dz1 : label is "X0Y1"; + + + +begin + +notclk <= not clk ; +notclk90 <= not clk90 ; +useaout <= useaint ; +usebout <= usebint ; +usecout <= usecint ; +usedout <= usedint ; +sdataa <= (aa0 and useaint) ; +sdatab <= (bb0 and usebint) ; +sdatac <= (cc0 and usecint) ; +sdatad <= (dd0 and usedint) ; + +saa0 : srl16 port map(d => az(2), clk => clk, a0 => ctrlint(0), a1 => ctrlint(1), a2 => '0', a3 => '0', q => aa0); +sbb0 : srl16 port map(d => bz(2), clk => clk, a0 => ctrlint(0), a1 => ctrlint(1), a2 => '0', a3 => '0', q => bb0); +scc0 : srl16 port map(d => cz(2), clk => clk, a0 => ctrlint(0), a1 => ctrlint(1), a2 => '0', a3 => '0', q => cc0); +sdd0 : srl16 port map(d => dz(2), clk => clk, a0 => ctrlint(0), a1 => ctrlint(1), a2 => '0', a3 => '0', q => dd0); + + +process (clk, rst) +begin +if rst = '1' then + ctrlint <= "10" ; + useaint <= '0' ; usebint <= '0' ; usecint <= '0' ; usedint <= '0' ; + usea <= '0' ; useb <= '0' ; usec <= '0' ; used <= '0' ; + useatemp <= '0';usebtemp <= '0';usectemp <= '0';usedtemp <= '0'; + pipe_ce0 <= '0' ; sdataout <= '0' ; + aap <= '0' ; bbp <= '0' ; ccp <= '0' ; ddp <= '0' ; + aan <= '0' ; bbn <= '0' ; ccn <= '0' ; ddn <= '0' ; + az(2) <= '0' ; bz(2) <= '0' ; cz(2) <= '0' ; dz(2) <= '0' ; + countera <= "00000000"; counterb <= "00000000"; counterc <= "00000000"; counterd <= "00000000"; + count <= '0'; + changed <= '0'; +elsif clk'event and clk = '1' then + az(2) <= az(1) ; bz(2) <= bz(1) ; cz(2) <= cz(1) ; dz(2) <= dz(1) ; + aap <= (az(2) xor az(1)) and not az(1) ; -- find positive edges + bbp <= (bz(2) xor bz(1)) and not bz(1) ; + ccp <= (cz(2) xor cz(1)) and not cz(1) ; + ddp <= (dz(2) xor dz(1)) and not dz(1) ; + aan <= (az(2) xor az(1)) and az(1) ; -- find negative edges + bbn <= (bz(2) xor bz(1)) and bz(1) ; + ccn <= (cz(2) xor cz(1)) and cz(1) ; + ddn <= (dz(2) xor dz(1)) and dz(1) ; + useatemp <= (bbp and not ccp and not ddp and aap) or (bbn and not ccn and not ddn and aan) ; + usebtemp <= (ccp and not ddp and aap and bbp) or (ccn and not ddn and aan and bbn) ; + usectemp <= (ddp and aap and bbp and ccp) or (ddn and aan and bbn and ccn) ; + usedtemp <= (aap and not bbp and not ccp and not ddp) or (aan and not bbn and not ccn and not ddn) ; +-- usea<=useain; +-- useb<=usebin; +-- usec<=usecin; +-- used<=usedin; + + if phaseConfig = '1' then + count <= '1'; + end if; + + + if count = '1' then + if useatemp='1' then -- FS: Only one of the usex equal 1 + countera <= countera+1; + elsif usebtemp='1' then + counterb <= counterb+1; + elsif usectemp='1' then + counterc <= counterc+1; + elsif usedtemp='1' then + counterd <= counterd+1; + end if; + end if; +-- data(7) <= useatemp; +-- data(6) <= usebtemp; +-- data(5) <= usectemp; +-- data(4) <= usedtemp; + + if countera = "11111111" then -- FS: . . . and set the one reaching the end of the counter + usea <= '1'; + useb <= '0'; + usec <= '0'; + used <= '0'; + changed <= '1'; + + elsif counterb = "11111111" then + usea <= '0'; + useb <= '1'; + usec <= '0'; + used <= '0'; + changed <= '1'; + + elsif counterc = "11111111" then + usea <= '0'; + useb <= '0'; + usec <= '1'; + used <= '0'; + changed <= '1'; + + elsif counterd = "11111111" then + usea <= '0'; + useb <= '0'; + usec <= '0'; + used <= '1'; + changed <= '1'; + + elsif changed = '1' then + changed <= '0'; + pipe_ce0 <= '1' ; + useaint <= usea ; + usebint <= useb ; + usecint <= usec ; + usedint <= used ; + + -- data(3) <= usea; + -- data(2) <= useb; + -- data(1) <= usec; + -- data(0) <= used; + + countera <= "00000000"; -- FS: Reset all counters if one of them has reached the end + counterb <= "00000000"; + counterc <= "00000000"; + counterd <= "00000000"; + count <= '0'; + end if ; + if pipe_ce0 = '1' then + sdataout <= sdataa or sdatab or sdatac or sdatad ; + end if ; + if usedint = '1' and usea = '1' then -- 'd' going to 'a' + ctrlint <= ctrlint - 1 ; + elsif useaint = '1' and used = '1' then -- 'a' going to 'd' + ctrlint <= ctrlint + 1 ; + end if ; +end if ; +end process ; + +-- get all the samples into the same time domain + +ff_az0 : fdc port map(d => rdatain, c => clk, clr => rst, q => az(0)); +ff_az1 : fdc port map(d => az(0), c => clk, clr => rst, q => az(1)); + +ff_bz0 : fdc port map(d => rdatain, c => clk90, clr => rst, q => bz(0)); +ff_bz1 : fdc port map(d => bz(0), c => clk, clr => rst, q => bz(1)); + +ff_cz0 : fdc port map(d => rdatain, c => notclk, clr => rst, q => cz(0)); +ff_cz1 : fdc port map(d => cz(0), c => clk, clr => rst, q => cz(1)); + +ff_dz0 : fdc port map(d => rdatain, c => notclk90, clr => rst, q => dz(0)); +ff_dz1 : fdc port map(d => dz(0), c => clk90, clr => rst, q => dz(1)); + +-- trigger <= "0000000" & phaseConfig; + + +-- icon : chipscope_icon +-- port map ( +-- CONTROL0 => control); + +-- ila : chipscope_ila +-- port map ( +-- CONTROL => control, +-- CLK => clk, +-- DATA => data, +-- TRIG0 => trigger); + +end arch_syncdata; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/tdc.vhd b/rce/fw-hsio/modules/pixelcore/hdl/tdc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b916b5b19306b3903c88f106cad55ad18a7a5200 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/tdc.vhd @@ -0,0 +1,215 @@ + +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity tdc is + +port( sysclk: in std_logic; + sysrst: in std_logic; + edge1: in std_logic; + edge2: in std_logic; + start: in std_logic; + ready: out std_logic; + counter1: out std_logic_vector(31 downto 0); + counter2: out std_logic_vector(31 downto 0) +); +end tdc; + +--------------------------------------------------------------- + +architecture TDC of tdc is + component FDCPE + generic(INIT:bit:='0'); + port( + Q : out std_logic; + C : in STD_LOGIC; + CE : in STD_LOGIC; + CLR : in STD_LOGIC; + D : in STD_LOGIC; + PRE : in STD_LOGIC); + end component; + component LUT1_D + generic(INIT:bit_vector(1 downto 0)); + port( + LO: out std_logic; + O : out std_logic; + I0: in std_logic + ); + end component; + component BUFG + port ( + O: out std_logic; + I: in std_logic + ); + end component; + component BUFR + generic (BUFR_DIVIDE : string := "BYPASS"); + port ( + O: out std_logic; + CE: in std_logic; + CLR: in std_logic; + I: in std_logic + ); + end component; + constant numdel:integer:=64; + attribute LUT_MAP : string; + attribute LUT_MAP of LUT1_D : component is "lut"; + signal clear: std_logic; + signal isready: std_logic; + signal oldstart: std_logic; + signal oldoldstart: std_logic; + signal controlstop: std_logic; + signal controlstopb: std_logic; + signal controlstartb: std_logic; + signal carry: std_logic_vector(numdel downto 0); + signal result: std_logic_vector(numdel-1 downto 0); + signal localtap: std_logic_vector(numdel-1 downto 0); + signal ss: std_logic_vector(numdel-1 downto 0); + signal st: std_logic_vector(numdel-1 downto 0); + + attribute U_SET: string; + attribute RLOC: string; + attribute U_SET of startcontrol: label is "TDC"; + attribute RLOC of startcontrol : label is "X0Y-1"; + attribute U_SET of stopcontrol: label is "TDC"; + attribute RLOC of stopcontrol : label is "X0Y0"; + + --attribute U_SET of MUX: label is "TDC"; + attribute Keep: boolean; + attribute Keep of carry : signal is true; + attribute Keep of localtap : signal is true; + attribute Keep of controlstop : signal is true; + attribute Keep of ss : signal is true; + attribute Keep of st : signal is true; + attribute OPT: string; + attribute OPT of carry : signal is "KEEP"; + attribute OPT of localtap : signal is "KEEP"; + attribute OPT of controlstop : signal is "KEEP"; + attribute OPT of st : signal is "KEEP"; +begin + ready<=isready; + process (sysrst, sysclk) + begin + if(sysrst='1') then + isready<='0'; + oldstart<='0'; + oldoldstart<='0'; + clear<='1'; + elsif(rising_edge(sysclk)) then + if(start='1' and oldstart='0')then + clear<='1'; + elsif(oldstart='1' and oldoldstart='0')then + clear<='0'; + isready<='1'; + elsif(controlstop='1')then + isready<='0'; + end if; + oldstart<=start; + oldoldstart<=oldstart; + end if; + end process; + + CHAIN: + for I in 0 to numdel-1 generate + constant lfour :natural:=(I mod 8)/4; + constant sfour :natural:= 1-lfour; + constant row :natural:=sfour*((I mod 4)*2+(I/8) mod 2)+lfour*(6-(I mod 4)*2 + (I/8) mod 2); + constant column:natural:=((I/4)mod 2)*2+I/32+1; + constant rloc_str : string := "X" & natural'image(row) & "Y" & natural'image(column); + attribute RLOC of TAP: label is rloc_str; + attribute RLOC of DELAYY: label is rloc_str; + attribute U_SET of TAP: label is "TDC"; + attribute U_SET of DELAYY: label is "TDC"; + begin + TAP: FDCPE + port map ( + Q=>result(I), + C=>controlstop, + CE=>'1', + CLR=>clear, + D=>st(i), --localtap(I), + PRE=>'0' + ); + -- MUX: MUXF5_D + -- port map ( + -- LO => localtap(I), + -- O => carry(I+1), + -- I0 => ss(I), + -- I1 => carry(I), + -- S => '1' + -- ); + -- DELAYX: LUT1_D + -- generic map ( INIT => "11" ) + -- port map ( + -- LO => ss(I), + -- O => open, + -- I0 => isready + -- ); + DELAYY: LUT1_D + generic map ( INIT => "10" ) + port map ( + LO => st(I), + O => carry(I+1), + I0 => carry(I) + ); + end generate CHAIN; + + + + startcontrol: FDCPE + port map ( + Q=>carry(0), + C=>edge1, + CE=>'1', + CLR=>clear, + D=>'1', + PRE=>'0' + ); + stopcontrol: FDCPE + port map ( + Q=>controlstopb, + C=>edge2, + CE=>carry(0), + CLR=>clear, + D=>'1', + PRE=>'0' + ); + -- BUFG_stop: BUFG + -- port map( + -- O => controlstop, + -- I => controlstopb + -- ); + BUFR_stop : BUFR + generic map ( + BUFR_DIVIDE => "BYPASS") + port map ( + O => controlstop, -- Clock buffer output + CE => '1', -- Clock enable input + CLR => '0', -- Clock buffer reset input + I => controlstopb -- Clock buffer input + ); + --BUFG_start: BUFG + --port map( + --O => carry(0), + --I => controlstartb + --); + +-- ex: for i in 0 to numdel/2-1 generate +-- counter1(i)<=result(I*2); +-- end generate ex; + counter1<=result(31 downto 0); + counter2<=result(63 downto 32); +end TDC; + + + + diff --git a/rce/fw-hsio/modules/pixelcore/hdl/tdcreadout.vhd b/rce/fw-hsio/modules/pixelcore/hdl/tdcreadout.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0a72733bbb2e36cc8de80241e1acd6e0cf029d42 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/tdcreadout.vhd @@ -0,0 +1,176 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.all; + +-------------------------------------------------------------- + +entity tdcreadout is +generic( CHANNEL: std_logic_vector:="1111"); +port( clk: in std_logic; + rst: in std_logic; + slowclock: in std_logic; + go: in std_logic; + delay: in std_logic_vector(4 downto 0); + counter1: in std_logic_vector(31 downto 0); + counter2: in std_logic_vector(31 downto 0); + trgtime: in std_logic_vector(63 downto 0); + deadtime: in std_logic_vector(63 downto 0); + status: in std_logic_vector(14 downto 0); + marker: in std_logic; + l1count: in std_logic_vector(3 downto 0); + bxid : in std_logic_vector(7 downto 0); + d_out: out std_logic_vector(15 downto 0); + ld: out std_logic; + busy: out std_logic; + sof: out std_logic; + eof: out std_logic; + runmode: in std_logic_vector(1 downto 0); + eudaqdone: in std_logic; + eudaqtrgword: in std_logic_vector(14 downto 0); + fifothresh: in std_logic_vector(7 downto 0); + triggerword:in std_logic_vector(7 downto 0) +); +end tdcreadout; + +-------------------------------------------------------------- + +architecture TDCREADOUT of tdcreadout is + + signal headercounter: unsigned (5 downto 0); + signal busys: std_logic; + signal marked: std_logic; + signal eventmark: std_logic; + signal waitforeudaq: std_logic; + signal oldbusys: std_logic; + signal oldoldbusys: std_logic; + +begin + + busy<=oldoldbusys; + process(rst, slowclock) + begin + if(rst='1')then + oldbusys<='0'; + oldoldbusys<='0'; + elsif (rising_edge(slowclock))then + oldbusys<=busys; + oldoldbusys<=oldbusys; + end if; + end process; + + process(rst, clk) + begin + if(rst='1') then + d_out<=x"0000"; + eof<='0'; + sof<='0'; + headercounter<=(others => '0'); + ld<='0'; + busys<='0'; + marked<='0'; + eventmark<='0'; + waitforeudaq<='0'; + elsif (clk'event and clk='1') then + if(marker='1')then + eventmark<='1'; + elsif(marked='1')then + eventmark<='0'; + end if; + if(busys='0' and go='1')then + busys<='1'; + eof<='0'; + headercounter<=unsigned('0'&delay)+31; + if(delay="00000") then + sof<='1'; + ld<='1'; + end if; + d_out<=x"0000"; + elsif (headercounter/=0)then + if (headercounter=32) then + sof<='1'; + ld<='1'; + elsif (headercounter=31) then + sof<='0'; + d_out(7 downto 0)<=(others=>'0'); + d_out(15 downto 8)<=x"0"&CHANNEL; + --d_out<=tid(23 downto 8); + elsif(headercounter=30) then + d_out<=x"0000"; + elsif(headercounter=29) then + d_out<=eventmark&"000"&x"000"; + elsif(headercounter=28) then + d_out<=x"0000"; + elsif(headercounter=16) then + d_out<=x"0" & l1count & bxid; + elsif(headercounter=15) then + d_out<=eventmark&status; + elsif(headercounter=14) then + d_out<=counter1(31 downto 16); + elsif(headercounter=13) then + d_out<=counter1(15 downto 0); + elsif(headercounter=12) then + d_out<=counter2(31 downto 16); + elsif(headercounter=11) then + d_out<=counter2(15 downto 0); + elsif(headercounter=10) then + d_out<=trgtime(63 downto 48); + elsif(headercounter=9) then + d_out<=trgtime(47 downto 32); + elsif(headercounter=8) then + d_out<=trgtime(31 downto 16); + elsif(headercounter=7) then + d_out<=trgtime(15 downto 0); + elsif(headercounter=6) then + d_out<=deadtime(63 downto 48); + elsif(headercounter=5) then + d_out<=deadtime(47 downto 32); + elsif(headercounter=4) then + d_out<=deadtime(31 downto 16); + elsif(headercounter=3) then + d_out<=deadtime(15 downto 0); + marked<='1'; + elsif(headercounter=2) then + d_out<=fifothresh&triggerword; + marked<='0'; + elsif(headercounter=1) then + if (runmode(1)='1')then + ld<='0'; + waitforeudaq<='1'; + else + d_out<=(others=>'0'); + eof<='1'; + end if; + else + d_out<=(others=>'0'); + end if; + headercounter<=headercounter-1; + else + if(waitforeudaq='1')then + if(eudaqdone='1')then + ld<='1'; + eof<='1'; + d_out<='0'&eudaqtrgword; + waitforeudaq<='0'; + else + ld<='0'; + d_out<=(others=>'0'); + end if; + else + eof<='0'; + ld<='0'; + busys<='0'; + end if; + end if; + end if; + + end process; + +end TDCREADOUT; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/tempadc.vhd b/rce/fw-hsio/modules/pixelcore/hdl/tempadc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..84edc1658ac5b76eb7fc9871f7e8a0d508430ca5 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/tempadc.vhd @@ -0,0 +1,93 @@ +-------------------------------------------------------------- +-- ADC Analog Devices 7998 readout +-- Martin Kocian 12/2014 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.StdRtlPkg.all; +use work.I2cPkg.all; +use work.all; + +-------------------------------------------------------------- + +entity tempadc is +generic( PRESCALE_G: integer range 0 to 65535 := 79; + MAPPING_G: NaturalArray(0 to 7) := (7,6,5,4,3,2,1,0) ); +port( clk: in std_logic; + d_out: out Slv16Array(11 downto 0):=(others => (others => '0')); + trig: in std_logic; + ld: out std_logic:= '0'; + adcAS: out std_logic; + scl: inout std_logic; + sda: inout std_logic +); +end tempadc; + +-------------------------------------------------------------- + +architecture TEMPADC of tempadc is + + type state_type is (idle, req, ack); + signal state: state_type; + signal adcI2cIn : i2c_in_type; + signal adcI2cOut : i2c_out_type; + signal i2cregmasterin: I2cRegMasterInType := I2C_REG_MASTER_IN_INIT_C; + signal i2cregmasterout: I2cRegMasterOutType; + signal index: natural range 0 to 7; +begin + sda <= adcI2cOut.sda when adcI2cOut.sdaoen = '0' else 'Z'; + adcI2cIn.sda <= to_x01z(sda); + scl <= adcI2cOut.scl when adcI2cOut.scloen = '0' else 'Z'; + adcI2cIn.scl <= to_x01z(scl); + adcAS <='0'; + + i2cregmasterin.regDataSize<="01"; + i2cregmasterin.endianness<='1'; + i2cregmasterin.i2cAddr<="0000100001"; + + chanmap: for I in 0 to 3 generate + d_out(I)<=toSlv(MAPPING_G(I*2), 8)& toSlv(MAPPING_G(I*2+1), 8); + end generate chanmap; + I2cRegMaster_Inst: entity work.I2cRegMaster + generic map( + PRESCALE_G => PRESCALE_G) + port map( + clk => clk, + regIn => i2cregmasterin, + regOut => i2cregmasterout, + i2ci => adcI2cIn, + i2co => adcI2cOut); + + process begin + wait until (rising_edge(clk)); + if(state=idle)then + ld<='0'; + if(trig='1') then + state<=req; + index<=0; + end if; + elsif (state=req)then + i2cregmasterin.regAddr <= toSlv(128+index*16, 32); + i2cregmasterin.regReq<='1'; + state<=ack; + elsif(state=ack)then + i2cregmasterin.regReq<='0'; + if(i2cregmasterout.regAck='1')then + d_out(index+4)<=i2cregmasterout.regRdData(7 downto 0) & i2cregmasterout.regRdData(15 downto 8); + if(index=7)then + ld<='1'; + state<=idle; + else + index<=index+1; + state<=req; + end if; + end if; + end if; + end process; + + +end TEMPADC; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/modules/pixelcore/hdl/triggerlogic.vhd b/rce/fw-hsio/modules/pixelcore/hdl/triggerlogic.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1dc106ec1769a87ccb28fa65adde2fe45d513fc7 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/triggerlogic.vhd @@ -0,0 +1,290 @@ +-------------------------------------------------------------- +-- Trigger logic for pixel HSIO firmware +-- Martin Kocian 07/2014 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; +use work.arraytype.all; + +-------------------------------------------------------------- + + +entity triggerlogic is + +port( clk: in std_logic; + rst: in std_logic; + clk160: in std_logic; + rst160: in std_logic; + -- hardware inputs + discin : in std_logic_vector(3 downto 0); + hitbusin : in std_logic_vector(1 downto 0); + -- HSIO trigger + HSIObusy : out std_logic; + HSIOtrigger : in std_logic_vector(1 downto 0); + HSIObusyin : in std_logic; + hitbusout : out std_logic; + + -- eudet trigger + exttrigger : in std_logic; + extrst : in std_logic; + extbusy : out std_logic; + exttrgclk : out std_logic; + + calibmode : in std_logic_vector(1 downto 0); + startmeas : in std_logic; + eudaqdone : out std_logic; + eudaqtrgword : out std_logic_vector(14 downto 0); + tcounter1 : out std_logic_vector(31 downto 0); + tcounter2 : out std_logic_vector(31 downto 0); + + trigenabled: in std_logic; + paused: in std_logic; + fifothresh: in std_logic; + triggermask: in std_logic_vector(15 downto 0); + resetdelay: in std_logic; + incrementdelay: in std_logic_vector(4 downto 0); + discop: in std_logic_vector(15 downto 0); + telescopeop: in std_logic_vector(2 downto 0); + period : in std_logic_vector(31 downto 0); + serbusy: in std_logic; + tdcreadoutbusy: in std_logic; + phaseclksel : in std_logic; + phasebusyEn: in std_logic; + phasebusySel: in std_logic_vector(1 downto 0); + l1a: out std_logic; + triggerword: out std_logic_vector(7 downto 0); + busy: out std_logic; + coincd: out std_logic +); +end triggerlogic; + +-------------------------------------------------------------- + +architecture TRIGGERLOGIC of triggerlogic is + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + +signal trgin: std_logic; +signal disc : std_logic_vector(4 downto 0); +signal discrim : std_logic; +signal delrst1 : std_logic; +signal delrst2 : std_logic; +signal delrstf : std_logic; +signal delayrst : std_logic; +signal exttrgclkeu : std_logic; +signal busys : std_logic; +signal l1as : std_logic; +signal cycliccounter : std_logic_vector(31 downto 0); +signal cyclic : std_logic; +signal hitbus : std_logic; +signal resettriggerword: std_logic; +signal oldtdcreadoutbusy: std_logic; +signal tdcready : std_logic; +signal starttdc : std_logic; +signal coinc : std_logic; +signal edge1 : std_logic; +signal edge2 : std_logic; +signal stdc : std_logic; +signal hsio : std_logic; +signal oldperiod : std_logic_vector(31 downto 0); +signal firstphase : std_logic; +signal oldclk : std_logic; + +begin + + HSIObusy <= busys or paused; + busy<=busys; + l1a<=l1as; + hitbusout<=hitbus; + + process(clk, rst) begin + if(rst='1')then + delrst1<='0'; + delrst2<='0'; + delrstf<='0'; + elsif(rising_edge(clk))then + if(resetdelay='1')then + delrst1<='1'; + delrst2<='1'; + delrstf<='1'; + else + delrstf<=delrst1; + delrst1<=delrst2; + delrst2<='0'; + end if; + end if; + end process; + + delayrst<= delrstf or rst; + + discdelays: for I in 0 to 3 generate + delay0 : IDELAY + generic map ( + IOBDELAY_TYPE => "VARIABLE", -- Set to DEFAULT for -- Zero Hold Time Mode + IOBDELAY_VALUE => 0 -- (0 to 63) + ) + port map ( + O => disc(I), + I => discin(I), + C => clk, + CE => incrementdelay(I), + INC => '1', + RST => delayrst + ); + end generate discdelays; + + discrim <= ((disc(0) xor discop(8)) or not discop(0)) and ((disc(1) xor discop(9)) or not discop(1)) and ((disc(2) xor discop(10)) or not discop(2)) and ((disc(3) xor discop(11)) or not discop(3)); + + with discop(15 downto 14) select + hsio <= HSIOtrigger(0) when "00", + HSIOtrigger(1) when "01", + HSIOtrigger(0) or HSIOtrigger(1) when "10", + HSIOtrigger(0) and HSIOtrigger(1) when "11", + '0' when others; + + with telescopeop select + hitbus<= hitbusin(0) when "001", + hitbusin(1) when "010", + hitbusin(0) or hitbusin(1) when "011", + hitbusin(0) and hitbusin(1) when "100", + '0' when others; + + trgin<= (triggermask(2) and exttrigger) + or (triggermask(3) and hsio) + or (triggermask(1) and cyclic) + or (triggermask(4) and hitbus) + or (triggermask(0) and discrim); + + -- Latching of trigger word + process(clk,rst) begin + if(rst='1')then + oldtdcreadoutbusy<='0'; + resettriggerword<='1'; + elsif(rising_edge(clk))then + oldtdcreadoutbusy<=tdcreadoutbusy; + if(oldtdcreadoutbusy='1' and tdcreadoutbusy='0')then + resettriggerword<='1'; + else + resettriggerword<='0'; + end if; + end if; + end process; + + process(resettriggerword, trgin) begin + if(resettriggerword='1')then + triggerword<=x"00"; + elsif(rising_edge(trgin))then + triggerword(7 downto 5)<="000"; + triggerword(4)<=triggermask(4) and hitbus; + triggerword(3)<=triggermask(3) and hsio; + triggerword(2)<=triggermask(2) and exttrigger; + triggerword(1)<=triggermask(1) and cyclic; + triggerword(0)<=triggermask(0) and discrim; + end if; + end process; + + process(clk,rst) begin + if(rst='1')then + cycliccounter<=(others=>'0'); + cyclic<='0'; + elsif(rising_edge(clk))then + oldperiod<=period; + if(period/=x"00000000" and cycliccounter=period)then + cycliccounter<=(others=>'0'); + cyclic<='1'; + elsif(period/=oldperiod)then + cycliccounter<=(others=>'0'); + cyclic<='0'; + else + cycliccounter<=unsigned(cycliccounter)+1; + cyclic<='0'; + end if; + end if; + end process; + + process(clk160, rst160) begin + if(rst160='1')then + oldclk<='0'; + elsif(rising_edge(clk160))then + if(clk=phasebusySel(0) and oldclk=phasebusySel(1))then + firstphase<='0'; + else + firstphase<=phasebusyEn; + end if; + oldclk<=clk; + end if; + end process; + + coin: entity work.coincidence + port map( + clk=>clk, + rst=>rst, + enabled=>trigenabled, + fifothresh=>fifothresh, + trgin=>trgin, + serbusy=>serbusy, + extbusy=>HSIObusyin, + firstphase=>firstphase, + tdcreadoutbusy=>tdcreadoutbusy, + tdcready=> tdcready, + starttdc=>starttdc, + l1a=> l1as, + trgdelay=>x"02", + busy=> busys, + coinc=> coinc, + coincd=> coincd + ); + + -- TDC config + with calibmode select + edge1<= clk when "01", -- tdc calib is special + coinc when others; + with calibmode select + edge2<= phaseclksel when "01", -- tdc calib + clk when others; + + stdc<= startmeas when calibmode="01" else starttdc; + thetdc: entity work.tdc + port map( + sysclk=>clk, + sysrst=>rst, + edge1=> edge1, + edge2=> edge2, + start=>stdc, + ready=>tdcready, + counter1=>tcounter1, + counter2=>tcounter2 + ); + + eudettrg: entity work.eudaqTrigger + port map( + clk => clk, + rst => rst, + busyin => busys, + tdcready => tdcready, + enabled =>calibmode(1), + l1a => l1as, + trg => exttrigger, + done => eudaqdone, + extbusy => extbusy, + trgword => eudaqtrgword, + trgclk => exttrgclkeu ); + + exttrgclk<=exttrgclkeu or paused or not trigenabled; + +end TRIGGERLOGIC; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/triggerpipeline.vhd b/rce/fw-hsio/modules/pixelcore/hdl/triggerpipeline.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6f846563f03227e2b75fd773bf993bb37cded842 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/triggerpipeline.vhd @@ -0,0 +1,125 @@ +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity triggerpipeline is + port ( + rst : in std_logic; + clk : in std_logic; + L1Ain : in std_logic; + L1Aout : out std_logic; + configure : in std_logic; + delay : in std_logic_vector(7 downto 0); + busy : out std_logic; + deadtime : in std_logic_vector(15 downto 0) + ); +end triggerpipeline; + +architecture TRIGGERPIPELINE of triggerpipeline is + + component triggerfifo + port ( + clk: IN std_logic; + din: IN std_logic_VECTOR(0 downto 0); + rd_en: IN std_logic; + rst: IN std_logic; + wr_en: IN std_logic; + data_count: OUT std_logic_VECTOR(7 downto 0); + dout: OUT std_logic_VECTOR(0 downto 0); + empty: OUT std_logic; + full: OUT std_logic); + end component; + + signal oldconfigure: std_logic; + signal configuring : std_logic; + signal configured : std_logic; + signal din : std_logic_vector(0 downto 0); + signal dout : std_logic_vector(0 downto 0); + signal data_count : std_logic_vector(7 downto 0); + --signal busycounter : std_logic_vector(2 downto 0); + signal busycounter : std_logic_vector(15 downto 0); + signal rd_en : std_logic; + signal wr_en : std_logic; + signal fiforst : std_logic; + +begin + + L1Aout<=dout(0); + process (rst,clk) + begin + if(rst='1')then + oldconfigure<='0'; + configuring<='0'; + configured<='0'; + busy<='1'; + din(0)<='0'; + rd_en<='0'; + wr_en<='0'; + busycounter<=x"0000"; + elsif(rising_edge(clk))then + if(configure='1'and oldconfigure='0')then + configuring<='1'; + configured<='0'; + fiforst<='1'; + rd_en<='0'; + wr_en<='0'; + busy<='1'; + elsif(configuring='1')then + fiforst<='0'; + if(delay=data_count)then + configuring<='0'; + configured<='1'; + wr_en<='0'; + busy<='0'; + else + din(0)<='0'; + wr_en<='1'; + end if; + elsif(configured='1')then + wr_en<='1'; + rd_en<='1'; + din(0)<=L1Ain; + if(L1Ain='1')then + busy<='1'; + -- busycounter<="111"; + -- elsif (busycounter/="000")then + if(deadtime(15 downto 3)="0000000000000")then + busycounter<="0000000000000111"; --at least 7 ticks deadtime + else + busycounter<=deadtime; + end if; + elsif (busycounter/=x"0000")then + busycounter<=unsigned(busycounter)-1; + else + busy<='0'; + end if; + end if; + end if; + end process; + + + thepiepeline: triggerfifo + port map( + clk=>clk, + din=>din, + rd_en=>rd_en, + rst=>fiforst, + wr_en=>wr_en, + data_count => data_count, + dout=>dout, + empty=>open, + full=>open ); + +end TRIGGERPIPELINE; diff --git a/rce/fw-hsio/modules/pixelcore/hdl/wordswapper.vhd b/rce/fw-hsio/modules/pixelcore/hdl/wordswapper.vhd new file mode 100644 index 0000000000000000000000000000000000000000..32e4bb11f60ea551a90cd659f4804f547b8877f1 --- /dev/null +++ b/rce/fw-hsio/modules/pixelcore/hdl/wordswapper.vhd @@ -0,0 +1,134 @@ +------------------------------------------------------------------------------- +-- Description: +-- Swaps 16-bit words in time for pgp. The number of words has to be even. +------------------------------------------------------------------------------- +-- Copyright (c) 2010 by Martin Kocian. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity wordswapper is + port ( + rst : in std_logic; + clk : in std_logic; + wordin : in std_logic_vector(15 downto 0); + eofin : in std_logic; + eeofin : in std_logic; + sofin : in std_logic; + validin : in std_logic; + wordout : out std_logic_vector(15 downto 0); + eofout : out std_logic; + eeofout : out std_logic; + sofout : out std_logic; + validout : out std_logic + ); +end wordswapper; + +architecture WORDSWAPPER of wordswapper is + + signal savedword : std_logic_vector(15 downto 0); + type state_type is (idle, firsteven, odd, even, lastodd); + signal state: state_type; + signal eeof: std_logic; + +begin + + process (rst,clk) + begin + if(rst='1')then + savedword<=x"0000"; + state<=idle; + eofout<='0'; + sofout<='0'; + eeofout<='0'; + validout<='0'; + wordout<=x"0000"; + elsif(rising_edge(clk))then + case state is + when idle => + if(validin='1' and sofin='1')then + eofout<='0'; + eeofout<='0'; + sofout<='0'; + validout<='0'; + wordout<=x"0000"; + savedword<=wordin; + state<=firsteven; + else + validout<='0'; + eofout<='0'; + eeofout<='0'; + sofout<='0'; + wordout<=x"0000"; + state<=idle; + end if; + when firsteven => + if(validin='1')then + sofout<='1'; + wordout<=wordin; + eofout<='0'; + eeofout<='0'; + validout<='1'; + if(eofin='1')then + eeof<=eeofin; + state<=lastodd; + else + state<=odd; + end if; + else + validout<='0'; + state<=firsteven; + end if; + when odd => + if(validin='1')then + sofout<='0'; + eofout<='0'; + eeofout<='0'; + validout<='1'; + wordout<=savedword; + savedword<=wordin; + state<=even; + else + validout<='0'; + sofout<='0'; + eofout<='0'; + eeofout<='0'; + state<=odd; + end if; + when even => + if(validin='1')then + sofout<='0'; + wordout<=wordin; + eofout<='0'; + eeofout<='0'; + validout<='1'; + if(eofin='1')then + eeof<=eeofin; + state<=lastodd; + else + state<=odd; + end if; + else + validout<='0'; + state<=even; + end if; + when lastodd => + sofout<='0'; + eofout<='1'; + eeofout<=eeof; + validout<='1'; + wordout<=savedword; + state<=idle; + end case; + end if; + end process; + + +end WORDSWAPPER; diff --git a/rce/fw-hsio/projects/HsioCosmic/Makefile b/rce/fw-hsio/projects/HsioCosmic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5c82cd853d84dbb484b348c2b7f4fdef5592551e --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/Makefile @@ -0,0 +1,12 @@ +# Project Name +export PROJECT = $(notdir $(PWD)) + +# List of build core directories. Relative to current directory. +CORE_DIRS = coregen ../../modules/pgp/coregen ../../modules/pgp2/coregen ../../modules/pixelcore/coregen + +# Optional ELF file to include. Relative to ./boot directory +#BOOT_ELF = udiTest.elf + +# Use top level makefile +include ../../system.mk + diff --git a/rce/fw-hsio/projects/HsioCosmic/Readme.txt b/rce/fw-hsio/projects/HsioCosmic/Readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0ba752b3e18a22530900255b57e6e1df48afd87 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/Readme.txt @@ -0,0 +1,59 @@ +This is a DPM project specific Readme.txt file. + +The files in this directory are used to build +the DPM project in this directory. The project +name matches the name of the directory in which +this file is found. + +The Makefile in this directory may be used to build +this project with a simple 'gmake' command. + +The Version.vhd file in this directory is used to +generate the software readable version constant +in the build and is also used to set the name of +the files added to the images directory. + +The following sub directories exist in this project: + +boot: + This directory contains boot loader files which are + used to program the boot loader code in the DPM. The + files in this directory include: + +config: + This directory contains Xilinx configuration files for + various steps in the synthesis process. The files in this + directory include: + + bitgen_options.txt: Options for bitgen + map_options.txt: Options for map + ngdbuild_options.txt: Options for ngdbuild + par_options.txt: Options for par + trce_options.txt: Options for trce + xst_options.txt: Options for xst + sources.txt Source file list used by xst + +coregen: + This directory holds the coregen project and any modules + generated by coregen that are specific to this project. + +debug: + This directory holds any debug files for the project. + +hdl: + This directory contains the source files (.vhd and .v) for + the project and the constraints file (.ucf) for the project. + The top level module name, its source file name and the ucf + file name should match the name of the project. + +images: + + This directory contains the result of the project compile. + The resulting .mcs and .bit files for the project are + added to this directory. The name of the copied file will + be: project_version.mcs/.bit. + +sim: + + Directory for simulation Makefile and test bench. + diff --git a/rce/fw-hsio/projects/HsioCosmic/Version.vhd b/rce/fw-hsio/projects/HsioCosmic/Version.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f31cbfbbb3b062172846ba2d0488da89fc0486d3 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/Version.vhd @@ -0,0 +1,34 @@ +------------------------------------------------------------------------------- +-- Title : Version Constant File +-- Project : HSIO +------------------------------------------------------------------------------- +-- File : Version.vhd +-- Author : Martin Kocian, kocian@slac.stanford.edu +-- Created : 01/07/2013 +------------------------------------------------------------------------------- +-- Description: +-- Version Constant Module +------------------------------------------------------------------------------- +-- Copyright (c) 2012 by SLAC. All rights reserved. +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Version is + +constant FpgaVersion : std_logic_vector(31 downto 0) := x"00000009"; -- MAKE_VERSION + +end Version; + +------------------------------------------------------------------------------- +-- Revision History: +-- 01/07/2013 (0x00000001): Initial XST version +-- 03/22/2013 (0x00000002): HSIO trigger/busy added to opto ucf file +-- 04/02/2013 (0x00000003): Memory buffer for triggering. +-- 06/20/2014 (0x00000004): Added hitbus readout for DBM +-- 07/24/2014 (0x00000005): Separated trigger from core. +-- 11/07/2014 (0x00000006): Set multiplicities for multiplexer +-- 12/15/2014 (0x00000007): Added Temperature ADC readout +-- 01/09/2015 (0x00000008): New readout for FEI4 +-- 01/09/2015 (0x00000009): New ADC data format, max 31 readout links. +------------------------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/HsioCosmic/config/bitgen_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/bitgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..abf29c69b7888da03e96c154d93bc2f56add8ccd --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/bitgen_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx bitgen options file +##----------------------------------------------------------------------------- +-intstyle silent +-w diff --git a/rce/fw-hsio/projects/HsioCosmic/config/map_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/map_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..6cef41ff642fa23ed75c9e6516aa65c1c9c961af --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/map_options.txt @@ -0,0 +1,21 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx map options file +##----------------------------------------------------------------------------- + +#-intstyle silent +-ol high +-xe n +-t 1 +-register_duplication on +#-global_opt off +#-equivalent_register_removal on +#-u +#-cm Area +-detail +#-ir off +#-pr off +#-lc off +#-mt 2 + + + diff --git a/rce/fw-hsio/projects/HsioCosmic/config/ngdbuild_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/ngdbuild_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..95ca0eea7e533ba749eb765d1e8cdd2068359eab --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/ngdbuild_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx ngdbuild options file +##----------------------------------------------------------------------------- +-nt timestamp + diff --git a/rce/fw-hsio/projects/HsioCosmic/config/par_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/par_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2cdd3ad019144a5e3f99c255af2010411238e4ea --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/par_options.txt @@ -0,0 +1,9 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx place and route options file +##----------------------------------------------------------------------------- +#-intstyle ise +-ol high +-xe n +#-mt 4 + + diff --git a/rce/fw-hsio/projects/HsioCosmic/config/promgen_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/promgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2c2257bee87830d2f7251e8db6d2b735977d3c56 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/promgen_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx promgen options file +##----------------------------------------------------------------------------- +-x xcf32p +-w +-p mcs +-c FF diff --git a/rce/fw-hsio/projects/HsioCosmic/config/sources.txt b/rce/fw-hsio/projects/HsioCosmic/config/sources.txt new file mode 120000 index 0000000000000000000000000000000000000000..c5dbc41ed1d3295e665824034473824a6b7da105 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/sources.txt @@ -0,0 +1 @@ +sources_pgp1.txt \ No newline at end of file diff --git a/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp1.txt b/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp1.txt new file mode 100644 index 0000000000000000000000000000000000000000..23b04f9f9ca5d67baba21ddcf318de73290790d6 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp1.txt @@ -0,0 +1,80 @@ +# Version Constant +vhdl work "_PROJ_DIR_/Version.vhd" + +# PGP + +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpVersion.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpAckRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellTx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpMgtWrap.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRxTrack.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTxSched.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTop.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpClkGen.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCmdSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRegSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPicRemBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDataBuffer.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpFrontEnd.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDsBuff.vhd" + +# Pixel core +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_wrapper.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_bram.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_disp.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut_base.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_pkg.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_rtl.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_top.vhd" + +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/StdRtlPkg.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cPkg.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/stdlib.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/i2c_master_bit_ctrl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/i2c_master_byte_ctrl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cMaster.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cRegMaster.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tempadc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/adcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/arraytype.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayCharacters.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayControl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser32.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/OutputEncoder.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock160.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock200.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/phaseshift.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflag.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagnew.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eofcounter.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/multiplexdataopt.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/coincidence.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerpipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/hitbuspipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/wordswapper.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eudaqTrigger.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/syncdatac.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealign.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealignhitbus.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser10b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser4b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp24bit.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/lookaheadfifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/decodefei4record.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/datafifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerlogic.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/HsioPixelCore.vhd" + + +# Local Files +vhdl work "_PROJ_DIR_/hdl/HsioCosmic.vhd" + diff --git a/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp2.txt b/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp2.txt new file mode 100644 index 0000000000000000000000000000000000000000..c9a08932dc06166e33e68c31c8c0e86982dd48ac --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/sources_pgp2.txt @@ -0,0 +1,86 @@ +# Version Constant +vhdl work "_PROJ_DIR_/Version.vhd" + +# PGP2 + +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2CorePackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2Rx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2RxCell.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2RxPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2Tx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxCell.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxSched.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtPackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2Mgt16.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/PgpClkGen.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtRxRst.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtTxRst.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2AppPackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2CmdSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2DsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2RegSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2UsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/PgpDsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/PgpFrontEnd.vhd" + + +# Pixel core +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_wrapper.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_bram.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_disp.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut_base.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_pkg.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_rtl.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_top.vhd" + +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/StdRtlPkg.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cPkg.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/stdlib.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/i2c_master_bit_ctrl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/i2c_master_byte_ctrl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cMaster.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/I2cRegMaster.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tempadc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/adcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/arraytype.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayCharacters.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayControl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser32.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/OutputEncoder.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock160.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock200.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/phaseshift.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflag.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagnew.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eofcounter.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/multiplexdataopt.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/coincidence.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerpipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/wordswapper.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eudaqTrigger.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/syncdatac.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealign.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser10b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp24bit.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/lookaheadfifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/decodefei4record.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/datafifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/hitbuspipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealignhitbus.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser4b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerlogic.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/HsioPixelCore.vhd" + + + +# Local Files +vhdl work "_PROJ_DIR_/hdl/HsioCosmic.vhd" + diff --git a/rce/fw-hsio/projects/HsioCosmic/config/trce_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/trce_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2656ff46d3ef8bf070390954affed019ee28ca82 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/trce_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx trace options file +##----------------------------------------------------------------------------- +-intstyle silent +-l 30 +-v 30 +-tsi DpmTest.tsi diff --git a/rce/fw-hsio/projects/HsioCosmic/config/xst_options.txt b/rce/fw-hsio/projects/HsioCosmic/config/xst_options.txt new file mode 100644 index 0000000000000000000000000000000000000000..50864e04d841f135a875d24c7404a37f3715dd80 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/config/xst_options.txt @@ -0,0 +1,50 @@ +run +-ofn HsioCosmic +-top HsioCosmic +-p XC4VFX60-11-FF1152 +-ifn "sources.txt" +-opt_mode Speed +-opt_level 2 +-power NO +-iuc NO +-keep_hierarchy No +-netlist_hierarchy As_Optimized +-rtlview Yes +-glob_opt AllClockNets +-write_timing_constraints No +-cross_clock_analysis NO +-hierarchy_separator / +-bus_delimiter <> +-case Maintain +-slice_utilization_ratio 100 +-bram_utilization_ratio 100 +-dsp_utilization_ratio 100 +-verilog2001 YES +-fsm_extract YES -fsm_encoding Auto +-safe_implementation No +-fsm_style LUT +-ram_extract Yes +-ram_style Auto +-rom_extract Yes +-mux_style Auto +-decoder_extract YES +-priority_extract Yes +-shreg_extract YES +-shift_extract YES +-xor_collapse YES +-resource_sharing Yes +-use_dsp48 Auto +-async_to_sync No +-iobuf Yes +-max_fanout 100000 +-bufg 32 +-register_duplication YES +-equivalent_register_removal Yes +-register_balancing No +-iob Auto +-slice_packing YES +-use_clock_enable Auto +-use_sync_set Auto +-use_sync_reset Auto +-optimize_primitives No + diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf new file mode 120000 index 0000000000000000000000000000000000000000..84bd04b7d481bad6f1f050ed435853d513d72429 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf @@ -0,0 +1 @@ +HsioCosmic.ucf.4core \ No newline at end of file diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.2core b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.2core new file mode 100644 index 0000000000000000000000000000000000000000..4393b339bea43c87f111cad888805ff37b53a9d5 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.2core @@ -0,0 +1,408 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore*/channelmask(*) TIG; +NET U_HsioCosmicCore*/channeloutmask(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(?) maxskew = 250 ps ; +#NET U_HsioCosmicCore/deldata maxskew = 250 ps ; + +INST "U_HsioCosmicCore*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +#NET "iMgtRxN2" LOC = "AA1"; +#NET "iMgtRxP2" LOC = "Y1"; +#NET "oMgtTxN2" LOC = "V1"; +#NET "oMgtTxP2" LOC = "U1"; + +NET "iMgtRxN2" LOC = "AD1"; +NET "iMgtRxP2" LOC = "AC1"; +NET "oMgtTxN2" LOC = "AG1"; +NET "oMgtTxP2" LOC = "AF1"; + +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +# fiber 2 +#NET "transDis2" LOC = "AK4"; +#NET "transDis2" IOSTANDARD="LVCMOS33"; +NET "transDis2" LOC = "Y4"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "G15"; +NET "iExtreload" IOSTANDARD="LVCMOS25"; +NET "iExtreload" PULLUP; + +NET "refclk_p" LOC = "J25"; +NET "refclk_p" IOSTANDARD="LVDS_25"; +NET "refclk_n" LOC = "H25"; +NET "refclk_n" IOSTANDARD="LVDS_25"; + +NET "xclk_p" LOC = "E24"; +NET "xclk_p" IOSTANDARD="LVDS_25"; +NET "xclk_n" LOC = "F24"; +NET "xclk_n" IOSTANDARD="LVDS_25"; + +NET "clkout40" LOC = "AJ29"; +NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "clkout40" SLEW="FAST"; + +NET "RD2" LOC = "AJ24"; +NET "RD2" IOSTANDARD="LVCMOS33"; +NET "RD2" SLEW="FAST"; + +NET "AuxClk" LOC = "AK29"; +NET "AuxClk" IOSTANDARD="LVCMOS33"; +NET "AuxClk" SLEW="FAST"; + +NET "RA" LOC = "AM30"; +NET "RA" IOSTANDARD="LVCMOS33"; +NET "RA" SLEW="FAST"; + +NET "RD1" LOC = "AH24"; +NET "RD1" IOSTANDARD="LVCMOS33"; +NET "RD1" SLEW="FAST"; + +NET "IOMXIN(3)" LOC = "AG3"; +NET "IOMXIN(3)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(2)" LOC = "AF3"; +NET "IOMXIN(2)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(1)" LOC = "W9"; +NET "IOMXIN(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(0)" LOC = "Y9"; +NET "IOMXIN(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXSEL(2)" LOC = "AB6"; +NET "IOMXSEL(2)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(2)" SLEW="FAST"; + +NET "IOMXSEL(1)" LOC = "AA6"; +NET "IOMXSEL(1)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(1)" SLEW="FAST"; + +NET "IOMXSEL(0)" LOC = "Y6"; +NET "IOMXSEL(0)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(0)" SLEW="FAST"; + +NET "HITOR" LOC = "AL29"; +NET "HITOR" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(0)" LOC = "AC4"; +NET "IOMXOUT(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(1)" LOC = "AA8"; +NET "IOMXOUT(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(2)" LOC = "AA9"; +NET "IOMXOUT(2)" IOSTANDARD="LVCMOS33"; + +NET "SELALTBUS" LOC = "AK6"; +NET "SELALTBUS" IOSTANDARD="LVCMOS33"; +NET "SELALTBUS" SLEW="FAST"; + +NET "REGABDACLD" LOC = "AD5"; +NET "REGABDACLD" IOSTANDARD="LVCMOS33"; +NET "REGABDACLD" SLEW="FAST"; + +NET "REGABSTBLD" LOC = "AD4"; +NET "REGABSTBLD" IOSTANDARD="LVCMOS33"; +NET "REGABSTBLD" SLEW="FAST"; + +NET "SELCMD" LOC = "AE6"; +NET "SELCMD" IOSTANDARD="LVCMOS33"; +NET "SELCMD" SLEW="FAST"; + +NET "CMDEXTTRIGGER" LOC = "AF6"; +NET "CMDEXTTRIGGER" IOSTANDARD="LVCMOS33"; +NET "CMDEXTTRIGGER" SLEW="FAST"; + +NET "CMDALTPLS" LOC = "AC3"; +NET "CMDALTPLS" IOSTANDARD="LVCMOS33"; +NET "CMDALTPLS" SLEW="FAST"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +#NET "oHSIObusy" LOC="H19"; +#NET "oHSIObusy" IOSTANDARD="LVTTL"; +#NET "oHSIObusy" SLEW=FAST; + +NET "oHSIOtrigger" LOC="L15"; +NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +NET "oHSIOtrigger" SLEW=FAST; + +NET "iHSIObusy" LOC="H19"; +NET "iHSIObusy" IOSTANDARD="LVTTL"; +NET "iHSIObusy" SLEW=FAST; +NET "iHSIObusy" PULLDOWN; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +# DI1 +NET "oExttrgclkP" LOC = "AH15"; +NET "oExttrgclkN" LOC = "AJ15"; +# DI3 +NET "oExtbusyP" LOC = "AD14"; +NET "oExtbusyN" LOC = "AC13"; +#DTO1 +NET "iExttriggerP" LOC = "J31"; +NET "iExttriggerN" LOC = "J30"; +# DTO3 +NET "iExtrstP" LOC = "G30"; +NET "iExtrstN" LOC = "F30"; + +NET "serialout_p(0)" LOC = "AG12"; +NET "serialout_n(0)" LOC = "AH12"; +NET "serialout_p(1)" LOC = "AF10"; +NET "serialout_n(1)" LOC = "AG10"; +NET "serialout_p(3)" LOC = "AH14"; +NET "serialout_n(3)" LOC = "AJ14"; +NET "serialout_p(2)" LOC = "AH10"; +NET "serialout_n(2)" LOC = "AJ10"; +NET "serialout_p(4)" LOC = "AJ12"; +NET "serialout_n(4)" LOC = "AK12"; +NET "serialout_p(5)" LOC = "AH8"; +NET "serialout_n(5)" LOC = "AH7"; +NET "serialout_p(6)" LOC = "AF11"; +NET "serialout_n(6)" LOC = "AG11"; +NET "serialout_p(7)" LOC = "AJ9"; +NET "serialout_n(7)" LOC = "AH9"; +#NET "oExttrgclkP" LOC = "AJ9"; +#NET "oExttrgclkN" LOC = "AH9"; + + +NET "serialout_p(11)" LOC = "AF15"; +NET "serialout_n(11)" LOC = "AG15"; +NET "serialout_p(12)" LOC = "AB13"; +NET "serialout_n(12)" LOC = "AA13"; +NET "serialout_p(13)" LOC = "AD10"; +NET "serialout_n(13)" LOC = "AD9"; +NET "serialout_p(14)" LOC = "AB11"; +NET "serialout_n(14)" LOC = "AA11"; +#NET "serialout_p(15)" LOC = "AD14"; +#NET "serialout_n(15)" LOC = "AC13"; +#NET "oExtbusyP" LOC = "AD14"; +#NET "oExtbusyN" LOC = "AC13"; + +NET "serialout(8)" LOC = "AL21"; + +NET "serialin_p(0)" LOC = "AK7"; +NET "serialin_n(0)" LOC = "AJ7"; +NET "serialin_p(1)" LOC = "AF9"; +NET "serialin_n(1)" LOC = "AE9"; +NET "serialin_p(3)" LOC = "AL10"; +NET "serialin_n(3)" LOC = "AM10"; +NET "serialin_p(2)" LOC = "AL9"; +NET "serialin_n(2)" LOC = "AK9"; +NET "serialin_p(4)" LOC = "AL11"; +NET "serialin_n(4)" LOC = "AM11"; +NET "serialin_p(5)" LOC = "AK13"; +NET "serialin_n(5)" LOC = "AL13"; +NET "serialin_p(6)" LOC = "AK14"; +NET "serialin_n(6)" LOC = "AL14"; +NET "serialin_p(7)" LOC = "AM8"; +NET "serialin_n(7)" LOC = "AM7"; +#NET "iExttriggerP" LOC = "AM8"; +#NET "iExttriggerN" LOC = "AM7"; +NET "serialin_p(8)" LOC = "AM13"; +NET "serialin_n(8)" LOC = "AM12"; + +NET "serialin_p(11)" LOC = "K28"; +NET "serialin_n(11)" LOC = "J27"; +NET "serialin_p(12)" LOC = "H30"; +NET "serialin_n(12)" LOC = "H29"; +NET "serialin_p(13)" LOC = "C23"; +NET "serialin_n(13)" LOC = "C22"; +NET "serialin_p(14)" LOC = "E23"; +NET "serialin_n(14)" LOC = "F23"; +#NET "serialin_p(15)" LOC = "G30"; +#NET "serialin_n(15)" LOC = "F30"; +#NET "iExtrstP" LOC = "G30"; +#NET "iExtrstN" LOC = "F30"; + + +NET "discinP(0)" LOC = "AD7"; +NET "discinP(1)" LOC = "AD6"; +NET "discinP(2)" LOC = "AM6"; +NET "discinP(3)" LOC = "AL6"; + +NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout(8)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(8)" SLEW = "FAST"; + +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.4core b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.4core new file mode 100644 index 0000000000000000000000000000000000000000..d1cc689dc71fd240b229ac815a19378db0d4d7b5 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.4core @@ -0,0 +1,438 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore*/channelmask(*) TIG; +NET U_HsioCosmicCore*/channeloutmask(*) TIG; +#NET U_HsioCosmicCore*/dispDigitC(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(?) maxskew = 250 ps ; +#NET U_HsioCosmicCore/deldata maxskew = 250 ps ; + +INST "U_HsioCosmicCore*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN(0)" LOC = "N1"; +NET "iMgtRxP(0)" LOC = "M1"; +NET "oMgtTxN(0)" LOC = "T1"; +NET "oMgtTxP(0)" LOC = "R1"; +# fiber 2 +NET "iMgtRxN(1)" LOC = "AA1"; +NET "iMgtRxP(1)" LOC = "Y1"; +NET "oMgtTxN(1)" LOC = "V1"; +NET "oMgtTxP(1)" LOC = "U1"; +#fiber 3 +NET "iMgtRxN(2)" LOC = "AD1"; +NET "iMgtRxP(2)" LOC = "AC1"; +NET "oMgtTxN(2)" LOC = "AG1"; +NET "oMgtTxP(2)" LOC = "AF1"; +#fiber 4 +NET "iMgtRxN(3)" LOC = "AM1"; +NET "iMgtRxP(3)" LOC = "AL1"; +NET "oMgtTxN(3)" LOC = "AJ1"; +NET "oMgtTxP(3)" LOC = "AH1"; + + +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis(0)" LOC = "AH4"; +NET "transDis(0)" IOSTANDARD="LVCMOS33"; +# fiber 2 +NET "transDis(1)" LOC = "AK4"; +NET "transDis(1)" IOSTANDARD="LVCMOS33"; +# fiber 3 +NET "transDis(2)" LOC = "Y4"; +NET "transDis(2)" IOSTANDARD="LVCMOS33"; +# fiber 4 +NET "transDis(3)" LOC = "V8"; +NET "transDis(3)" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "G15"; +NET "iExtreload" IOSTANDARD="LVCMOS25"; +NET "iExtreload" PULLUP; + +NET "refclk_p" LOC = "J25"; +NET "refclk_p" IOSTANDARD="LVDS_25"; +NET "refclk_n" LOC = "H25"; +NET "refclk_n" IOSTANDARD="LVDS_25"; + +NET "xclk_p" LOC = "E24"; +NET "xclk_p" IOSTANDARD="LVDS_25"; +NET "xclk_n" LOC = "F24"; +NET "xclk_n" IOSTANDARD="LVDS_25"; + +NET "clkout40" LOC = "AJ29"; +NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "clkout40" SLEW="FAST"; + +NET "RD2" LOC = "AJ24"; +NET "RD2" IOSTANDARD="LVCMOS33"; +NET "RD2" SLEW="FAST"; + +NET "AuxClk" LOC = "AK29"; +NET "AuxClk" IOSTANDARD="LVCMOS33"; +NET "AuxClk" SLEW="FAST"; + +NET "RA" LOC = "AM30"; +NET "RA" IOSTANDARD="LVCMOS33"; +NET "RA" SLEW="FAST"; + +NET "RD1" LOC = "AH24"; +NET "RD1" IOSTANDARD="LVCMOS33"; +NET "RD1" SLEW="FAST"; + +NET "IOMXIN(3)" LOC = "AG3"; +NET "IOMXIN(3)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(2)" LOC = "AF3"; +NET "IOMXIN(2)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(1)" LOC = "W9"; +NET "IOMXIN(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(0)" LOC = "Y9"; +NET "IOMXIN(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXSEL(2)" LOC = "AB6"; +NET "IOMXSEL(2)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(2)" SLEW="FAST"; + +NET "IOMXSEL(1)" LOC = "AA6"; +NET "IOMXSEL(1)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(1)" SLEW="FAST"; + +NET "IOMXSEL(0)" LOC = "Y6"; +NET "IOMXSEL(0)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(0)" SLEW="FAST"; + +NET "HITOR" LOC = "AL29"; +NET "HITOR" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(0)" LOC = "AC4"; +NET "IOMXOUT(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(1)" LOC = "AA8"; +NET "IOMXOUT(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(2)" LOC = "AA9"; +NET "IOMXOUT(2)" IOSTANDARD="LVCMOS33"; + +NET "SELALTBUS" LOC = "AK6"; +NET "SELALTBUS" IOSTANDARD="LVCMOS33"; +NET "SELALTBUS" SLEW="FAST"; + +NET "REGABDACLD" LOC = "AD5"; +NET "REGABDACLD" IOSTANDARD="LVCMOS33"; +NET "REGABDACLD" SLEW="FAST"; + +NET "REGABSTBLD" LOC = "AD4"; +NET "REGABSTBLD" IOSTANDARD="LVCMOS33"; +NET "REGABSTBLD" SLEW="FAST"; + +NET "SELCMD" LOC = "AE6"; +NET "SELCMD" IOSTANDARD="LVCMOS33"; +NET "SELCMD" SLEW="FAST"; + +NET "CMDEXTTRIGGER" LOC = "AF6"; +NET "CMDEXTTRIGGER" IOSTANDARD="LVCMOS33"; +NET "CMDEXTTRIGGER" SLEW="FAST"; + +NET "CMDALTPLS" LOC = "AC3"; +NET "CMDALTPLS" IOSTANDARD="LVCMOS33"; +NET "CMDALTPLS" SLEW="FAST"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +#NET "oHSIObusy" LOC="H19"; +#NET "oHSIObusy" LOC="L15"; +#NET "oHSIObusy" IOSTANDARD="LVTTL"; +#NET "oHSIObusy" SLEW=FAST; + +NET "oHSIOtrigger" LOC="L15"; +NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +NET "oHSIOtrigger" SLEW=FAST; + +NET "iHSIObusy" LOC="H19"; +NET "iHSIObusy" IOSTANDARD="LVTTL"; +NET "iHSIObusy" SLEW=FAST; +NET "iHSIObusy" PULLDOWN; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +# DI1 +NET "oExttrgclkP" LOC = "AH15"; +NET "oExttrgclkN" LOC = "AJ15"; +# DI3 +NET "oExtbusyP" LOC = "AD14"; +NET "oExtbusyN" LOC = "AC13"; +#DTO1 +NET "iExttriggerP" LOC = "J31"; +NET "iExttriggerN" LOC = "J30"; +# DTO3 +NET "iExtrstP" LOC = "G30"; +NET "iExtrstN" LOC = "F30"; + +NET "serialout_p(0)" LOC = "AG12"; +NET "serialout_n(0)" LOC = "AH12"; +NET "serialout_p(1)" LOC = "AF10"; +NET "serialout_n(1)" LOC = "AG10"; +NET "serialout_p(3)" LOC = "AH14"; +NET "serialout_n(3)" LOC = "AJ14"; +NET "serialout_p(2)" LOC = "AH10"; +NET "serialout_n(2)" LOC = "AJ10"; +NET "serialout_p(4)" LOC = "AJ12"; +NET "serialout_n(4)" LOC = "AK12"; +NET "serialout_p(5)" LOC = "AH8"; +NET "serialout_n(5)" LOC = "AH7"; +NET "serialout_p(6)" LOC = "AF11"; +NET "serialout_n(6)" LOC = "AG11"; +# LVDS drivers broken, use header instead +NET "serialout_p(7)" LOC = "AJ9"; +NET "serialout_n(7)" LOC = "AH9"; +#NET "serialout_p(7)" LOC = "AF15"; +#NET "serialout_n(7)" LOC = "AG15"; +#NET "oExttrgclkP" LOC = "AJ9"; +#NET "oExttrgclkN" LOC = "AH9"; + + +#NET "serialout_p(11)" LOC = "AF15"; +#NET "serialout_n(11)" LOC = "AG15"; +#NET "serialout_p(12)" LOC = "AB13"; +#NET "serialout_n(12)" LOC = "AA13"; +#NET "serialout_p(13)" LOC = "AD10"; +#NET "serialout_n(13)" LOC = "AD9"; +#NET "serialout_p(14)" LOC = "AB11"; +#NET "serialout_n(14)" LOC = "AA11"; +#NET "serialout_p(15)" LOC = "AD14"; +#NET "serialout_n(15)" LOC = "AC13"; +#NET "oExtbusyP" LOC = "AD14"; +#NET "oExtbusyN" LOC = "AC13"; + +NET "serialout(8)" LOC = "AL21"; + +NET "serialin_p(0)" LOC = "AK7"; +NET "serialin_n(0)" LOC = "AJ7"; +NET "serialin_p(1)" LOC = "AF9"; +NET "serialin_n(1)" LOC = "AE9"; +NET "serialin_p(3)" LOC = "AL10"; +NET "serialin_n(3)" LOC = "AM10"; +NET "serialin_p(2)" LOC = "AL9"; +NET "serialin_n(2)" LOC = "AK9"; +NET "serialin_p(4)" LOC = "AL11"; +NET "serialin_n(4)" LOC = "AM11"; +NET "serialin_p(5)" LOC = "AK13"; +NET "serialin_n(5)" LOC = "AL13"; +NET "serialin_p(6)" LOC = "AK14"; +NET "serialin_n(6)" LOC = "AL14"; +# LVDS drivers broken, use header instead +NET "serialin_p(7)" LOC = "AM8"; +NET "serialin_n(7)" LOC = "AM7"; +#NET "serialin_p(7)" LOC = "K28"; +#NET "serialin_n(7)" LOC = "J27"; +#NET "iExttriggerP" LOC = "AM8"; +#NET "iExttriggerN" LOC = "AM7"; +NET "serialin_p(8)" LOC = "AM13"; +NET "serialin_n(8)" LOC = "AM12"; + +#NET "serialin_p(11)" LOC = "K28"; +#NET "serialin_n(11)" LOC = "J27"; +#NET "serialin_p(12)" LOC = "H30"; +#NET "serialin_n(12)" LOC = "H29"; +#NET "serialin_p(13)" LOC = "C23"; +#NET "serialin_n(13)" LOC = "C22"; +#NET "serialin_p(14)" LOC = "E23"; +#NET "serialin_n(14)" LOC = "F23"; +#NET "serialin_p(15)" LOC = "G30"; +#NET "serialin_n(15)" LOC = "F30"; +#NET "iExtrstP" LOC = "G30"; +#NET "iExtrstN" LOC = "F30"; + + +NET "discinP(0)" LOC = "AD7"; +NET "discinP(1)" LOC = "AD6"; +NET "discinP(2)" LOC = "AM6"; +NET "discinP(3)" LOC = "AL6"; + +NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +# ADC I2C +NET "adcI2cScl" LOC = "AM3"; +NET "adcI2cSda" LOC = "AL3"; +NET "adcAS" LOC = "AJ6"; + +NET "adcI2cScl" IOSTANDARD = "LVCMOS33"; +NET "adcI2cSda" IOSTANDARD = "LVCMOS33"; +NET "adcAS" IOSTANDARD = "LVCMOS33"; + +NET "adcI2cScl" PULLUP; +NET "adcI2cSda" PULLUP; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; +# +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout(8)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(8)" SLEW = "FAST"; + +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.RJ45.oldHSIO b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.RJ45.oldHSIO new file mode 100644 index 0000000000000000000000000000000000000000..d9f802b93c895e97eb3fc1be0a7437d1b54fa1d0 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.RJ45.oldHSIO @@ -0,0 +1,370 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_HsioCosmicCore/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore/channelmask(*) TIG; +NET U_HsioCosmicCore/channeloutmask(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(?) maxskew = 250 ps ; +#NET U_HsioCosmicCore/deldata maxskew = 250 ps ; + +INST "U_HsioCosmicCore/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "AP29"; +NET "iPgpRefClkM" LOC = "AP28"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "AP25"; +NET "iMgtRxP" LOC = "AP26"; +NET "oMgtTxN" LOC = "AP22"; +NET "oMgtTxP" LOC = "AP23"; +# fiber 2 +#NET "iMgtRxN" LOC = "AA1"; +#NET "iMgtRxP" LOC = "Y1"; +#NET "oMgtTxN" LOC = "V1"; +#NET "oMgtTxP" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AE27"; +# fiber 2 +#NET "transDis1" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; + +NET "refclk_p" LOC = "T9"; +NET "refclk_p" IOSTANDARD="LVDS_25"; +NET "refclk_n" LOC = "R9"; +NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +#NET "clkout40" SLEW="FAST"; + +#NET "RD2" LOC = "AJ24"; +#NET "RD2" IOSTANDARD="LVCMOS33"; +#NET "RD2" SLEW="FAST"; + +#NET "AuxClk" LOC = "AK29"; +#NET "AuxClk" IOSTANDARD="LVCMOS33"; +#NET "AuxClk" SLEW="FAST"; + +#NET "RA" LOC = "AM30"; +#NET "RA" IOSTANDARD="LVCMOS33"; +#NET "RA" SLEW="FAST"; + +#NET "RD1" LOC = "AH24"; +#NET "RD1" IOSTANDARD="LVCMOS33"; +#NET "RD1" SLEW="FAST"; + +#NET "IOMXIN(3)" LOC = "AG3"; +#NET "IOMXIN(3)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXIN(2)" LOC = "AF3"; +#NET "IOMXIN(2)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXIN(1)" LOC = "W9"; +#NET "IOMXIN(1)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXIN(0)" LOC = "Y9"; +#NET "IOMXIN(0)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXSEL(2)" LOC = "AB6"; +#NET "IOMXSEL(2)" IOSTANDARD="LVCMOS33"; +#NET "IOMXSEL(2)" SLEW="FAST"; + +#NET "IOMXSEL(1)" LOC = "AA6"; +#NET "IOMXSEL(1)" IOSTANDARD="LVCMOS33"; +#NET "IOMXSEL(1)" SLEW="FAST"; + +#NET "IOMXSEL(0)" LOC = "Y6"; +#NET "IOMXSEL(0)" IOSTANDARD="LVCMOS33"; +#NET "IOMXSEL(0)" SLEW="FAST"; + +#NET "HITOR" LOC = "T8"; #auxclk +#NET "HITOR" LOC = "AL29"; +#NET "HITOR" IOSTANDARD="LVCMOS33"; + +#NET "IOMXOUT(0)" LOC = "AC4"; +#NET "IOMXOUT(0)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXOUT(1)" LOC = "AA8"; +#NET "IOMXOUT(1)" IOSTANDARD="LVCMOS33"; + +#NET "IOMXOUT(2)" LOC = "AA9"; +#NET "IOMXOUT(2)" IOSTANDARD="LVCMOS33"; + +#NET "SELALTBUS" LOC = "AK6"; +#NET "SELALTBUS" IOSTANDARD="LVCMOS33"; +#NET "SELALTBUS" SLEW="FAST"; + +#NET "REGABDACLD" LOC = "AD5"; +#NET "REGABDACLD" IOSTANDARD="LVCMOS33"; +#NET "REGABDACLD" SLEW="FAST"; + +#NET "REGABSTBLD" LOC = "AD4"; +#NET "REGABSTBLD" IOSTANDARD="LVCMOS33"; +#NET "REGABSTBLD" SLEW="FAST"; + +#NET "SELCMD" LOC = "AE6"; +#NET "SELCMD" IOSTANDARD="LVCMOS33"; +#NET "SELCMD" SLEW="FAST"; + +#NET "CMDEXTTRIGGER" LOC = "AF6"; +#NET "CMDEXTTRIGGER" IOSTANDARD="LVCMOS33"; +#NET "CMDEXTTRIGGER" SLEW="FAST"; + +#NET "CMDALTPLS" LOC = "AC3"; +#NET "CMDALTPLS" IOSTANDARD="LVCMOS33"; +#NET "CMDALTPLS" SLEW="FAST"; + +#NET "iHSIOtrigger" LOC="J14"; +#NET "iHSIOtrigger" IOSTANDARD="LVTTL"; +#NET "iHSIOtrigger" SLEW=FAST; + +#NET "oHSIObusy" LOC="H19"; +#NET "oHSIObusy" IOSTANDARD="LVTTL"; +#NET "oHSIObusy" SLEW=FAST; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "serialout_p(0)" LOC = "U3"; +NET "serialout_n(0)" LOC = "T3"; +#NET "serialout_p(1)" LOC = "AF10"; +#NET "serialout_n(1)" LOC = "AG10"; +#NET "serialout_p(3)" LOC = "AH14"; +#NET "serialout_n(3)" LOC = "AJ14"; +#NET "serialout_p(2)" LOC = "AH10"; +#NET "serialout_n(2)" LOC = "AJ10"; +#NET "serialout_p(4)" LOC = "AJ12"; +#NET "serialout_n(4)" LOC = "AK12"; +#NET "serialout_p(5)" LOC = "AH8"; +#NET "serialout_n(5)" LOC = "AH7"; +#NET "serialout_p(6)" LOC = "AF11"; +#NET "serialout_n(6)" LOC = "AG11"; +#NET "serialout_p(7)" LOC = "AJ9"; +#NET "serialout_n(7)" LOC = "AH9"; +#NET "oExttrgclkP" LOC = "AJ9"; +#NET "oExttrgclkN" LOC = "AH9"; + + +#NET "serialout_p(11)" LOC = "AF15"; +#NET "serialout_n(11)" LOC = "AG15"; +#NET "serialout_p(12)" LOC = "AB13"; +#NET "serialout_n(12)" LOC = "AA13"; +#NET "serialout_p(13)" LOC = "AD10"; +#NET "serialout_n(13)" LOC = "AD9"; +#NET "serialout_p(14)" LOC = "AB11"; +#NET "serialout_n(14)" LOC = "AA11"; +#NET "serialout_p(15)" LOC = "AD14"; +#NET "serialout_n(15)" LOC = "AC13"; +#NET "oExtbusyP" LOC = "AD14"; +#NET "oExtbusyN" LOC = "AC13"; + +#NET "serialout(8)" LOC = "AL21"; + +NET "serialin_p(0)" LOC = "M3"; +NET "serialin_n(0)" LOC = "N3"; +#NET "serialin_p(1)" LOC = "AF9"; +#NET "serialin_n(1)" LOC = "AE9"; +#NET "serialin_p(3)" LOC = "AL10"; +#NET "serialin_n(3)" LOC = "AM10"; +#NET "serialin_p(2)" LOC = "AL9"; +#NET "serialin_n(2)" LOC = "AK9"; +#NET "serialin_p(4)" LOC = "AL11"; +#NET "serialin_n(4)" LOC = "AM11"; +#NET "serialin_p(5)" LOC = "AK13"; +#NET "serialin_n(5)" LOC = "AL13"; +#NET "serialin_p(6)" LOC = "AK14"; +#NET "serialin_n(6)" LOC = "AL14"; +##NET "serialin_p(7)" LOC = "AM8"; +##NET "serialin_n(7)" LOC = "AM7"; +#NET "iExttriggerP" LOC = "AM8"; +#NET "iExttriggerN" LOC = "AM7"; +#NET "serialin_p(8)" LOC = "AM13"; +#NET "serialin_n(8)" LOC = "AM12"; + +#NET "serialin_p(11)" LOC = "K28"; +#NET "serialin_n(11)" LOC = "J27"; +#NET "serialin_p(12)" LOC = "H30"; +#NET "serialin_n(12)" LOC = "H29"; +#NET "serialin_p(13)" LOC = "C23"; +#NET "serialin_n(13)" LOC = "C22"; +#NET "serialin_p(14)" LOC = "E23"; +#NET "serialin_n(14)" LOC = "F23"; +#NET "serialin_p(15)" LOC = "G30"; +#NET "serialin_n(15)" LOC = "F30"; +#NET "iExtrstP" LOC = "G30"; +#NET "iExtrstN" LOC = "F30"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout(8)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(8)" SLEW = "FAST"; + +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.fei3 b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.fei3 new file mode 100644 index 0000000000000000000000000000000000000000..6d214340318e889bae234b6124004944dbc6aca9 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.fei3 @@ -0,0 +1,161 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_HsioCosmicCore/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore/channelmask(*) TIG; +NET U_HsioCosmicCore/channeloutmask(*) TIG; + +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + + + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +#NET "iMgtRxN" LOC = "AA1"; +#NET "iMgtRxP" LOC = "Y1"; +#NET "oMgtTxN" LOC = "V1"; +#NET "oMgtTxP" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +#NET "transDis1" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; + +NET "refclk_p" LOC = "J25"; +NET "refclk_p" IOSTANDARD="LVDS_25"; +NET "refclk_n" LOC = "H25"; +NET "refclk_n" IOSTANDARD="LVDS_25"; + +NET "xclk_p" LOC = "E24"; +NET "xclk_p" IOSTANDARD="LVDS_25"; +NET "xclk_n" LOC = "F24"; +NET "xclk_n" IOSTANDARD="LVDS_25"; + +NET "clkout40" LOC = "AF16"; +NET "clkout40" IOSTANDARD="LVCMOS25"; +NET "clkout40" SLEW="FAST"; + +NET "iHSIOtrigger" LOC="J14"; +NET "iHSIOtrigger" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger" SLEW=FAST; + +NET "oHSIObusy" LOC="H19"; +NET "oHSIObusy" IOSTANDARD="LVTTL"; +NET "oHSIObusy" SLEW=FAST; + +NET "serialout(0)" LOC = "AE16"; +NET "serialout(0)" SLEW = "FAST"; +NET "serialout(0)" IOSTANDARD = "LVCMOS25"; + +NET "serialin(0)" LOC = "AE18"; +NET "serialout(0)" IOSTANDARD = "LVCMOS25"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + + + diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.full b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.full new file mode 100644 index 0000000000000000000000000000000000000000..75a17a88d7f351c06e59fbeccdad512ebb2b2f58 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.full @@ -0,0 +1,412 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore*/channelmask(*) TIG; +NET U_HsioCosmicCore*/channeloutmask(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(?) maxskew = 250 ps ; +#NET U_HsioCosmicCore/deldata maxskew = 250 ps ; + +INST "U_HsioCosmicCore*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +#NET "iMgtRxN2" LOC = "AA1"; +#NET "iMgtRxP2" LOC = "Y1"; +#NET "oMgtTxN2" LOC = "V1"; +#NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +# fiber 2 +#NET "transDis2" LOC = "AK4"; +#NET "transDis2" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "G15"; +NET "iExtreload" IOSTANDARD="LVCMOS25"; +NET "iExtreload" PULLUP; + +NET "refclk_p" LOC = "J25"; +NET "refclk_p" IOSTANDARD="LVDS_25"; +NET "refclk_n" LOC = "H25"; +NET "refclk_n" IOSTANDARD="LVDS_25"; + +NET "xclk_p" LOC = "E24"; +NET "xclk_p" IOSTANDARD="LVDS_25"; +NET "xclk_n" LOC = "F24"; +NET "xclk_n" IOSTANDARD="LVDS_25"; + +NET "clkout40" LOC = "AJ29"; +NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "clkout40" SLEW="FAST"; + +NET "RD2" LOC = "AJ24"; +NET "RD2" IOSTANDARD="LVCMOS33"; +NET "RD2" SLEW="FAST"; + +NET "AuxClk" LOC = "AK29"; +NET "AuxClk" IOSTANDARD="LVCMOS33"; +NET "AuxClk" SLEW="FAST"; + +NET "RA" LOC = "AM30"; +NET "RA" IOSTANDARD="LVCMOS33"; +NET "RA" SLEW="FAST"; + +NET "RD1" LOC = "AH24"; +NET "RD1" IOSTANDARD="LVCMOS33"; +NET "RD1" SLEW="FAST"; + +NET "IOMXIN(3)" LOC = "AG3"; +NET "IOMXIN(3)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(2)" LOC = "AF3"; +NET "IOMXIN(2)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(1)" LOC = "W9"; +NET "IOMXIN(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXIN(0)" LOC = "Y9"; +NET "IOMXIN(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXSEL(2)" LOC = "AB6"; +NET "IOMXSEL(2)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(2)" SLEW="FAST"; + +NET "IOMXSEL(1)" LOC = "AA6"; +NET "IOMXSEL(1)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(1)" SLEW="FAST"; + +NET "IOMXSEL(0)" LOC = "Y6"; +NET "IOMXSEL(0)" IOSTANDARD="LVCMOS33"; +NET "IOMXSEL(0)" SLEW="FAST"; + +NET "HITOR" LOC = "AL29"; +NET "HITOR" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(0)" LOC = "AC4"; +NET "IOMXOUT(0)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(1)" LOC = "AA8"; +NET "IOMXOUT(1)" IOSTANDARD="LVCMOS33"; + +NET "IOMXOUT(2)" LOC = "AA9"; +NET "IOMXOUT(2)" IOSTANDARD="LVCMOS33"; + +NET "SELALTBUS" LOC = "AK6"; +NET "SELALTBUS" IOSTANDARD="LVCMOS33"; +NET "SELALTBUS" SLEW="FAST"; + +NET "REGABDACLD" LOC = "AD5"; +NET "REGABDACLD" IOSTANDARD="LVCMOS33"; +NET "REGABDACLD" SLEW="FAST"; + +NET "REGABSTBLD" LOC = "AD4"; +NET "REGABSTBLD" IOSTANDARD="LVCMOS33"; +NET "REGABSTBLD" SLEW="FAST"; + +NET "SELCMD" LOC = "AE6"; +NET "SELCMD" IOSTANDARD="LVCMOS33"; +NET "SELCMD" SLEW="FAST"; + +NET "CMDEXTTRIGGER" LOC = "AF6"; +NET "CMDEXTTRIGGER" IOSTANDARD="LVCMOS33"; +NET "CMDEXTTRIGGER" SLEW="FAST"; + +NET "CMDALTPLS" LOC = "AC3"; +NET "CMDALTPLS" IOSTANDARD="LVCMOS33"; +NET "CMDALTPLS" SLEW="FAST"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +#NET "oHSIObusy" LOC="H19"; +#NET "oHSIObusy" IOSTANDARD="LVTTL"; +#NET "oHSIObusy" SLEW=FAST; + +NET "oHSIOtrigger" LOC="L15"; +NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +NET "oHSIOtrigger" SLEW=FAST; + +NET "iHSIObusy" LOC="H19"; +NET "iHSIObusy" IOSTANDARD="LVTTL"; +NET "iHSIObusy" SLEW=FAST; +NET "iHSIObusy" PULLDOWN; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +# DI1 +NET "oExttrgclkP" LOC = "AH15"; +NET "oExttrgclkN" LOC = "AJ15"; +# DI3 +NET "oExtbusyP" LOC = "AD14"; +NET "oExtbusyN" LOC = "AC13"; +#DTO1 +NET "iExttriggerP" LOC = "J31"; +NET "iExttriggerN" LOC = "J30"; +# DTO3 +NET "iExtrstP" LOC = "G30"; +NET "iExtrstN" LOC = "F30"; + +NET "serialout_p(0)" LOC = "AG12"; +NET "serialout_n(0)" LOC = "AH12"; +NET "serialout_p(1)" LOC = "AF10"; +NET "serialout_n(1)" LOC = "AG10"; +NET "serialout_p(3)" LOC = "AH14"; +NET "serialout_n(3)" LOC = "AJ14"; +NET "serialout_p(2)" LOC = "AH10"; +NET "serialout_n(2)" LOC = "AJ10"; +NET "serialout_p(4)" LOC = "AJ12"; +NET "serialout_n(4)" LOC = "AK12"; +NET "serialout_p(5)" LOC = "AH8"; +NET "serialout_n(5)" LOC = "AH7"; +NET "serialout_p(6)" LOC = "AF11"; +NET "serialout_n(6)" LOC = "AG11"; +NET "serialout_p(7)" LOC = "AJ9"; +NET "serialout_n(7)" LOC = "AH9"; +#NET "oExttrgclkP" LOC = "AJ9"; +#NET "oExttrgclkN" LOC = "AH9"; + + +NET "serialout_p(11)" LOC = "AF15"; +NET "serialout_n(11)" LOC = "AG15"; +NET "serialout_p(12)" LOC = "AB13"; +NET "serialout_n(12)" LOC = "AA13"; +NET "serialout_p(13)" LOC = "AD10"; +NET "serialout_n(13)" LOC = "AD9"; +NET "serialout_p(14)" LOC = "AB11"; +NET "serialout_n(14)" LOC = "AA11"; +#NET "serialout_p(15)" LOC = "AD14"; +#NET "serialout_n(15)" LOC = "AC13"; +#NET "oExtbusyP" LOC = "AD14"; +#NET "oExtbusyN" LOC = "AC13"; + +NET "serialout(8)" LOC = "AL21"; + +NET "serialin_p(0)" LOC = "AK7"; +NET "serialin_n(0)" LOC = "AJ7"; +NET "serialin_p(1)" LOC = "AF9"; +NET "serialin_n(1)" LOC = "AE9"; +NET "serialin_p(3)" LOC = "AL10"; +NET "serialin_n(3)" LOC = "AM10"; +NET "serialin_p(2)" LOC = "AL9"; +NET "serialin_n(2)" LOC = "AK9"; +NET "serialin_p(4)" LOC = "AL11"; +NET "serialin_n(4)" LOC = "AM11"; +NET "serialin_p(5)" LOC = "AK13"; +NET "serialin_n(5)" LOC = "AL13"; +NET "serialin_p(6)" LOC = "AK14"; +NET "serialin_n(6)" LOC = "AL14"; +NET "serialin_p(7)" LOC = "AM8"; +NET "serialin_n(7)" LOC = "AM7"; +#NET "iExttriggerP" LOC = "AM8"; +#NET "iExttriggerN" LOC = "AM7"; +NET "serialin_p(8)" LOC = "AM13"; +NET "serialin_n(8)" LOC = "AM12"; + +NET "serialin_p(11)" LOC = "K28"; +NET "serialin_n(11)" LOC = "J27"; +NET "serialin_p(12)" LOC = "H30"; +NET "serialin_n(12)" LOC = "H29"; +NET "serialin_p(13)" LOC = "C23"; +NET "serialin_n(13)" LOC = "C22"; +NET "serialin_p(14)" LOC = "E23"; +NET "serialin_n(14)" LOC = "F23"; +#NET "serialin_p(15)" LOC = "G30"; +#NET "serialin_n(15)" LOC = "F30"; +#NET "iExtrstP" LOC = "G30"; +#NET "iExtrstN" LOC = "F30"; + + +NET "discinP(0)" LOC = "AD7"; +NET "discinP(1)" LOC = "AD6"; +NET "discinP(2)" LOC = "AM6"; +NET "discinP(3)" LOC = "AL6"; + +NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +# ADC I2C +NET "adcI2cScl" LOC = "AM3"; +NET "adcI2cSda" LOC = "AL3"; +NET "adcAS" LOC = "AJ6"; + +NET "adcI2cScl" IOSTANDARD = "LVCMOS33"; +NET "adcI2cSda" IOSTANDARD = "LVCMOS33"; +NET "adcAS" IOSTANDARD = "LVCMOS33"; + +NET "adcI2cScl" PULLUP; +NET "adcI2cSda" PULLUP; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout(8)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(8)" SLEW = "FAST"; + +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.oldCosmic b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.oldCosmic new file mode 100644 index 0000000000000000000000000000000000000000..e7412378a25082988027163c0e140e1db35ed776 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.ucf.oldCosmic @@ -0,0 +1,219 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioCosmic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +#NET clk320 TNM_NET = FFS clk320; +#NET sysClk250 TNM_NET = FFS sysClk250; +#NET mainClk TNM_NET = FFS mainClk; +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 3.2 ns HIGH 50%; +#TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +#TIMEGRP TG_sysClk250_r = RISING sysClk250; +#TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioCosmicCore*/channelmask(*) TIG; +NET U_HsioCosmicCore*/channeloutmask(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(?) maxskew = 250 ps ; +#NET U_HsioCosmicCore/deldata maxskew = 250 ps ; + +INST "U_HsioCosmicCore*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +#NET "iPgpRefClkP" LOC = "J1"; +#NET "iPgpRefClkM" LOC = "K1"; +NET "iPgpRefClkP" LOC = "AP29"; +NET "iPgpRefClkM" LOC = "AP28"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +#NET "iMgtRxN" LOC = "N1"; +#NET "iMgtRxP" LOC = "M1"; +#NET "oMgtTxN" LOC = "T1"; +#NET "oMgtTxP" LOC = "R1"; +# fiber 2 +#NET "iMgtRxN2" LOC = "AA1"; +#NET "iMgtRxP2" LOC = "Y1"; +#NET "oMgtTxN2" LOC = "V1"; +#NET "oMgtTxP2" LOC = "U1"; +# fiber RTM 1 +#NET "iMgtRxN" LOC = "AP25"; +#NET "iMgtRxP" LOC = "AP26"; +#NET "oMgtTxN" LOC = "AP22"; +#NET "oMgtTxP" LOC = "AP23"; +# fiber RTM 2 +NET "iMgtRxN" LOC = "AP17"; +NET "iMgtRxP" LOC = "AP18"; +NET "oMgtTxN" LOC = "AP20"; +NET "oMgtTxP" LOC = "AP21"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +# fiber 2 +#NET "transDis2" LOC = "AK4"; +#NET "transDis2" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "L15"; +NET "iExtreload" IOSTANDARD="LVCMOS33"; +NET "iExtreload" PULLUP; + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AF21"; +NET "clkout40" LOC = "AF16"; +NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "clkout40" SLEW="FAST"; + +NET "HITOR" LOC = "AL29"; +NET "HITOR" IOSTANDARD="LVCMOS33"; + + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +NET "oHSIObusy" LOC="H19"; +NET "oHSIObusy" IOSTANDARD="LVTTL"; +NET "oHSIObusy" SLEW=FAST; + +#NET "oHSIOtrigger" LOC="L14"; +#NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +#NET "oHSIOtrigger" SLEW=FAST; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +# DI1 +#NET "oExttrgclkP" LOC = "AH15"; +#NET "oExttrgclkN" LOC = "AJ15"; +# DI3 +#NET "oExtbusyP" LOC = "AD14"; +#NET "oExtbusyN" LOC = "AC13"; +#DTO1 +#NET "iExttriggerP" LOC = "J31"; +#NET "iExttriggerN" LOC = "J30"; +# DTO3 +#NET "iExtrstP" LOC = "G30"; +#NET "iExtrstN" LOC = "F30"; + +NET "serialout(0)" LOC = "AE16"; +#NET "serialout(0)" LOC = "AL21"; + + +#NET "serialin(0)" LOC = "AK21"; +NET "serialin(0)" LOC = "AE18"; + +NET "discinP(0)" LOC = "AD7"; +NET "discinP(1)" LOC = "AD6"; +NET "discinP(2)" LOC = "AM6"; +NET "discinP(3)" LOC = "AG6"; + +NET "discinP(0)" IOSTANDARD = "LVCMOS33"; +NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +NET "discinP(2)" IOSTANDARD = "LVCMOS33"; +NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin(0)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(0)" IOSTANDARD = "LVCMOS33"; + +NET "serialout(0)" SLEW = "FAST"; + diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd new file mode 120000 index 0000000000000000000000000000000000000000..ead52a632d9fad3de0767da4a73e3287b32a0bcc --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd @@ -0,0 +1 @@ +HsioCosmic.vhd.4core \ No newline at end of file diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.2core b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.2core new file mode 100755 index 0000000000000000000000000000000000000000..266f2a2693277abdd52a0a7bcd02197fba4d58a4 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.2core @@ -0,0 +1,786 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + iMgtRxN2 : in std_logic; + iMgtRxP2 : in std_logic; + oMgtTxN2 : out std_logic; + oMgtTxP2 : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic; + transDis2 : out std_logic; + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal reload1 : std_logic; + signal reload2 : std_logic; + signal extreload : std_logic; + signal resetOut : std_logic; + signal resetOut1 : std_logic; + signal resetOut2 : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal mgtRxN2 : std_logic; + signal mgtRxP2 : std_logic; + signal mgtTxN2 : std_logic; + signal mgtTxP2 : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal HITORout : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal serialoutm1 : std_logic_vector(15 downto 0); + signal serialoutm2 : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal serialinm1 : std_logic_vector(15 downto 0); + signal serialinm2 : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmode1 : std_logic_vector(1 downto 0); + signal calibmode2 : std_logic_vector(1 downto 0); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabled1 : std_logic; + signal trigenabled2 : std_logic; + signal trigenabled : std_logic; + signal paused1 : std_logic; + signal paused2 : std_logic; + signal paused : std_logic; + signal triggermask1 : std_logic_vector(15 downto 0); + signal triggermask2 : std_logic_vector(15 downto 0); + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelay1 : std_logic; + signal resetdelay2 : std_logic; + signal resetdelay : std_logic; + signal incrementdelay1: std_logic_vector(4 downto 0); + signal incrementdelay2: std_logic_vector(4 downto 0); + signal incrementdelay: std_logic_vector(4 downto 0); + signal discop1 : std_logic_vector(15 downto 0); + signal discop2 : std_logic_vector(15 downto 0); + signal discop : std_logic_vector(15 downto 0); + signal telescopeop1 : std_logic_vector(2 downto 0); + signal telescopeop2 : std_logic_vector(2 downto 0); + signal telescopeop : std_logic_vector(2 downto 0); + signal period1 : std_logic_vector(31 downto 0); + signal period2 : std_logic_vector(31 downto 0); + signal period : std_logic_vector(31 downto 0); + signal fifothresh : std_logic; + signal fifothresh1 : std_logic; + signal fifothresh2 : std_logic; + signal serbusy1 : std_logic; + signal serbusy2 : std_logic; + signal serbusy : std_logic; + signal tdcreadoutbusy1: std_logic; + signal tdcreadoutbusy2: std_logic; + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1a1 : std_logic; + signal l1a2 : std_logic; + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCore1 : std_logic; + signal rstFromCore2 : std_logic; + signal rstFromCore : std_logic; + signal hitbus : std_logic_vector(1 downto 0); + signal present : std_logic_vector(1 downto 0); + signal phaseclksel : std_logic; + signal phaseclksel1 : std_logic; + signal phaseclksel2 : std_logic; + signal startmeas : std_logic; + signal startmeas1 : std_logic; + signal startmeas2 : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + mgtRxN2 <= iMgtRxN2; + mgtRxP2 <= iMgtRxP2; + oMgtTxN2 <= mgtTxN2; + oMgtTxP2 <= mgtTxP2; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + + U_transdis : OBUF port map ( I => '0' , O => transDis1 ); + U_transdis2 : OBUF port map ( I => '0' , O => transDis2 ); + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtriggero : OBUF port map ( I => l1a , O => oHSIOtrigger); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + + SERIAL_IO_DATA: + for I in 0 to 7 generate +-- U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA; + + U_serialout : OBUF port map ( I => serialoutb(8) , O => serialout(8) ); + U_serialin_pn_8 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + paused <= paused1 or paused2; + resetdelay <= resetdelay1 or resetdelay2; + incrementdelay <= incrementdelay1 or incrementdelay2; + serbusy <= (serbusy1 and present(0)) or (serbusy2 and present(1)); + tdcreadoutbusy<= tdcreadoutbusy1 or tdcreadoutbusy2; + rstFromCore <= rstFromCore1 or rstFromCore2; + + fifothresh <= (fifothresh1 and present(0)) or (fifothresh2 and present(1)); + trigenabled <= (trigenabled1 or not present(0)) and (trigenabled2 or not present(1)) and (present(0) or present(1)); + l1a1 <= l1a and present(0); + l1a2 <= l1a and present(1); + + serialinm1 <= x"000"&serialinb(3 downto 0); + serialinm2 <= x"000"&serialinb(7 downto 4); + serialoutb <= x"00" & serialoutm2(3 downto 0) & serialoutm1(3 downto 0); + + with present select discop <= discop2 when "10", discop1 when others; + with present select calibmode <= calibmode2 when "10", calibmode1 when others; + with present select triggermask <= triggermask2 when "10", triggermask1 when others; + with present select period <= period2 when "10", period1 when others; + with present select telescopeop <= telescopeop2 when "10", telescopeop1 when others; + with present select phaseclksel <= phaseclksel2 when "10", phaseclksel1 when others; + with present select startmeas <= startmeas2 when "10", startmeas1 when others; + + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + -- hardware inputs + discin => discinb, + hitbusin => hitbus, + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => open, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + + reload <= reload1 and reload2 and extreload; -- active low + resetOut <= resetOut1 or resetOut2; + -- FPGA Core + U_HsioCosmicCore1: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 3, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersize => 16384, + bpmDefault => '0', + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload1, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinm1, + serialout => serialoutm1, clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut1, l1a => l1a1, + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode1, startmeas => startmeas1, + pausedout => paused1, present => present(0), + trgenabledout => trigenabled1, rstFromCore => rstFromCore1, + fifothresh => fifothresh1, triggermask => triggermask1, + discop => discop1, period => period1, + telescopeop => telescopeop1, resetdelay => resetdelay1, + incrementdelay => incrementdelay1, + sbusy => serbusy1, tdcbusy => tdcreadoutbusy1, + phaseclksel => phaseclksel1 , hitbus => hitbus(0), + debug => debug, + exttriggero => exttriggero, extrsto => extrsto, + doricreset => open, + dispDigitA => dispDigitE, dispDigitB => dispDigitF, + dispDigitC => dispDigitG, dispDigitD => dispDigitH, + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf + ); + U_HsioCosmicCore2: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 3, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersize => 16384, + bpmDefault => '0', + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload2, + mgtRxN => mgtRxN2, + mgtRxP => mgtRxP2, mgtTxN => mgtTxN2, + mgtTxP => mgtTxP2, serialin => serialinm2, + serialout => serialoutm2, clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut2, + l1a => l1a2, latchtriggerword => triggerword, + tcounter1=>tcounter1, tcounter2=>tcounter2, + busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode2, startmeas => startmeas2, + pausedout => paused2, present => present(1), + trgenabledout => trigenabled2, rstFromCore => rstFromCore2, + fifothresh => fifothresh2, triggermask => triggermask2, + discop => discop2, period => period2, + telescopeop => telescopeop2, resetdelay => resetdelay2, + incrementdelay => incrementdelay2, + sbusy => serbusy2, tdcbusy => tdcreadoutbusy2, + phaseclksel=>phaseclksel2, hitbus => hitbus(1), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + dispDigitA => dispDigitA, dispDigitB => dispDigitB, + dispDigitC => dispDigitC, dispDigitD => dispDigitD, + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf + ); + sysClk125i <= not sysClk125; + --sysClk125i<=debug(0); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.4core b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.4core new file mode 100755 index 0000000000000000000000000000000000000000..7ec9f154631188792cf69546b6ca6650f8d081e6 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.4core @@ -0,0 +1,986 @@ +------------------------------------------------------------------------------- +-- Title : HsioCosmic, Top Level +-- Project : ATLAS Pixel Detector +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Martin Kocian, kocian@slac.stanford.edu +-- Created : 2009 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for cosmic interface board +------------------------------------------------------------------------------- +-- Copyright (c) 2009 by Martin Kocian. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; +use work.StdRtlPkg.all; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic_vector(3 downto 0); + iMgtRxP : in std_logic_vector(3 downto 0); + oMgtTxN : out std_logic_vector(3 downto 0); + oMgtTxP : out std_logic_vector(3 downto 0); + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Temperature ADC + adcI2cScl: inout std_logic; + adcI2cSda: inout std_logic; + adcAS: out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis : out std_logic_vector(3 downto 0); + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal reloadc : std_logic_vector(3 downto 0); + signal extreload : std_logic; + signal resetOut : std_logic; + signal resetOutc : std_logic_vector(3 downto 0); + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal HITORout : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal serialoutm1 : std_logic_vector(15 downto 0); + signal serialoutm2 : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal serialinm1 : std_logic_vector(15 downto 0); + signal serialinm2 : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmodec : Slv2Array(0 to 3); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabledc : std_logic_vector(3 downto 0); + signal trigenabled : std_logic; + signal pausedc : std_logic_vector(3 downto 0); + signal paused : std_logic; + signal triggermaskc : Slv16Array(0 to 3); + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelayc : std_logic_vector(3 downto 0); + signal resetdelay : std_logic; + signal incrementdelayc: Slv5Array(0 to 3); + signal incrementdelay: std_logic_vector(4 downto 0); + signal discopc : Slv16Array(0 to 3); + signal discop : std_logic_vector(15 downto 0); + signal telescopeopc : Slv3Array(0 to 3); + signal telescopeop : std_logic_vector(2 downto 0); + signal periodc : Slv32Array(0 to 3); + signal period : std_logic_vector(31 downto 0); + signal fifothreshc : std_logic_vector(3 downto 0); + signal fifothresh : std_logic; + signal serbusyc : std_logic_vector(3 downto 0); + signal serbusy : std_logic; + signal tdcreadoutbusyc: std_logic_vector(3 downto 0); + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1ac : std_logic_vector(3 downto 0); + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCorec : std_logic_vector(3 downto 0); + signal rstFromCore : std_logic; + signal hitbus : std_logic_vector(3 downto 0); + signal present : std_logic_vector(3 downto 0); + signal phaseclkselc : std_logic_vector(3 downto 0); + signal phaseclksel : std_logic; + signal startmeasc : std_logic_vector(3 downto 0); + signal startmeas : std_logic; + signal dispDigitAA : Slv8Array(0 to 3); + signal dispDigitBB : Slv8Array(0 to 3); + signal dispDigitCC : Slv8Array(0 to 3); + signal dispDigitDD : Slv8Array(0 to 3); + signal transdissig : std_logic_vector(3 downto 0); + signal trigAdc : sl; + signal trigAdcc : slv(3 downto 0); + signal sendAdcData : sl; + type adcarray is array(3 downto 0) of Slv16Array(11 downto 0); + signal adcDatachan : adcarray; + signal adcData : Slv16Array(11 downto 0); + signal phasebusySelc : Slv2Array(3 downto 0); + signal phasebusySel : slv(1 downto 0); + signal phasebusyEnc : slv(3 downto 0); + signal phasebusyEn : sl; + + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + + TRANSDISGEN: + for I in 0 to 3 generate + U_transdis : OBUF port map ( I => transdissig(I) , O => transDis(I) ); + end generate TRANSDISGEN; + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtriggero : OBUF port map ( I => l1a , O => oHSIOtrigger); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + + SERIAL_IO_DATA: + for I in 0 to 7 generate +-- U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA; + + U_serialout : OBUF port map ( I => serialoutb(8) , O => serialout(8) ); + U_serialin_pn_8 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + paused <= uOr(pausedc); + resetdelay <= uOr(resetdelayc); + incrementdelay <= incrementdelayc(0) or incrementdelayc(1) or incrementdelayc (2) or incrementdelayc(3); + serbusy <= uOr(serbusyc and present); + tdcreadoutbusy<= uOr(tdcreadoutbusyc); + rstFromCore <= uOr(rstFromCorec); + + fifothresh <= uOr(fifothreshc and present); + trigenabled <= uAnd(trigenabledc or not present) and uOr(present); + trigAdc <= uOr(trigAdcc and present); + + reload <= uAnd(reloadc) and extreload; -- active low + resetOut <= uOr(resetOutc); + phasebusyEn <= uOr(phasebusyEnc); + phasebusySel <= phasebusySelc(0) or phasebusySelc(1) or phasebusySelc(2) or phasebusySelc(3); + + process(present, discopc) begin + if(present(0)='1')then discop<=discopc(0); + elsif(present(1)='1')then discop<=discopc(1); + elsif(present(2)='1')then discop<=discopc(2); + else discop<=discopc(3); + end if; + end process; + + process(present, calibmodec) begin + if(present(0)='1')then calibmode<=calibmodec(0); + elsif(present(1)='1')then calibmode<=calibmodec(1); + elsif(present(2)='1')then calibmode<=calibmodec(2); + else calibmode<=calibmodec(3); + end if; + end process; + + process(present, triggermaskc) begin + if(present(0)='1')then triggermask<=triggermaskc(0); + elsif(present(1)='1')then triggermask<=triggermaskc(1); + elsif(present(2)='1')then triggermask<=triggermaskc(2); + else triggermask<=triggermaskc(3); + end if; + end process; + + process(present, periodc) begin + if(present(0)='1')then period<=periodc(0); + elsif(present(1)='1')then period<=periodc(1); + elsif(present(2)='1')then period<=periodc(2); + else period<=periodc(3); + end if; + end process; + + process(present, telescopeopc) begin + if(present(0)='1')then telescopeop<=telescopeopc(0); + elsif(present(1)='1')then telescopeop<=telescopeopc(1); + elsif(present(2)='1')then telescopeop<=telescopeopc(2); + else telescopeop<=telescopeopc(3); + end if; + end process; + + process(present, phaseclkselc) begin + if(present(0)='1')then phaseclksel<=phaseclkselc(0); + elsif(present(1)='1')then phaseclksel<=phaseclkselc(1); + elsif(present(2)='1')then phaseclksel<=phaseclkselc(2); + else phaseclksel<=phaseclkselc(3); + end if; + end process; + + process(present, startmeasc) begin + if(present(0)='1')then startmeas<=startmeasc(0); + elsif(present(1)='1')then startmeas<=startmeasc(1); + elsif(present(2)='1')then startmeas<=startmeasc(2); + else startmeas<=startmeasc(3); + end if; + end process; + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + clk160 => pgpClk, + rst160 => pgpReset, + -- hardware inputs + discin => discinb, + hitbusin => hitbus(1 downto 0), + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => open, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + phasebusyEn => phasebusyEn, + phasebusySel => phasebusySel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + + -- FPGA Cores + -- Telescope 1 + U_HsioCosmicCore0: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 2, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 4096, + buffersizetdc => 16384, + fixed160 => '1', + encodingDefault => "00", + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reloadc(0), + mgtRxN => iMgtRxN(0), + mgtRxP => iMgtRxP(0), mgtTxN => oMgtTxN(0), + mgtTxP => oMgtTxP(0), + serialin(2 downto 0) => serialinb(2 downto 0), + serialin(15 downto 3) => "0000000000000", + serialout(2 downto 0) => serialoutb(2 downto 0), + serialout(15 downto 3) => open, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOutc(0), l1a => l1ac(0), + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmodec(0), startmeas => startmeasc(0), + pausedout => pausedc(0), present => present(0), + trgenabledout => trigenabledc(0), rstFromCore => rstFromCorec(0), + fifothresh => fifothreshc(0), triggermask => triggermaskc(0), + discop => discopc(0), period => periodc(0), + telescopeop => telescopeopc(0), resetdelay => resetdelayc(0), + incrementdelay => incrementdelayc(0), + sbusy => serbusyc(0), tdcbusy => tdcreadoutbusyc(0), + phaseclksel => phaseclkselc(0) , hitbus => hitbus(0), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + phasebusyEn => phasebusyEnc(0), phasebusySel => phasebusySelc(0), + dispDigitA => dispDigitAA(0), dispDigitB => dispDigitBB(0), + dispDigitC => dispDigitCC(0), dispDigitD => dispDigitDD(0), + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => trigAdcc(0), + sendAdcData => sendAdcData, adcData => adcDataChan(0) + ); + --Remap ADC channels. Unused channel is f. + adcDataChan(0)(0)<=x"000f"; + adcDataChan(0)(1)<=x"0f0f"; + adcDataChan(0)(2)<=x"0f0f"; + adcDataChan(0)(3)<=x"0f0f"; + adcDataChan(0)(11 downto 4)<=adcData(11 downto 4); + -- Telescope 2 + U_HsioCosmicCore1: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 2, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 4096, + buffersizetdc => 16384, + fixed160 => '1', + encodingDefault => "00", + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reloadc(1), + mgtRxN => iMgtRxN(1), + mgtRxP => iMgtRxP(1), mgtTxN => oMgtTxN(1), + mgtTxP => oMgtTxP(1), + serialin(2 downto 0) => serialinb(5 downto 3), + serialin(15 downto 3) => "0000000000000", + serialout(2 downto 0) => serialoutb(5 downto 3), + serialout(15 downto 3) => open, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOutc(1), l1a => l1ac(1), + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmodec(1), startmeas => startmeasc(1), + pausedout => pausedc(1), present => present(1), + trgenabledout => trigenabledc(1), rstFromCore => rstFromCorec(1), + fifothresh => fifothreshc(1), triggermask => triggermaskc(1), + discop => discopc(1), period => periodc(1), + telescopeop => telescopeopc(1), resetdelay => resetdelayc(1), + incrementdelay => incrementdelayc(1), + sbusy => serbusyc(1), tdcbusy => tdcreadoutbusyc(1), + phaseclksel => phaseclkselc(1) , hitbus => hitbus(1), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + phasebusyEn => phasebusyEnc(1), phasebusySel => phasebusySelc(1), + dispDigitA => dispDigitAA(1), dispDigitB => dispDigitBB(1), + dispDigitC => dispDigitCC(1), dispDigitD => dispDigitDD(1), + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => trigAdcc(1), + sendAdcData => sendAdcData, adcData => adcDataChan(1) + ); + adcDataChan(1)(0)<=x"0f00"; + adcDataChan(1)(1)<=x"0f0f"; + adcDataChan(1)(2)<=x"0f0f"; + adcDataChan(1)(3)<=x"0f0f"; + adcDataChan(1)(11 downto 4)<=adcData(11 downto 4); + -- Telescope 3 + U_HsioCosmicCore2: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 0, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 8192, + buffersizetdc => 16384, + fixed160 => '0', + encodingDefault => "00", + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reloadc(2), + mgtRxN => iMgtRxN(2), + mgtRxP => iMgtRxP(2), mgtTxN => oMgtTxN(2), + mgtTxP => oMgtTxP(2), + serialin(0) => serialinb(6), + serialin(15 downto 1) => "000000000000000", + serialout(0) => serialoutb(6), + serialout(15 downto 1) => open, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOutc(2), l1a => l1ac(2), + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmodec(2), startmeas => startmeasc(2), + pausedout => pausedc(2), present => present(2), + trgenabledout => trigenabledc(2), rstFromCore => rstFromCorec(2), + fifothresh => fifothreshc(2), triggermask => triggermaskc(2), + discop => discopc(2), period => periodc(2), + telescopeop => telescopeopc(2), resetdelay => resetdelayc(2), + incrementdelay => incrementdelayc(2), + sbusy => serbusyc(2), tdcbusy => tdcreadoutbusyc(2), + phaseclksel => phaseclkselc(2) , hitbus => hitbus(2), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + phasebusyEn => phasebusyEnc(2), phasebusySel => phasebusySelc(2), + dispDigitA => dispDigitAA(2), dispDigitB => dispDigitBB(2), + dispDigitC => dispDigitCC(2), dispDigitD => dispDigitDD(2), + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc=>trigAdcc(2), + sendAdcData => sendAdcData, adcData => adcDataChan(2) + ); + adcDataChan(2)(0)<=x"0f0f"; + adcDataChan(2)(1)<=x"0201"; + adcDataChan(2)(2)<=x"0f00"; + adcDataChan(2)(3)<=x"0f0f"; + adcDataChan(2)(11 downto 4)<=adcData(11 downto 4); + -- DUT + U_HsioCosmicCore3: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 0, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 8192, + buffersizetdc => 16384, + fixed160 => '0', + encodingDefault => "00", + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reloadc(3), + mgtRxN => iMgtRxN(3), + mgtRxP => iMgtRxP(3), mgtTxN => oMgtTxN(3), + mgtTxP => oMgtTxP(3), + serialin(0) => serialinb(7), + serialin(15 downto 1) => "000000000000000", + serialout(0) => serialoutb(7), + serialout(15 downto 1) => open, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOutc(3), l1a => l1ac(3), + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmodec(3), startmeas => startmeasc(3), + pausedout => pausedc(3), present => present(3), + trgenabledout => trigenabledc(3), rstFromCore => rstFromCorec(3), + fifothresh => fifothreshc(3), triggermask => triggermaskc(3), + discop => discopc(3), period => periodc(3), + telescopeop => telescopeopc(3), resetdelay => resetdelayc(3), + incrementdelay => incrementdelayc(3), + sbusy => serbusyc(3), tdcbusy => tdcreadoutbusyc(3), + phaseclksel => phaseclkselc(3) , hitbus => hitbus(3), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + phasebusyEn => phasebusyEnc(3), phasebusySel => phasebusySelc(3), + dispDigitA => dispDigitAA(3), dispDigitB => dispDigitBB(3), + dispDigitC => dispDigitCC(3), dispDigitD => dispDigitDD(3), + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => trigAdcc(3), + sendAdcData => sendAdcData, adcData => adcDataChan(3) + ); + adcDataChan(3)(0)<=x"0f0f"; + adcDataChan(3)(1)<=x"0f0f"; + adcDataChan(3)(2)<=x"020f"; + adcDataChan(3)(3)<=x"0100"; + adcDataChan(3)(11 downto 4)<=adcData(11 downto 4); + tempadc_inst: entity work.tempadc + generic map( + PRESCALE_G => 79, + MAPPING_G => (0, 1, 2, 3, 5, 4, 6, 7) ) + port map( + clk => sysClk125, + d_out => adcData, + trig => trigAdc, + ld => sendAdcData, + adcAS => adcAs, + scl => adcI2cScl, + sda => adcI2cSda + ); + HSIOCORES: + for I in 0 to 3 generate + l1ac(I) <= l1a and present(I); + transdissig(I)<='0'; + end generate HSIOCORES; + + dispDigitE<=dispDigitAA(0); + dispDigitF<=dispDigitAA(1); + dispDigitG<=dispDigitAA(2); + dispDigitH<=dispDigitAA(3); + dispDigitA<=dispDigitBB(0); + dispDigitB<=dispDigitBB(1); + dispDigitC<="0000"&dispDigitCC(0)(0)&dispDigitCC(1)(0)&dispDigitCC(2)(0)&dispDigitCC(3)(0); + dispDigitD<=dispDigitDD(3); + + sysClk125i <= not sysClk125; + --sysClk125i<=debug(0); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.fei3 b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.fei3 new file mode 100755 index 0000000000000000000000000000000000000000..d76e8ffaf654841c1c7c7952ee398ded66b1d191 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.fei3 @@ -0,0 +1,770 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic; + oHSIObusy : out std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic; + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + + -- PGP Clock Generator + component PgpClkGen + generic ( + RefClkEn1 : string := "ENABLE"; -- ENABLE or DISABLE + RefClkEn2 : string := "DISABLE"; -- ENABLE or DISABLE + DcmClkSrc : string := "RefClk1"; -- RefClk1 or RefClk2 + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Pad Inputs + pgpRefClkInP : in std_logic; + pgpRefClkInN : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Reference Clock To PGP MGT + -- Use one, See RefClkEn1 & RefClkEn2 Generics + pgpRefClk1 : out std_logic; + pgpRefClk2 : out std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpClk90 : out std_logic; + pgpReset : out std_logic; + + clk320 : out std_logic; + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic; + + pgpClkUnbuf : out std_logic; + pgpClk90Unbuf : out std_logic; + locClkUnbuf : out std_logic + + ); + end component; + + + -- Core Logic + component HsioPixelCore + generic ( + framedFirstChannel : integer := 0; --First framed channel + framedLastChannel : integer := 7; --Last framed channel + rawFirstChannel : integer := 11; --First raw channel + rawLastChannel : integer := 14; --Last raw channel + buffersize : integer := 8192; --FIFO size + bpmDefault : std_logic := '0' --BPM on startup + ); + port ( + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + refClock : in std_logic; + pgpClk : in std_logic; + pgpClk90 : in std_logic; + pgpReset : in std_logic; + + pgpClkUnbuf : in std_logic; + pgpClk90Unbuf: in std_logic; + sysClkUnbuf : in std_logic; + + clk320 : in std_logic; + reload : out std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + discin : in std_logic_vector(3 downto 0); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + resetOut : out std_logic; + debug : out std_logic_vector(7 downto 0); + exttrigger : in std_logic; + extrst : in std_logic; + extbusy : out std_logic; + exttrgclk : out std_logic; + exttriggero : out std_logic; + extrsto : out std_logic; + doricreset : out std_logic; + dispDigitA : out std_logic_vector(7 downto 0); + dispDigitB : out std_logic_vector(7 downto 0); + dispDigitC : out std_logic_vector(7 downto 0); + dispDigitD : out std_logic_vector(7 downto 0); + dispDigitE : out std_logic_vector(7 downto 0); + dispDigitF : out std_logic_vector(7 downto 0); + dispDigitG : out std_logic_vector(7 downto 0); + dispDigitH : out std_logic_vector(7 downto 0); + HSIObusy : out std_logic; + HSIOtrigger : in std_logic + ); + end component; + + component clock160 + port ( + CLKIN_N_IN : in std_logic; + CLKIN_P_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLKIN_IBUFGDS_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; + component clock200 + port( CLKIN_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + component DisplayControl + port ( + sysClk : in std_logic; + sysRst : in std_logic; + dispStrobe : in std_logic; + dispUpdate : in std_logic; + dispRotate : in std_logic_vector(1 downto 0); + dispDigitA : in std_logic_vector(7 downto 0); + dispDigitB : in std_logic_vector(7 downto 0); + dispDigitC : in std_logic_vector(7 downto 0); + dispDigitD : in std_logic_vector(7 downto 0); + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic; + dispRstL : out std_logic + ); + end component; + + + component ODDR port ( + Q : out std_logic; + CE : in std_logic; + C : in std_logic; + D1 : in std_logic; + D2 : in std_logic; + R : in std_logic; + S : in std_logic + ); + end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal resetOut : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiotriggerb : std_logic; + signal serialoutb : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of IBUF : component is TRUE; + attribute syn_noprune of IBUF : component is TRUE; + attribute syn_black_box of OBUF : component is TRUE; + attribute syn_noprune of OBUF : component is TRUE; + attribute syn_black_box of IBUFDS : component is TRUE; + attribute syn_noprune of IBUFDS : component is TRUE; + attribute syn_black_box of OBUFDS : component is TRUE; + attribute syn_noprune of OBUFDS : component is TRUE; + attribute syn_black_box of BUFGMUX : component is TRUE; + attribute syn_noprune of BUFGMUX : component is TRUE; + attribute syn_hier: string; + attribute syn_hier of HsioCosmic: architecture is "hard"; + attribute xc_props : string; + attribute xc_props of HsioCosmic : architecture is "KEEP_HIERARCHY=TRUE"; +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + +-- U_pgpClk : ODDR port map ( +-- Q => opgpClk, +-- CE => '1', +-- C => pgpClk, +-- D1 => '0', +-- D2 => '1', +-- R => '0', +-- S => '0' +-- ); + + + + -- Debug + -- U_Debug0 : OBUF port map ( I => debug(0) , O => oDebug(0) ); + -- U_Debug1 : OBUF port map ( I => debug(1) , O => oDebug(1) ); + -- U_Debug2 : OBUF port map ( I => debug(2) , O => oDebug(2) ); + -- U_Debug3 : OBUF port map ( I => debug(3) , O => oDebug(3) ); + -- U_Debug4 : OBUF port map ( I => debug(4) , O => oDebug(4) ); + -- U_Debug5 : OBUF port map ( I => debug(5) , O => oDebug(5) ); + -- U_Debug6 : OBUF port map ( I => debug(6) , O => oDebug(6) ); + -- U_Debug7 : OBUF port map ( I => debug(7) , O => oDebug(7) ); + + U_transdis : OBUF port map ( I => '0' , O => transDis1 ); + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb , I => iHSIOtrigger ); + + SERIAL_IO_DATA: + for I in 0 to 0 generate + U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); + U_serialout : OBUF port map ( I => serialoutb(I) , O => serialout(I) ); + --U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + -- port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + --U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + -- port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA; + + --U_serialout : OBUF port map ( I => serialoutb(8) , O => serialout(8) ); + --U_serialin_pn_8 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + --port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + -- Display Controller A + U_DispCntrlA: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + + -- FPGA Core + U_HsioCosmicCore: HsioPixelCore + generic map( framedFirstChannel=> 1, + framedLastChannel=> 0, + rawFirstChannel => 0, + rawLastChannel => 0, + buffersize => 16384, + bpmDefault => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb, + serialout => serialoutb, discin => discinb, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut, + debug => debug, exttrigger => exttrigger, + extrst => extrst, extbusy => extbusy, exttrgclk => exttrgclk, + exttriggero => exttriggero, extrsto => extrsto, + doricreset => open, + dispDigitA => dispDigitA, dispDigitB => dispDigitB, + dispDigitC => dispDigitC, dispDigitD => dispDigitD, + dispDigitE => dispDigitE, dispDigitF => dispDigitF, + dispDigitG => dispDigitF, dispDigitH => dispDigitH, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb + ); + sysClk125i <= not sysClk125; + --sysClk125i<=debug(0); + U_clock160: clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.multicore b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.multicore new file mode 100755 index 0000000000000000000000000000000000000000..4cdb8055eb856ede1750ac720d7d641690c47794 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.multicore @@ -0,0 +1,800 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; +use work.StdRtlPkg.all; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic_vector(3 downto 0); + iMgtRxP : in std_logic_vector(3 downto 0); + oMgtTxN : out std_logic_vector(3 downto 0); + oMgtTxP : out std_logic_vector(3 downto 0); + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis : out std_logic_vector(3 downto 0); + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal reloadc : std_logic_vector(3 downto 0); + signal extreload : std_logic; + signal resetOut : std_logic; + signal resetOutc : std_logic_vector(3 downto 0); + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal HITORout : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal serialoutm1 : std_logic_vector(15 downto 0); + signal serialoutm2 : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal serialinm1 : std_logic_vector(15 downto 0); + signal serialinm2 : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmodec : Slv2Array(0 to 3); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabledc : std_logic_vector(3 downto 0); + signal trigenabled : std_logic; + signal pausedc : std_logic_vector(3 downto 0); + signal paused : std_logic; + signal triggermaskc : Slv16Array(0 to 3); + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelayc : std_logic_vector(3 downto 0); + signal resetdelay : std_logic; + signal incrementdelayc: Slv5Array(0 to 3); + signal incrementdelay: std_logic_vector(4 downto 0); + signal discopc : Slv16Array(0 to 3); + signal discop : std_logic_vector(15 downto 0); + signal telescopeopc : Slv3Array(0 to 3); + signal telescopeop : std_logic_vector(2 downto 0); + signal periodc : Slv32Array(0 to 3); + signal period : std_logic_vector(31 downto 0); + signal fifothreshc : std_logic_vector(3 downto 0); + signal fifothresh : std_logic; + signal serbusyc : std_logic_vector(3 downto 0); + signal serbusy : std_logic; + signal tdcreadoutbusyc: std_logic_vector(3 downto 0); + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1ac : std_logic_vector(3 downto 0); + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCorec : std_logic_vector(3 downto 0); + signal rstFromCore : std_logic; + signal hitbus : std_logic_vector(3 downto 0); + signal present : std_logic_vector(3 downto 0); + signal phaseclkselc : std_logic_vector(3 downto 0); + signal phaseclksel : std_logic; + signal startmeasc : std_logic_vector(3 downto 0); + signal startmeas : std_logic; + signal dispDigitAA : Slv8Array(0 to 3); + signal dispDigitBB : Slv8Array(0 to 3); + signal dispDigitCC : Slv8Array(0 to 3); + signal dispDigitDD : Slv8Array(0 to 3); + signal transdissig : std_logic_vector(3 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + constant N_CORES: integer := 4; + constant N_CHANS: integer := 2; + +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + + TRANSDISGEN: + for I in 0 to 3 generate + U_transdis : OBUF port map ( I => transdissig(I) , O => transDis(I) ); + end generate TRANSDISGEN; + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtriggero : OBUF port map ( I => l1a , O => oHSIOtrigger); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + + SERIAL_IO_DATA: + for I in 0 to 7 generate +-- U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA; + + U_serialout : OBUF port map ( I => serialoutb(8) , O => serialout(8) ); + U_serialin_pn_8 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + disc<= hitorb & discinb; + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + paused <= uOr(pausedc); + resetdelay <= uOr(resetdelayc); + incrementdelay <= incrementdelayc(0) or incrementdelayc(1) or incrementdelayc (2) or incrementdelayc(3); + serbusy <= uOr(serbusyc and present); + tdcreadoutbusy<= uOr(tdcreadoutbusyc); + rstFromCore <= uOr(rstFromCorec); + + fifothresh <= uOr(fifothreshc and present); + trigenabled <= uAnd(trigenabledc or not present) and uOr(present); + + reload <= uAnd(reloadc) and extreload; -- active low + resetOut <= uOr(resetOutc); + + process(present, discopc) begin + if(present(0)='1')then discop<=discopc(0); + elsif(present(1)='1')then discop<=discopc(1); + elsif(present(2)='1')then discop<=discopc(2); + else discop<=discopc(3); + end if; + end process; + + process(present, calibmodec) begin + if(present(0)='1')then calibmode<=calibmodec(0); + elsif(present(1)='1')then calibmode<=calibmodec(1); + elsif(present(2)='1')then calibmode<=calibmodec(2); + else calibmode<=calibmodec(3); + end if; + end process; + + process(present, triggermaskc) begin + if(present(0)='1')then triggermask<=triggermaskc(0); + elsif(present(1)='1')then triggermask<=triggermaskc(1); + elsif(present(2)='1')then triggermask<=triggermaskc(2); + else triggermask<=triggermaskc(3); + end if; + end process; + + process(present, periodc) begin + if(present(0)='1')then period<=periodc(0); + elsif(present(1)='1')then period<=periodc(1); + elsif(present(2)='1')then period<=periodc(2); + else period<=periodc(3); + end if; + end process; + + process(present, telescopeopc) begin + if(present(0)='1')then telescopeop<=telescopeopc(0); + elsif(present(1)='1')then telescopeop<=telescopeopc(1); + elsif(present(2)='1')then telescopeop<=telescopeopc(2); + else telescopeop<=telescopeopc(3); + end if; + end process; + + process(present, phaseclkselc) begin + if(present(0)='1')then phaseclksel<=phaseclkselc(0); + elsif(present(1)='1')then phaseclksel<=phaseclkselc(1); + elsif(present(2)='1')then phaseclksel<=phaseclkselc(2); + else phaseclksel<=phaseclkselc(3); + end if; + end process; + + process(present, startmeasc) begin + if(present(0)='1')then startmeas<=startmeasc(0); + elsif(present(1)='1')then startmeas<=startmeasc(1); + elsif(present(2)='1')then startmeas<=startmeasc(2); + else startmeas<=startmeasc(3); + end if; + end process; + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + -- hardware inputs + discin => disc, + hitbusin => hitbus(1 downto 0), + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => open, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + + -- FPGA Core + HSIOCORES: + for I in 0 to N_CORES-1 generate + U_HsioCosmicCorex: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> N_CHANS-1, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersize => 8192, + bpmDefault => '0', + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reloadc(I), + mgtRxN => iMgtRxN(I), + mgtRxP => iMgtRxP(I), mgtTxN => oMgtTxN(I), + mgtTxP => oMgtTxP(I), + serialin(N_CHANS-1 downto 0) => serialinb(N_CHANS*(I+1)-1 downto I*N_CHANS), + serialin(15 downto N_CHANS) => (others => '0'), + serialout(N_CHANS-1 downto 0) => serialoutb(N_CHANS*(I+1)-1 downto I*N_CHANS), + serialout(15 downto N_CHANS) => open, + clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOutc(I), l1a => l1ac(I), + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmodec(I), startmeas => startmeasc(I), + pausedout => pausedc(I), present => present(I), + trgenabledout => trigenabledc(I), rstFromCore => rstFromCorec(I), + fifothresh => fifothreshc(I), triggermask => triggermaskc(I), + discop => discopc(I), period => periodc(I), + telescopeop => telescopeopc(I), resetdelay => resetdelayc(I), + incrementdelay => incrementdelayc(I), + sbusy => serbusyc(I), tdcbusy => tdcreadoutbusyc(I), + phaseclksel => phaseclkselc(I) , hitbus => hitbus(I), + debug => open, + exttriggero => open, extrsto => open, + doricreset => open, + dispDigitA => dispDigitAA(I), dispDigitB => dispDigitBB(I), + dispDigitC => dispDigitCC(I), dispDigitD => dispDigitDD(I), + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf + ); + l1ac(I) <= l1a and present(I); + transdissig(I)<='0'; + end generate HSIOCORES; + FILLVECTORS: + for I in N_CORES to 3 generate + dispDigitAA(I)<=x"00"; + dispDigitBB(I)<=x"00"; + dispDigitCC(I)<=x"00"; + dispDigitDD(I)<=x"00"; + transdissig(I)<='1'; -- disable fiber + present(I)<='0'; + hitbus(I)<='0'; + pausedc(I)<='0'; + resetdelayc(I)<='0'; + incrementdelayc(I)<="00000"; + serbusyc(I)<='0'; + tdcreadoutbusyc(I)<='0'; + rstFromCorec(I)<='0'; + fifothreshc(I)<='0'; + trigenabledc(I)<='0'; + l1ac(I)<='0'; + reloadc(I)<='1'; -- inverted logic + discopc(I)<=(others =>'0'); + calibmodec(I)<=(others =>'0'); + triggermaskc(I)<=(others =>'0'); + periodc(I)<=(others =>'0'); + telescopeopc(I)<=(others =>'0'); + phaseclkselc(I)<='0'; + startmeasc(I)<='0'; + end generate FILLVECTORS; + dispDigitE<=dispDigitAA(0); + dispDigitF<=dispDigitAA(1); + dispDigitG<=dispDigitAA(2); + dispDigitH<=dispDigitAA(3); + dispDigitA<=dispDigitBB(0); + dispDigitB<=dispDigitBB(1); + dispDigitC<=dispDigitBB(2); + dispDigitD<=dispDigitDD(0); + + sysClk125i <= not sysClk125; + --sysClk125i<=debug(0); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.oldCosmic b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.oldCosmic new file mode 100644 index 0000000000000000000000000000000000000000..ca7240084193f42afdba0c7e50d516270aff120f --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.oldCosmic @@ -0,0 +1,668 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic; + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal reload1 : std_logic; + signal extreload : std_logic; + signal resetOut : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmode1 : std_logic_vector(1 downto 0); + signal calibmode2 : std_logic_vector(1 downto 0); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabled : std_logic; + signal paused : std_logic; + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelay : std_logic; + signal incrementdelay: std_logic_vector(4 downto 0); + signal discop : std_logic_vector(15 downto 0); + signal telescopeop : std_logic_vector(2 downto 0); + signal period : std_logic_vector(31 downto 0); + signal fifothresh : std_logic; + signal serbusy : std_logic; + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCore : std_logic; + signal phaseclksel : std_logic; + signal hitbus : std_logic_vector(1 downto 0); + signal startmeas : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + + U_transdis : OBUF port map ( I => '0' , O => transDis1 ); + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + U_HSIOtriggero : OBUF port map ( O => oHSIOtrigger , I => l1a ); + +-- SERIAL_IO_DATA: +-- for I in 0 to 7 generate +-- U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); +-- U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") +-- port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); +-- +-- U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") +-- port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); +-- +-- end generate SERIAL_IO_DATA; + + U_serialout : OBUF port map ( I => serialoutb(0) , O => serialout(0) ); + U_serialin1 : IBUF port map ( I => serialin(0) , O => serialinb(0) ); + U_serialin_pn_0 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + -- hardware inputs + discin => discinb, + hitbusin => hitbus, + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => open, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + + -- FPGA Core + U_HsioCosmicCore1: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 0, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 16384, + buffersizetdc => 4096, + fixed160 => '0', + bpmDefault => '0', + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload1, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb, + serialout => serialoutb, clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut, l1a => l1a, + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode, startmeas => startmeas, + pausedout => paused, present =>open, + trgenabledout => trigenabled, rstFromCore => rstFromCore, + fifothresh => fifothresh, triggermask => triggermask, + discop => discop, period => period, + telescopeop => telescopeop, resetdelay => resetdelay, + incrementdelay => incrementdelay, + sbusy => serbusy, tdcbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, hitbus => hitbus(0), + debug => debug, + exttriggero => exttriggero, extrsto => extrsto, + doricreset => open, + dispDigitA => dispDigitA, dispDigitB => dispDigitB, + dispDigitC => dispDigitC, dispDigitD => dispDigitD, + dispDigitE => dispDigitE, dispDigitF => dispDigitF, + dispDigitG => dispDigitF, dispDigitH => dispDigitH, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf + ); + sysClk125i <= not sysClk125; + reload <= reload1 and extreload; -- active low + --sysClk125i<=debug(0); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.regular b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.regular new file mode 100755 index 0000000000000000000000000000000000000000..9a363fd060613f16f11d1954a152e765f5135ad8 --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/hdl/HsioCosmic.vhd.regular @@ -0,0 +1,697 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +use work.StdRtlPkg.all; +USE work.ALL; + +entity HsioCosmic is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Temperature ADC + adcI2cScl: inout std_logic; + adcI2cSda: inout std_logic; + adcAS: out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttriggerP : in std_logic; + iExttriggerN : in std_logic; + iExtrstP : in std_logic; + iExtrstN : in std_logic; + oExtbusyP : out std_logic; + oExtbusyN : out std_logic; + oExttrgclkP : out std_logic; + oExttrgclkN : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + -- Eudet test + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic; + -- CMOS chip I/O + RD2 : out std_logic; + AuxClk : out std_logic; + RA : out std_logic; + RD1 : out std_logic; + IOMXIN : out std_logic_vector(3 downto 0); + IOMXSEL : out std_logic_vector(2 downto 0); + HITOR : in std_logic; + IOMXOUT : in std_logic_vector(2 downto 0); + SELALTBUS : out std_logic; + REGABDACLD : out std_logic; + REGABSTBLD : out std_logic; + SELCMD : out std_logic; + CMDEXTTRIGGER : out std_logic; + CMDALTPLS : out std_logic + ); +end HsioCosmic; + + +-- Define architecture for top level module +architecture HsioCosmic of HsioCosmic is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioCosmic : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioCosmic : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioCosmic : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal reload : std_logic; + signal reload1 : std_logic; + signal extreload : std_logic; + signal resetOut : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal RD2b : std_logic; + signal AuxClkb : std_logic; + signal RAb : std_logic; + signal RD1b : std_logic; + signal IOMXINb : std_logic_vector(3 downto 0); + signal IOMXSELb : std_logic_vector(2 downto 0); + signal HITORb : std_logic; + signal IOMXOUTb : std_logic_vector(2 downto 0); + signal SELALTBUSb : std_logic; + signal REGABDACLDb : std_logic; + signal REGABSTBLDb : std_logic; + signal SELCMDb : std_logic; + signal CMDEXTTRIGGERb : std_logic; + signal CMDALTPLSb : std_logic; + signal exttrigger : std_logic; + signal exttriggerinv : std_logic; + signal extrst : std_logic; + signal extrstinv : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal extbusyinv : std_logic; + signal exttrgclk : std_logic; + signal exttrgclkinv : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal serialoutb : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol : std_logic_vector(35 downto 0); + signal cdata : std_logic_vector(31 downto 0); + signal ctrig : std_logic_vector(0 downto 0); + signal opgpClk : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal holdctr : std_logic_vector(24 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmode1 : std_logic_vector(1 downto 0); + signal calibmode2 : std_logic_vector(1 downto 0); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabled : std_logic; + signal paused : std_logic; + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelay : std_logic; + signal incrementdelay: std_logic_vector(4 downto 0); + signal discop : std_logic_vector(15 downto 0); + signal telescopeop : std_logic_vector(2 downto 0); + signal period : std_logic_vector(31 downto 0); + signal fifothresh : std_logic; + signal serbusy : std_logic; + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCore : std_logic; + signal phaseclksel : std_logic; + signal hitbus : std_logic_vector(1 downto 0); + signal startmeas : std_logic; + signal phasebusySel : std_logic_vector(1 downto 0); + signal phasebusyEn : std_logic; + + signal trigAdc : sl; + signal sendAdcData : sl; + signal adcData : Slv16Array(11 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + + U_transdis : OBUF port map ( I => '0' , O => transDis1 ); + + U_rd2 : OBUF port map ( I => RD2b , O => RD2); + U_auxclk : OBUF port map ( I => AuxClkb , O => AuxClk); + U_RA : OBUF port map ( I => RAb , O => RA ); + U_rd1 : OBUF port map ( I => RD1b , O => RD1 ); + U_IOMXIN3 : OBUF port map ( I => IOMXINb(3) , O => IOMXIN(3) ); + U_IOMXIN2 : OBUF port map ( I => IOMXINb(2) , O => IOMXIN(2) ); + U_IOMXIN1 : OBUF port map ( I => IOMXINb(1) , O => IOMXIN(1) ); + U_IOMXIN0 : OBUF port map ( I => IOMXINb(0) , O => IOMXIN(0) ); + U_IOMXSEL2 : OBUF port map ( I => IOMXSELb(2) , O => IOMXSEL(2) ); + U_IOMXSEL1 : OBUF port map ( I => IOMXSELb(1) , O => IOMXSEL(1) ); + U_IOMXSEL0 : OBUF port map ( I => IOMXSELb(0) , O => IOMXSEL(0) ); + U_HITOR : IBUF port map ( O => HITORb , I => HITOR); + U_IOMXOUT2 : IBUF port map ( O => IOMXOUTb(2) , I => IOMXOUT(2) ); + U_IOMXOUT1 : IBUF port map ( O => IOMXOUTb(1) , I => IOMXOUT(1) ); + U_IOMXOUT0 : IBUF port map ( O => IOMXOUTb(0) , I => IOMXOUT(0) ); + U_SELALTBUS : OBUF port map ( I => SELALTBUSb , O => SELALTBUS); + U_REGABDACLD : OBUF port map ( I => REGABDACLDb , O => REGABDACLD); + U_REGABSTBLD : OBUF port map ( I => REGABSTBLDb , O => REGABSTBLD); + U_SELCMD : OBUF port map ( I => SELCMDb , O => SELCMD ); + U_CMDEXTTRIGGER : OBUF port map ( I => CMDEXTTRIGGERb , O => CMDEXTTRIGGER ); + U_CMDALTPLS : OBUF port map ( I => CMDALTPLSb , O => CMDALTPLS ); + U_exttrgclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttrgclkinv , O => oExttrgclkP , OB => oExttrgclkN ); + exttrgclkinv<= not exttrgclk; + U_extbusy : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extbusyinv , O => oExtBusyP , OB => oExtbusyN ); + extbusyinv<= not extbusy; + U_exttrigger : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExttriggerP , IB=>iExttriggerN , O => exttriggerinv ); + exttrigger<= not exttriggerinv; + U_extrst : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => iExtrstP , IB=>iExtrstN , O => extrstinv ); + extrst<= not extrstinv; + U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + U_HSIOtriggero : OBUF port map ( O => oHSIOtrigger , I => l1a ); + + SERIAL_IO_DATA: + for I in 0 to 7 generate +-- U_serialin : IBUF port map ( I => serialin(I) , O => serialinb(I) ); + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA; + + U_serialout : OBUF port map ( I => serialoutb(8) , O => serialout(8) ); + U_serialin_pn_8 : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(8) , IB=>serialin_n(8) , O => serialinb(8) ); + +-- U_serialout11 : OBUF port map ( I => serialoutb(11) , O => serialout(11) ); +-- U_serialin11 : IBUF port map ( I => serialin(11) , O => serialinb(11) ); + SERIAL_IO_DATA_FEI3: + for I in 11 to 14 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + + end generate SERIAL_IO_DATA_FEI3; + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + clk160 => pgpClk, + rst160 => pgpReset, + -- hardware inputs + discin => discinb, + hitbusin => hitbus, + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => open, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + phasebusyEn => phasebusyEn, + phasebusySel => phasebusySel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + + -- FPGA Core + U_HsioCosmicCore1: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 7, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 8192, + buffersizetdc => 16384, + encodingDefault => "00", + hitbusreadout => '0') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload1, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb, + serialout => serialoutb, clock160 => pgpClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut, l1a => l1a, + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2 => tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode, startmeas => startmeas, + pausedout => paused, present =>open, + trgenabledout => trigenabled, rstFromCore => rstFromCore, + fifothresh => fifothresh, triggermask => triggermask, + discop => discop, period => period, + telescopeop => telescopeop, resetdelay => resetdelay, + incrementdelay => incrementdelay, + sbusy => serbusy, tdcbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, hitbus => hitbus(0), + debug => debug, + exttriggero => exttriggero, extrsto => extrsto, + doricreset => open, + phasebusyEn => phasebusyEn, phasebusySel => phasebusySel, + dispDigitA => dispDigitA, dispDigitB => dispDigitB, + dispDigitC => dispDigitC, dispDigitD => dispDigitD, + dispDigitE => dispDigitE, dispDigitF => dispDigitF, + dispDigitG => dispDigitF, dispDigitH => dispDigitH, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => trigAdc, + sendAdcData => sendAdcData, adcData => adcData + ); + sysClk125i <= not sysClk125; + reload <= reload1 and extreload; -- active low + --sysClk125i<=debug(0); + tempadc_inst: entity work.tempadc + generic map( + PRESCALE_G => 79, + MAPPING_G => (7, 6, 4, 5, 3, 2, 1, 0) ) + port map( + clk => sysClk125, + d_out => adcData, + trig => trigAdc, + ld => sendAdcData, + adcAS => adcAs, + scl => adcI2cScl, + sda => adcI2cSda + ); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end HsioCosmic; diff --git a/rce/fw-hsio/projects/HsioCosmic/images/.gitignore b/rce/fw-hsio/projects/HsioCosmic/images/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d6b7ef32c8478a48c3994dcadc86837f4371184d --- /dev/null +++ b/rce/fw-hsio/projects/HsioCosmic/images/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/rce/fw-hsio/projects/HsioStave0/Makefile b/rce/fw-hsio/projects/HsioStave0/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5c82cd853d84dbb484b348c2b7f4fdef5592551e --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/Makefile @@ -0,0 +1,12 @@ +# Project Name +export PROJECT = $(notdir $(PWD)) + +# List of build core directories. Relative to current directory. +CORE_DIRS = coregen ../../modules/pgp/coregen ../../modules/pgp2/coregen ../../modules/pixelcore/coregen + +# Optional ELF file to include. Relative to ./boot directory +#BOOT_ELF = udiTest.elf + +# Use top level makefile +include ../../system.mk + diff --git a/rce/fw-hsio/projects/HsioStave0/Readme.txt b/rce/fw-hsio/projects/HsioStave0/Readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0ba752b3e18a22530900255b57e6e1df48afd87 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/Readme.txt @@ -0,0 +1,59 @@ +This is a DPM project specific Readme.txt file. + +The files in this directory are used to build +the DPM project in this directory. The project +name matches the name of the directory in which +this file is found. + +The Makefile in this directory may be used to build +this project with a simple 'gmake' command. + +The Version.vhd file in this directory is used to +generate the software readable version constant +in the build and is also used to set the name of +the files added to the images directory. + +The following sub directories exist in this project: + +boot: + This directory contains boot loader files which are + used to program the boot loader code in the DPM. The + files in this directory include: + +config: + This directory contains Xilinx configuration files for + various steps in the synthesis process. The files in this + directory include: + + bitgen_options.txt: Options for bitgen + map_options.txt: Options for map + ngdbuild_options.txt: Options for ngdbuild + par_options.txt: Options for par + trce_options.txt: Options for trce + xst_options.txt: Options for xst + sources.txt Source file list used by xst + +coregen: + This directory holds the coregen project and any modules + generated by coregen that are specific to this project. + +debug: + This directory holds any debug files for the project. + +hdl: + This directory contains the source files (.vhd and .v) for + the project and the constraints file (.ucf) for the project. + The top level module name, its source file name and the ucf + file name should match the name of the project. + +images: + + This directory contains the result of the project compile. + The resulting .mcs and .bit files for the project are + added to this directory. The name of the copied file will + be: project_version.mcs/.bit. + +sim: + + Directory for simulation Makefile and test bench. + diff --git a/rce/fw-hsio/projects/HsioStave0/Version.vhd b/rce/fw-hsio/projects/HsioStave0/Version.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ce6867c7924b34069ed1434149099bdf93c9310d --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/Version.vhd @@ -0,0 +1,32 @@ +------------------------------------------------------------------------------- +-- Title : Version Constant File +-- Project : HSIO +------------------------------------------------------------------------------- +-- File : Version.vhd +-- Author : Martin Kocian, kocian@slac.stanford.edu +-- Created : 01/07/2013 +------------------------------------------------------------------------------- +-- Description: +-- Version Constant Module +------------------------------------------------------------------------------- +-- Copyright (c) 2012 by SLAC. All rights reserved. +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Version is + +constant FpgaVersion : std_logic_vector(31 downto 0) := x"00000009"; -- MAKE_VERSION + +end Version; + +------------------------------------------------------------------------------- +-- Revision History: +-- 01/07/2013 (0x00000001): Initial XST version +-- 03/22/2013 (0x00000002): HSIO trigger/busy added to opto ucf file +-- 04/02/2013 (0x00000003): Memory buffer for triggering. +-- 06/20/2014 (0x00000004): Added hitbus readout for DBM +-- 07/24/2014 (0x00000005): Separated trigger from core. +-- 01/26/2015 (0x00000008): New fei4 readout +-- 01/09/2015 (0x00000009): New ADC data format, max 31 readout links. +------------------------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/HsioStave0/config/bitgen_options.txt b/rce/fw-hsio/projects/HsioStave0/config/bitgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..abf29c69b7888da03e96c154d93bc2f56add8ccd --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/bitgen_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx bitgen options file +##----------------------------------------------------------------------------- +-intstyle silent +-w diff --git a/rce/fw-hsio/projects/HsioStave0/config/map_options.txt b/rce/fw-hsio/projects/HsioStave0/config/map_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..6cef41ff642fa23ed75c9e6516aa65c1c9c961af --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/map_options.txt @@ -0,0 +1,21 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx map options file +##----------------------------------------------------------------------------- + +#-intstyle silent +-ol high +-xe n +-t 1 +-register_duplication on +#-global_opt off +#-equivalent_register_removal on +#-u +#-cm Area +-detail +#-ir off +#-pr off +#-lc off +#-mt 2 + + + diff --git a/rce/fw-hsio/projects/HsioStave0/config/ngdbuild_options.txt b/rce/fw-hsio/projects/HsioStave0/config/ngdbuild_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..95ca0eea7e533ba749eb765d1e8cdd2068359eab --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/ngdbuild_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx ngdbuild options file +##----------------------------------------------------------------------------- +-nt timestamp + diff --git a/rce/fw-hsio/projects/HsioStave0/config/par_options.txt b/rce/fw-hsio/projects/HsioStave0/config/par_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2cdd3ad019144a5e3f99c255af2010411238e4ea --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/par_options.txt @@ -0,0 +1,9 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx place and route options file +##----------------------------------------------------------------------------- +#-intstyle ise +-ol high +-xe n +#-mt 4 + + diff --git a/rce/fw-hsio/projects/HsioStave0/config/promgen_options.txt b/rce/fw-hsio/projects/HsioStave0/config/promgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2c2257bee87830d2f7251e8db6d2b735977d3c56 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/promgen_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx promgen options file +##----------------------------------------------------------------------------- +-x xcf32p +-w +-p mcs +-c FF diff --git a/rce/fw-hsio/projects/HsioStave0/config/sources.txt b/rce/fw-hsio/projects/HsioStave0/config/sources.txt new file mode 120000 index 0000000000000000000000000000000000000000..c5dbc41ed1d3295e665824034473824a6b7da105 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/sources.txt @@ -0,0 +1 @@ +sources_pgp1.txt \ No newline at end of file diff --git a/rce/fw-hsio/projects/HsioStave0/config/sources_pgp1.txt b/rce/fw-hsio/projects/HsioStave0/config/sources_pgp1.txt new file mode 100644 index 0000000000000000000000000000000000000000..40eabc71a7246105987dc3df5bad01ebc0244989 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/sources_pgp1.txt @@ -0,0 +1,73 @@ +# Version Constant +vhdl work "_PROJ_DIR_/Version.vhd" + +# PGP + +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpVersion.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpAckRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellTx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpMgtWrap.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRxTrack.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTxSched.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTop.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpClkGen.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCmdSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRegSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPicRemBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDataBuffer.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpFrontEnd.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDsBuff.vhd" + +# Pixel core +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/StdRtlPkg.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/adcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/arraytype.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayCharacters.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayControl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser32.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/OutputEncoder.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock160.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock200.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/phaseshift.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflag.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagnew.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eofcounter.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/multiplexdataopt.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/coincidence.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerpipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/hitbuspipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/wordswapper.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eudaqTrigger.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/syncdatac.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealign.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealignhitbus.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser10b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser4b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp24bit.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/lookaheadfifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/decodefei4record.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/datafifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerlogic.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/HsioPixelCore.vhd" + +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_wrapper.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_bram.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_disp.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut_base.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_pkg.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_rtl.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_top.vhd" + + +# Local Files +vhdl work "_PROJ_DIR_/hdl/HsioStave0.vhd" + diff --git a/rce/fw-hsio/projects/HsioStave0/config/sources_pgp2.txt b/rce/fw-hsio/projects/HsioStave0/config/sources_pgp2.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7ff5dd10ed874a6d1d43144ab692450d5fac061 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/sources_pgp2.txt @@ -0,0 +1,67 @@ +# Version Constant +vhdl work "_PROJ_DIR_/Version.vhd" + +# PGP2 + +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2CorePackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2Rx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2RxCell.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2RxPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2Tx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxCell.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/core/Pgp2TxSched.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtPackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2Mgt16.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/PgpClkGen.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtRxRst.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/mgt/Pgp2MgtTxRst.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2AppPackage.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2CmdSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2DsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2RegSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/Pgp2UsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/PgpDsBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp2/hdl/applications/PgpFrontEnd.vhd" + + +# Pixel core +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/arraytype.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayCharacters.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayControl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/ser32.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/BiphaseMarkEncoder.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdc.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/tdcreadout.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock160.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock200.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/phaseshift.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflag.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/dataflagnew.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eofcounter.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/multiplexdatapgp2.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/coincidence.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/triggerpipeline.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/wordswapper.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/eudaqTrigger.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/syncdatac.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/framealign.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/deser10b.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/encodepgp.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/datafifo.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/HsioPixelCore.vhd" + +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_wrapper.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_bram.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_disp.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_lut_base.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_pkg.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_rtl.vhd" +vhdl decode_8b10b "_PROJ_DIR_/../../modules/pixelcore/hdl/decode_8b10b_top.vhd" + + +# Local Files +vhdl work "_PROJ_DIR_/hdl/HsioStave0.vhd" + diff --git a/rce/fw-hsio/projects/HsioStave0/config/trce_options.txt b/rce/fw-hsio/projects/HsioStave0/config/trce_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2656ff46d3ef8bf070390954affed019ee28ca82 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/trce_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx trace options file +##----------------------------------------------------------------------------- +-intstyle silent +-l 30 +-v 30 +-tsi DpmTest.tsi diff --git a/rce/fw-hsio/projects/HsioStave0/config/xst_options.txt b/rce/fw-hsio/projects/HsioStave0/config/xst_options.txt new file mode 100644 index 0000000000000000000000000000000000000000..268629be97abb1787ab138ed6c6ab74a71f4aecc --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/config/xst_options.txt @@ -0,0 +1,50 @@ +run +-ofn HsioStave0 +-top HsioStave0 +-p XC4VFX60-11-FF1152 +-ifn "sources.txt" +-opt_mode Speed +-opt_level 2 +-power NO +-iuc NO +-keep_hierarchy No +-netlist_hierarchy As_Optimized +-rtlview Yes +-glob_opt AllClockNets +-write_timing_constraints No +-cross_clock_analysis NO +-hierarchy_separator / +-bus_delimiter <> +-case Maintain +-slice_utilization_ratio 100 +-bram_utilization_ratio 100 +-dsp_utilization_ratio 100 +-verilog2001 YES +-fsm_extract YES -fsm_encoding Auto +-safe_implementation No +-fsm_style LUT +-ram_extract Yes +-ram_style Auto +-rom_extract Yes +-mux_style Auto +-decoder_extract YES +-priority_extract Yes +-shreg_extract YES +-shift_extract YES +-xor_collapse YES +-resource_sharing Yes +-use_dsp48 Auto +-async_to_sync No +-iobuf Yes +-max_fanout 100000 +-bufg 32 +-register_duplication YES +-equivalent_register_removal Yes +-register_balancing No +-iob Auto +-slice_packing YES +-use_clock_enable Auto +-use_sync_set Auto +-use_sync_reset Auto +-optimize_primitives No + diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf new file mode 120000 index 0000000000000000000000000000000000000000..461f59811fa4fa54aa3e473406b71728be063130 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf @@ -0,0 +1 @@ +HsioStave0.ucf.rotated \ No newline at end of file diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.dbm_nonrotated b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.dbm_nonrotated new file mode 100644 index 0000000000000000000000000000000000000000..ace28b7284b6fbeb11957e3cfa3cafd474012da7 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.dbm_nonrotated @@ -0,0 +1,333 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioStave0.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +#NET clk320 TNM_NET = FFS clk320; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET mainClk TNM_NET = FFS mainClk; +INST "U_HsioStave0Core1/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; +INST "U_HsioStave0Core2/thetdc/stopcontrol" RLOC_ORIGIN="X44Y89"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 TS_pgpClk / 2; +TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioStave0Core*/channelmask(*) TIG; +NET U_HsioStave0Core*/dfifothresh(*) TIG; +#NET U_HsioStave0Core*/enablereadout(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialin(*) maxskew = 250 ps ; + +INST "U_HsioStave0Core*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +NET "iMgtRxN2" LOC = "AA1"; +NET "iMgtRxP2" LOC = "Y1"; +NET "oMgtTxN2" LOC = "V1"; +NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis2" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +#NET "oDebug(7)" LOC = "N9"; +#NET "oDebug(7)" IOSTANDARD="LVDS_25"; +#NET "oDebug(6)" LOC = "N10"; +#NET "oDebug(6)" IOSTANDARD="LVDS_25"; +#NET "oDebug(4)" LOC = "N8"; +#NET "oDebug(4)" IOSTANDARD="LVDS_25"; +#NET "oDebug(5)" LOC = "N7"; +#NET "oDebug(5)" IOSTANDARD="LVDS_25"; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "iHSIOtrigger" LOC="J14"; +NET "iHSIOtrigger" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger" SLEW=FAST; + +NET "oHSIObusy" LOC="H19"; +NET "oHSIObusy" IOSTANDARD="LVTTL"; +NET "oHSIObusy" SLEW=FAST; + +NET "oExttriggerP" LOC="L15"; +NET "oExttriggerP" IOSTANDARD="LVCMOS33"; +NET "oExttriggerP" SLEW=FAST; + +NET "doricreset1" LOC = "AJ11"; +NET "doricreset1" IOSTANDARD="LVCMOS25"; +NET "doricreset2" LOC = "AK11"; +NET "doricreset2" IOSTANDARD="LVCMOS25"; + +NET "iExtrst" LOC = "K18"; +NET "iExtrst" IOSTANDARD="LVCMOS33"; +NET "iExtrst" SLEW=FAST; +NET "iExttrigger" LOC = "K19"; +NET "iExttrigger" IOSTANDARD="LVCMOS33"; +NET "iExttrigger" SLEW=FAST; +NET "oExttrgclk" LOC = "K16"; +NET "oExttrgclk" IOSTANDARD="LVCMOS33"; +NET "oExttrgclk" SLEW=FAST; +NET "oExtBusy" LOC = "J16"; +NET "oExtBusy" IOSTANDARD="LVCMOS33"; +NET "oExtBusy" SLEW=FAST; + + +NET "serialout_p(0)" LOC = "AM13"; +NET "serialout_n(0)" LOC = "AM12"; +NET "serialout_p(1)" LOC = "AM8"; +NET "serialout_n(1)" LOC = "AM7"; +NET "serialout_p(2)" LOC = "AK14"; +NET "serialout_n(2)" LOC = "AL14"; +NET "serialout_p(3)" LOC = "AK13"; +NET "serialout_n(3)" LOC = "AL13"; +NET "serialout_p(4)" LOC = "AL11"; +NET "serialout_n(4)" LOC = "AM11"; +NET "serialout_p(5)" LOC = "AL9"; +NET "serialout_n(5)" LOC = "AK9"; +NET "serialout_p(6)" LOC = "AL10"; +NET "serialout_n(6)" LOC = "AM10"; +NET "serialout_p(7)" LOC = "AF9"; +NET "serialout_n(7)" LOC = "AE9"; + +NET "serialout_p(8)" LOC = "AK7"; +NET "serialout_n(8)" LOC = "AJ7"; +NET "serialout_p(9)" LOC = "AJ9"; +NET "serialout_n(9)" LOC = "AH9"; +NET "serialout_p(10)" LOC = "AF11"; +NET "serialout_n(10)" LOC = "AG11"; +NET "serialout_p(11)" LOC = "AH8"; +NET "serialout_n(11)" LOC = "AH7"; +NET "serialout_p(12)" LOC = "AJ12"; +NET "serialout_n(12)" LOC = "AK12"; +NET "serialout_p(13)" LOC = "AH10"; +NET "serialout_n(13)" LOC = "AJ10"; +NET "serialout_p(14)" LOC = "AH14"; +NET "serialout_n(14)" LOC = "AJ14"; +NET "serialout_p(15)" LOC = "AF10"; +NET "serialout_n(15)" LOC = "AG10"; + + +NET "serialin_p(8)" LOC = "AC12"; +NET "serialin_n(8)" LOC = "AB12"; +NET "serialin_p(9)" LOC = "AG13"; +NET "serialin_n(9)" LOC = "AH13"; +NET "serialin_p(10)" LOC = "AD11"; +NET "serialin_n(10)" LOC = "AE11"; +NET "serialin_p(11)" LOC = "AD10"; +NET "serialin_n(11)" LOC = "AD9"; +NET "serialin_p(12)" LOC = "AE14"; +NET "serialin_n(12)" LOC = "AF14"; +NET "serialin_p(13)" LOC = "AB11"; +NET "serialin_n(13)" LOC = "AA11"; +NET "serialin_p(14)" LOC = "AD14"; +NET "serialin_n(14)" LOC = "AC13"; +NET "serialin_p(15)" LOC = "AB13"; +NET "serialin_n(15)" LOC = "AA13"; + +NET "serialin_p(1)" LOC = "AH15"; +NET "serialin_n(1)" LOC = "AJ15"; +NET "serialin_p(6)" LOC = "AF15"; +NET "serialin_n(6)" LOC = "AG15"; +NET "serialin_p(4)" LOC = "AE13"; +NET "serialin_n(4)" LOC = "AF13"; +NET "serialin_p(7)" LOC = "AJ16"; +NET "serialin_n(7)" LOC = "AK16"; +NET "serialin_p(0)" LOC = "H24"; +NET "serialin_n(0)" LOC = "J24"; +NET "serialin_p(2)" LOC = "G22"; +NET "serialin_n(2)" LOC = "H22"; +NET "serialin_p(3)" LOC = "E24"; +NET "serialin_n(3)" LOC = "F24"; +NET "serialin_p(5)" LOC = "J25"; +NET "serialin_n(5)" LOC = "H25"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.full b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.full new file mode 100644 index 0000000000000000000000000000000000000000..7f2224330bff825f727525c150bdc5169992542e --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.full @@ -0,0 +1,348 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioStave0.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +#NET clk320 TNM_NET = FFS clk320; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET mainClk TNM_NET = FFS mainClk; + +INST "U_triggerlogic/thetdc/CHAIN[*].TAP" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/CHAIN[*].DELAYY" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/startcontrol" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/stopcontrol" U_SET="TDC1"; +#INST "U_HsioStave0Core2/thetdc/CHAIN[*].TAP" U_SET="TDC2"; +#INST "U_HsioStave0Core2/thetdc/CHAIN[*].DELAYY" U_SET="TDC2"; +#INST "U_HsioStave0Core2/thetdc/startcontrol" U_SET="TDC2"; +#INST "U_HsioStave0Core2/thetdc/stopcontrol" U_SET="TDC2"; + +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; +#INST "U_HsioStave0Core2/thetdc/stopcontrol" RLOC_ORIGIN="X44Y89"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 TS_pgpClk / 2; +TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioStave0Core*/channelmask(*) TIG; +NET U_HsioStave0Core*/dfifothresh(*) TIG; +#NET U_HsioStave0Core*/enablereadout(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(*) maxskew = 250 ps ; + +INST "U_HsioStave0Core*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +NET "iMgtRxN2" LOC = "AA1"; +NET "iMgtRxP2" LOC = "Y1"; +NET "oMgtTxN2" LOC = "V1"; +NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis2" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "L15"; +NET "iExtreload" IOSTANDARD="LVCMOS33"; +NET "iExtreload" PULLUP; + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +#NET "oDebug(7)" LOC = "N9"; +#NET "oDebug(7)" IOSTANDARD="LVDS_25"; +#NET "oDebug(6)" LOC = "N10"; +#NET "oDebug(6)" IOSTANDARD="LVDS_25"; +#NET "oDebug(4)" LOC = "N8"; +#NET "oDebug(4)" IOSTANDARD="LVDS_25"; +#NET "oDebug(5)" LOC = "N7"; +#NET "oDebug(5)" IOSTANDARD="LVDS_25"; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + + +NET "oHSIObusy" LOC="H19"; +NET "oHSIObusy" IOSTANDARD="LVTTL"; +NET "oHSIObusy" SLEW=FAST; + + +NET "doricreset1" LOC = "AJ11"; +NET "doricreset1" IOSTANDARD="LVCMOS25"; +NET "doricreset2" LOC = "AK11"; +NET "doricreset2" IOSTANDARD="LVCMOS25"; + +NET "iExtrst" LOC = "K18"; +NET "iExtrst" IOSTANDARD="LVCMOS33"; +NET "iExtrst" SLEW=FAST; +NET "iExttrigger" LOC = "K19"; +NET "iExttrigger" IOSTANDARD="LVCMOS33"; +NET "iExttrigger" SLEW=FAST; +NET "oExttrgclk" LOC = "K16"; +NET "oExttrgclk" IOSTANDARD="LVCMOS33"; +NET "oExttrgclk" SLEW=FAST; +NET "oExtBusy" LOC = "J16"; +NET "oExtBusy" IOSTANDARD="LVCMOS33"; +NET "oExtBusy" SLEW=FAST; + +NET "serialout_p(0)" LOC = "AM13"; +NET "serialout_n(0)" LOC = "AM12"; +NET "serialout_p(1)" LOC = "AM8"; +NET "serialout_n(1)" LOC = "AM7"; +NET "serialout_p(2)" LOC = "AK14"; +NET "serialout_n(2)" LOC = "AL14"; +NET "serialout_p(3)" LOC = "AK13"; +NET "serialout_n(3)" LOC = "AL13"; +NET "serialout_p(4)" LOC = "AL11"; +NET "serialout_n(4)" LOC = "AM11"; +NET "serialout_p(5)" LOC = "AL9"; +NET "serialout_n(5)" LOC = "AK9"; +NET "serialout_p(6)" LOC = "AL10"; +NET "serialout_n(6)" LOC = "AM10"; +NET "serialout_p(7)" LOC = "AF9"; +NET "serialout_n(7)" LOC = "AE9"; + +NET "serialout_p(8)" LOC = "AK7"; +NET "serialout_n(8)" LOC = "AJ7"; +NET "serialout_p(9)" LOC = "AJ9"; +NET "serialout_n(9)" LOC = "AH9"; +NET "serialout_p(10)" LOC = "AF11"; +NET "serialout_n(10)" LOC = "AG11"; +NET "serialout_p(11)" LOC = "AH8"; +NET "serialout_n(11)" LOC = "AH7"; +NET "serialout_p(12)" LOC = "AJ12"; +NET "serialout_n(12)" LOC = "AK12"; +NET "serialout_p(13)" LOC = "AH10"; +NET "serialout_n(13)" LOC = "AJ10"; +NET "serialout_p(14)" LOC = "AH14"; +NET "serialout_n(14)" LOC = "AJ14"; +NET "serialout_p(15)" LOC = "AF10"; +NET "serialout_n(15)" LOC = "AG10"; + + +NET "serialin_p(0)" LOC = "AC12"; +NET "serialin_n(0)" LOC = "AB12"; +NET "serialin_p(1)" LOC = "AG13"; +NET "serialin_n(1)" LOC = "AH13"; +NET "serialin_p(2)" LOC = "AD11"; +NET "serialin_n(2)" LOC = "AE11"; +NET "serialin_p(3)" LOC = "AD10"; +NET "serialin_n(3)" LOC = "AD9"; +NET "serialin_p(4)" LOC = "AE14"; +NET "serialin_n(4)" LOC = "AF14"; +NET "serialin_p(5)" LOC = "AB11"; +NET "serialin_n(5)" LOC = "AA11"; +NET "serialin_p(6)" LOC = "AD14"; +NET "serialin_n(6)" LOC = "AC13"; +NET "serialin_p(7)" LOC = "AB13"; +NET "serialin_n(7)" LOC = "AA13"; + +NET "serialin_p(8)" LOC = "AH15"; +NET "serialin_n(8)" LOC = "AJ15"; +NET "serialin_p(9)" LOC = "AF15"; +NET "serialin_n(9)" LOC = "AG15"; +NET "serialin_p(10)" LOC = "AE13"; +NET "serialin_n(10)" LOC = "AF13"; +NET "serialin_p(11)" LOC = "AJ16"; +NET "serialin_n(11)" LOC = "AK16"; +NET "serialin_p(12)" LOC = "H24"; +NET "serialin_n(12)" LOC = "J24"; +NET "serialin_p(13)" LOC = "G22"; +NET "serialin_n(13)" LOC = "H22"; +NET "serialin_p(14)" LOC = "E24"; +NET "serialin_n(14)" LOC = "F24"; +NET "serialin_p(15)" LOC = "J25"; +NET "serialin_n(15)" LOC = "H25"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.ibl b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.ibl new file mode 100644 index 0000000000000000000000000000000000000000..beda4562944ceb7282e698f894906290d8e388ed --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.ibl @@ -0,0 +1,396 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioStave0.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +#NET clk320 TNM_NET = FFS clk320; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET mainClk TNM_NET = FFS mainClk; +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; +#INST "U_HsioStave0Core2/thetdc/stopcontrol" RLOC_ORIGIN="X44Y89"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 TS_pgpClk / 2; +TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioStave0Core*/channelmask(*) TIG; +NET U_HsioStave0Core*/dfifothresh(*) TIG; +#NET U_HsioStave0Core*/enablereadout(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(*) maxskew = 250 ps ; + +INST "U_HsioStave0Core*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +NET "iMgtRxN2" LOC = "AA1"; +NET "iMgtRxP2" LOC = "Y1"; +NET "oMgtTxN2" LOC = "V1"; +NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis2" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + +NET "iExtreload" LOC = "L15"; +NET "iExtreload" IOSTANDARD="LVCMOS33"; +NET "iExtreload" PULLUP; + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "oDebug(0)" LOC = "N10"; +NET "oDebug(1)" LOC = "N9"; +NET "oDebug(2)" LOC = "N8"; +NET "oDebug(3)" LOC = "N7"; +NET "oDebug(4)" LOC = "U8"; +NET "oDebug(5)" LOC = "T8"; +NET "oDebug(6)" LOC = "L6"; +NET "oDebug(7)" LOC = "L5"; +NET "oDebug(0)" IOSTANDARD="LVCMOS25"; +NET "oDebug(1)" IOSTANDARD="LVCMOS25"; +NET "oDebug(2)" IOSTANDARD="LVCMOS25"; +NET "oDebug(3)" IOSTANDARD="LVCMOS25"; +NET "oDebug(4)" IOSTANDARD="LVCMOS25"; +NET "oDebug(5)" IOSTANDARD="LVCMOS25"; +NET "oDebug(6)" IOSTANDARD="LVCMOS25"; +NET "oDebug(7)" IOSTANDARD="LVCMOS25"; +NET "oDebug(0)" SLEW="FAST"; +NET "oDebug(1)" SLEW="FAST"; +NET "oDebug(2)" SLEW="FAST"; +NET "oDebug(3)" SLEW="FAST"; +NET "oDebug(4)" SLEW="FAST"; +NET "oDebug(5)" SLEW="FAST"; +NET "oDebug(6)" SLEW="FAST"; +NET "oDebug(7)" SLEW="FAST"; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +NET "oHSIOtrigger" LOC="L15"; +NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +NET "oHSIOtrigger" SLEW=FAST; + +NET "iHSIObusy" LOC="H19"; +NET "iHSIObusy" IOSTANDARD="LVTTL"; +NET "iHSIObusy" SLEW=FAST; +NET "iHSIObusy" PULLDOWN; + +NET "iExtreload" LOC = "G15"; +NET "iExtreload" IOSTANDARD="LVCMOS25"; +NET "iExtreload" PULLUP; + + +NET "doricreset1" LOC = "AJ11"; +NET "doricreset1" IOSTANDARD="LVCMOS25"; +NET "doricreset2" LOC = "AK11"; +NET "doricreset2" IOSTANDARD="LVCMOS25"; + +#NET "oExtrstP" LOC = "N10"; +#NET "oExtrstN" LOC = "N9"; +#NET "oExtrstP" IOSTANDARD="LVDS_25"; +#NET "oExtrstN" IOSTANDARD="LVDS_25"; + +#NET "unused_p(0)" LOC="AM13"; +#NET "unused_n(0)" LOC="AM12"; +#NET "unused_p(1)" LOC="AM8"; +#NET "unused_n(1)" LOC="AM7"; +#NET "unused_p(2)" LOC="AH8"; +#NET "unused_n(2)" LOC="AH7"; +#NET "unused_p(3)" LOC="AF11"; +#NET "unused_n(3)" LOC="AG11"; +NET "serialout_p(0)" LOC = "AJ9"; +NET "serialout_n(0)" LOC = "AH9"; +#NET "serialout_p(1)" LOC = "AJ9"; +#NET "serialout_n(1)" LOC = "AH9"; +NET "serialout_p(2)" LOC = "AK7"; +NET "serialout_n(2)" LOC = "AJ7"; +#NET "serialout_p(3)" LOC = "AF9"; +#NET "serialout_n(3)" LOC = "AE9"; +NET "serialout_p(4)" LOC = "AF9"; +NET "serialout_n(4)" LOC = "AE9"; +#NET "serialout_p(5)" LOC = "AL9"; +#NET "serialout_n(5)" LOC = "AK9"; +NET "serialout_p(6)" LOC = "AL10"; +NET "serialout_n(6)" LOC = "AM10"; +#NET "serialout_p(7)" LOC = "AL10"; +#NET "serialout_n(7)" LOC = "AM10"; + +NET "serialout_p(8)" LOC = "AL9"; +NET "serialout_n(8)" LOC = "AK9"; +#NET "serialout_p(9)" LOC = "J31"; +#NET "serialout_n(9)" LOC = "J30"; +NET "serialout_p(10)" LOC = "AL11"; +NET "serialout_n(10)" LOC = "AM11"; +#NET "serialout_p(11)" LOC = "T31"; +#NET "serialout_n(11)" LOC = "T30"; +NET "serialout_p(12)" LOC = "AK13"; +NET "serialout_n(12)" LOC = "AL13"; +#NET "serialout_p(13)" LOC = "M32"; +#NET "serialout_n(13)" LOC = "M31"; +NET "serialout_p(14)" LOC = "AK14"; +NET "serialout_n(14)" LOC = "AL14"; +#NET "serialout_p(15)" LOC = "H28"; +#NET "serialout_n(15)" LOC = "H27"; + + +NET "serialin_p(0)" LOC = "N29"; +NET "serialin_n(0)" LOC = "N28"; +NET "serialin_p(1)" LOC = "P32"; +NET "serialin_n(1)" LOC = "N32"; +NET "serialin_p(2)" LOC = "K32"; +NET "serialin_n(2)" LOC = "K31"; +NET "serialin_p(3)" LOC = "N27"; +NET "serialin_n(3)" LOC = "M28"; +NET "serialin_p(4)" LOC = "L31"; +NET "serialin_n(4)" LOC = "L30"; +NET "serialin_p(5)" LOC = "M32"; +NET "serialin_n(5)" LOC = "M31"; +NET "serialin_p(6)" LOC = "E32"; +NET "serialin_n(6)" LOC = "F31"; +NET "serialin_p(7)" LOC = "G32"; +NET "serialin_n(7)" LOC = "G31"; + +NET "serialin_p(8)" LOC = "H28"; +NET "serialin_n(8)" LOC = "H27"; +NET "serialin_p(9)" LOC = "G30"; +NET "serialin_n(9)" LOC = "F30"; +NET "serialin_p(10)" LOC = "H30"; +NET "serialin_n(10)" LOC = "H29"; +NET "serialin_p(11)" LOC = "J31"; +NET "serialin_n(11)" LOC = "J30"; +NET "serialin_p(12)" LOC = "K28"; +NET "serialin_n(12)" LOC = "J27"; +NET "serialin_p(13)" LOC = "T26"; +NET "serialin_n(13)" LOC = "R26"; +NET "serialin_p(14)" LOC = "U28"; +NET "serialin_n(14)" LOC = "U27"; +NET "serialin_p(15)" LOC = "T31"; +NET "serialin_n(15)" LOC = "T30"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +NET "TX_EN" LOC="AJ6"; +NET "TX_DIS" LOC="AM3"; +NET "TX_RESET" LOC="AL3"; +NET "TX_FAULT" LOC="AG7"; +NET "RX0_RX_EN" LOC="AM6"; +NET "RX0_EN_SD" LOC="AL6"; +NET "RX0_SD" LOC="AG6"; +NET "RX0_SQ_EN" LOC="AG5"; +NET "RX1_RX_EN" LOC="AJ5"; +NET "RX1_EN_SD" LOC="AH5"; +NET "RX1_SD" LOC="AD21"; +NET "RX1_SQ_EN" LOC="AD20"; + +NET "TX_EN" IOSTANDARD= "LVCMOS33"; +NET "TX_DIS" IOSTANDARD= "LVCMOS33"; +NET "TX_RESET" IOSTANDARD= "LVCMOS33"; +NET "TX_FAULT" IOSTANDARD= "LVTTL"; +NET "RX0_RX_EN" IOSTANDARD= "LVCMOS33"; +NET "RX0_EN_SD" IOSTANDARD= "LVCMOS33"; +NET "RX0_SD" IOSTANDARD= "LVTTL"; +NET "RX0_SQ_EN" IOSTANDARD= "LVCMOS33"; +NET "RX1_RX_EN" IOSTANDARD= "LVCMOS33"; +NET "RX1_EN_SD" IOSTANDARD= "LVCMOS33"; +NET "RX1_SD" IOSTANDARD= "LVTTL"; +NET "RX1_SQ_EN" IOSTANDARD= "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; +#NET "unused_p(0)" IOSTANDARD = "LVDS_25"; +#NET "unused_n(0)" IOSTANDARD = "LVDS_25"; +#NET "unused_p(1)" IOSTANDARD = "LVDS_25"; +#NET "unused_n(1)" IOSTANDARD = "LVDS_25"; +#NET "unused_p(2)" IOSTANDARD = "LVDS_25"; +#NET "unused_n(2)" IOSTANDARD = "LVDS_25"; +#NET "unused_p(3)" IOSTANDARD = "LVDS_25"; +#NET "unused_n(3)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.nsqp.flipped b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.nsqp.flipped new file mode 100644 index 0000000000000000000000000000000000000000..db1b3068abf8824bb2d8317090fa29dbde15ae81 --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.opto.nsqp.flipped @@ -0,0 +1,354 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioStave0.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +#NET clk320 TNM_NET = FFS clk320; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET mainClk TNM_NET = FFS mainClk; +INST "U_HsioStave0Core1/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; +INST "U_HsioStave0Core2/thetdc/stopcontrol" RLOC_ORIGIN="X44Y89"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 TS_pgpClk / 2; +TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioStave0Core*/channelmask(*) TIG; +NET U_HsioStave0Core*/dfifothresh(*) TIG; +#NET U_HsioStave0Core*/enablereadout(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(*) maxskew = 250 ps ; + +INST "U_HsioStave0Core*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +NET "iMainClkP" LOC = "H17"; +NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +NET "iMgtRxN2" LOC = "AA1"; +NET "iMgtRxP2" LOC = "Y1"; +NET "oMgtTxN2" LOC = "V1"; +NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis2" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "oDebug(0)" LOC = "N10"; +NET "oDebug(1)" LOC = "N9"; +NET "oDebug(2)" LOC = "N8"; +NET "oDebug(3)" LOC = "N7"; +NET "oDebug(4)" LOC = "U8"; +NET "oDebug(5)" LOC = "T8"; +NET "oDebug(6)" LOC = "L6"; +NET "oDebug(7)" LOC = "L5"; +NET "oDebug(0)" IOSTANDARD="LVCMOS25"; +NET "oDebug(1)" IOSTANDARD="LVCMOS25"; +NET "oDebug(2)" IOSTANDARD="LVCMOS25"; +NET "oDebug(3)" IOSTANDARD="LVCMOS25"; +NET "oDebug(4)" IOSTANDARD="LVCMOS25"; +NET "oDebug(5)" IOSTANDARD="LVCMOS25"; +NET "oDebug(6)" IOSTANDARD="LVCMOS25"; +NET "oDebug(7)" IOSTANDARD="LVCMOS25"; +NET "oDebug(0)" SLEW="FAST"; +NET "oDebug(1)" SLEW="FAST"; +NET "oDebug(2)" SLEW="FAST"; +NET "oDebug(3)" SLEW="FAST"; +NET "oDebug(4)" SLEW="FAST"; +NET "oDebug(5)" SLEW="FAST"; +NET "oDebug(6)" SLEW="FAST"; +NET "oDebug(7)" SLEW="FAST"; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "doricreset1" LOC = "AJ11"; +NET "doricreset1" IOSTANDARD="LVCMOS25"; +NET "doricreset2" LOC = "AK11"; +NET "doricreset2" IOSTANDARD="LVCMOS25"; + +#NET "oExtrstP" LOC = "N10"; +#NET "oExtrstN" LOC = "N9"; +#NET "oExtrstP" IOSTANDARD="LVDS_25"; +#NET "oExtrstN" IOSTANDARD="LVDS_25"; + +NET "serialout_p(0)" LOC = "AJ9"; +NET "serialout_n(0)" LOC = "AH9"; +#NET "serialout_p(1)" LOC = "AJ9"; +#NET "serialout_n(1)" LOC = "AH9"; +NET "serialout_p(2)" LOC = "AL10"; +NET "serialout_n(2)" LOC = "AM10"; +#NET "serialout_p(3)" LOC = "AF9"; +#NET "serialout_n(3)" LOC = "AE9"; +NET "serialout_p(4)" LOC = "AF9"; +NET "serialout_n(4)" LOC = "AE9"; +#NET "serialout_p(5)" LOC = "AL9"; +#NET "serialout_n(5)" LOC = "AK9"; +NET "serialout_p(6)" LOC = "AL11"; +NET "serialout_n(6)" LOC = "AM11"; +#NET "serialout_p(7)" LOC = "AL10"; +#NET "serialout_n(7)" LOC = "AM10"; + +#NET "serialout_p(8)" LOC = "G30"; +#NET "serialout_n(8)" LOC = "F30"; +#NET "serialout_p(9)" LOC = "J31"; +#NET "serialout_n(9)" LOC = "J30"; +#NET "serialout_p(10)" LOC = "T26"; +#NET "serialout_n(10)" LOC = "R26"; +#NET "serialout_p(11)" LOC = "T31"; +#NET "serialout_n(11)" LOC = "T30"; +#NET "serialout_p(12)" LOC = "N27"; +#NET "serialout_n(12)" LOC = "M28"; +#NET "serialout_p(13)" LOC = "M32"; +#NET "serialout_n(13)" LOC = "M31"; +#NET "serialout_p(14)" LOC = "G32"; +#NET "serialout_n(14)" LOC = "G31"; +#NET "serialout_p(15)" LOC = "H28"; +#NET "serialout_n(15)" LOC = "H27"; + + +NET "serialin_p(0)" LOC = "G30"; +NET "serialin_n(0)" LOC = "F30"; +NET "serialin_p(1)" LOC = "J31"; +NET "serialin_n(1)" LOC = "J30"; +NET "serialin_p(2)" LOC = "T26"; +NET "serialin_n(2)" LOC = "R26"; +NET "serialin_p(3)" LOC = "T31"; +NET "serialin_n(3)" LOC = "T30"; +NET "serialin_p(4)" LOC = "N27"; +NET "serialin_n(4)" LOC = "M28"; +NET "serialin_p(5)" LOC = "M32"; +NET "serialin_n(5)" LOC = "M31"; +NET "serialin_p(6)" LOC = "G32"; +NET "serialin_n(6)" LOC = "G31"; +NET "serialin_p(7)" LOC = "H28"; +NET "serialin_n(7)" LOC = "H27"; + +#NET "serialin_p(8)" LOC = "AH15"; +#NET "serialin_n(8)" LOC = "AJ15"; +#NET "serialin_p(9)" LOC = "AF15"; +#NET "serialin_n(9)" LOC = "AG15"; +#NET "serialin_p(10)" LOC = "AE13"; +#NET "serialin_n(10)" LOC = "AF13"; +#NET "serialin_p(11)" LOC = "AJ16"; +#NET "serialin_n(11)" LOC = "AK16"; +#NET "serialin_p(12)" LOC = "H24"; +#NET "serialin_n(12)" LOC = "J24"; +#NET "serialin_p(13)" LOC = "G22"; +#NET "serialin_n(13)" LOC = "H22"; +#NET "serialin_p(14)" LOC = "E24"; +#NET "serialin_n(14)" LOC = "F24"; +#NET "serialin_p(15)" LOC = "J25"; +#NET "serialin_n(15)" LOC = "H25"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +NET "TX_EN" LOC="AJ6"; +NET "TX_DIS" LOC="AM3"; +NET "TX_RESET" LOC="AL3"; +NET "TX_FAULT" LOC="AG7"; +NET "RX0_RX_EN" LOC="AM6"; +NET "RX0_EN_SD" LOC="AL6"; +NET "RX0_SD" LOC="AG6"; +NET "RX0_SQ_EN" LOC="AG5"; +NET "RX1_RX_EN" LOC="AJ5"; +NET "RX1_EN_SD" LOC="AH5"; +NET "RX1_SD" LOC="AD21"; +NET "RX1_SQ_EN" LOC="AD20"; + +NET "TX_EN" IOSTANDARD= "LVCMOS33"; +NET "TX_DIS" IOSTANDARD= "LVCMOS33"; +NET "TX_RESET" IOSTANDARD= "LVCMOS33"; +NET "TX_FAULT" IOSTANDARD= "LVTTL"; +NET "RX0_RX_EN" IOSTANDARD= "LVCMOS33"; +NET "RX0_EN_SD" IOSTANDARD= "LVCMOS33"; +NET "RX0_SD" IOSTANDARD= "LVTTL"; +NET "RX0_SQ_EN" IOSTANDARD= "LVCMOS33"; +NET "RX1_RX_EN" IOSTANDARD= "LVCMOS33"; +NET "RX1_EN_SD" IOSTANDARD= "LVCMOS33"; +NET "RX1_SD" IOSTANDARD= "LVTTL"; +NET "RX1_SQ_EN" IOSTANDARD= "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.rotated b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.rotated new file mode 100644 index 0000000000000000000000000000000000000000..da051433a9092fae16ad0362c34ed533dbe2c90c --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.ucf.rotated @@ -0,0 +1,368 @@ + +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : HsioStave0.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +#NET clk320 TNM_NET = FFS clk320; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET mainClk TNM_NET = FFS mainClk; + +INST "U_triggerlogic/thetdc/CHAIN[*].TAP" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/CHAIN[*].DELAYY" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/startcontrol" U_SET="TDC1"; +INST "U_triggerlogic/thetdc/stopcontrol" U_SET="TDC1"; +#INST "U_HsioStave0Core2/thetdc/CHAIN[*].TAP" U_SET="TDC2"; +#INST "U_HsioStave0Core2/thetdc/CHAIN[*].DELAYY" U_SET="TDC2"; +#INST "U_HsioStave0Core2/thetdc/startcontrol" U_SET="TDC2"; +#IINST "U_HsioStave0Core2/thetdc/stopcontrol" U_SET="TDC2"; + +INST "U_triggerlogic/thetdc/stopcontrol" RLOC_ORIGIN="X44Y117"; +#INST "U_HsioStave0Core2/thetdc/stopcontrol" RLOC_ORIGIN="X44Y89"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 6.4 ns HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 25.6 ns HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 12.8 ns HIGH 50%; +#TIMESPEC TS_clk320 = PERIOD clk320 TS_pgpClk / 2; +TIMESPEC TS_mainClk = PERIOD mainClk 6.4 ns HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_mainClk_r = RISING mainClk; + +# Inter Domain Constraints +# TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +#TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 8ns; +# NET U_HsioFei4Core/go TIG; +NET U_HsioStave0Core*/channelmask(*) TIG; +NET U_HsioStave0Core*/dfifothresh(*) TIG; +#NET U_HsioStave0Core*/enablereadout(*) TIG; + +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +#timespec ts_03 = from ffs(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; +#timespec ts_04 = from rams(*fei4fifo*) to ffs(*fei4dataflag*) 6.4ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + +NET serialinb(*) maxskew = 250 ps ; + +INST "U_HsioStave0Core*/*receivedata/ff_*" IOB=FALSE; + + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +#NET "iMainClkP" LOC = "H17"; +#NET "iMainClkN" LOC = "J17"; +# fiber 1 +NET "iMgtRxN" LOC = "N1"; +NET "iMgtRxP" LOC = "M1"; +NET "oMgtTxN" LOC = "T1"; +NET "oMgtTxP" LOC = "R1"; +# fiber 2 +NET "iMgtRxN2" LOC = "AA1"; +NET "iMgtRxP2" LOC = "Y1"; +NET "oMgtTxN2" LOC = "V1"; +NET "oMgtTxP2" LOC = "U1"; +NET "oReload" LOC = "G16"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis2" LOC = "AK4"; +NET "transDis1" IOSTANDARD="LVCMOS33"; +NET "transDis2" IOSTANDARD="LVCMOS33"; + + +#NET "refclk_p" LOC = "J25"; +#NET "refclk_p" IOSTANDARD="LVDS_25"; +#NET "refclk_n" LOC = "H25"; +#NET "refclk_n" IOSTANDARD="LVDS_25"; + +#NET "xclk_p" LOC = "E24"; +#NET "xclk_p" IOSTANDARD="LVDS_25"; +#NET "xclk_n" LOC = "F24"; +#NET "xclk_n" IOSTANDARD="LVDS_25"; + +#NET "clkout40" LOC = "AJ29"; +#NET "clkout40" IOSTANDARD="LVCMOS33"; +NET "oDebug(0)" LOC = "N10"; +NET "oDebug(0)" IOSTANDARD="LVCMOS25"; +NET "oDebug(0)" SLEW=FAST; +NET "oDebug(1)" LOC = "N9"; +NET "oDebug(1)" IOSTANDARD="LVCMOS25"; +NET "oDebug(1)" SLEW=FAST; +NET "oDebug(2)" LOC = "N8"; +NET "oDebug(2)" IOSTANDARD="LVCMOS25"; +NET "oDebug(2)" SLEW=FAST; +NET "oDebug(3)" LOC = "N7"; +NET "oDebug(3)" IOSTANDARD="LVCMOS25"; +NET "oDebug(3)" SLEW=FAST; +NET "oDebug(4)" LOC = "U8"; +NET "oDebug(4)" IOSTANDARD="LVCMOS25"; +NET "oDebug(4)" SLEW=FAST; +NET "oDebug(5)" LOC = "T8"; +NET "oDebug(5)" IOSTANDARD="LVCMOS25"; +NET "oDebug(5)" SLEW=FAST; +NET "oDebug(6)" LOC = "L6"; +NET "oDebug(6)" IOSTANDARD="LVCMOS25"; +NET "oDebug(6)" SLEW=FAST; +NET "oDebug(7)" LOC = "L5"; +NET "oDebug(7)" IOSTANDARD="LVCMOS25"; +NET "oDebug(7)" SLEW=FAST; + +# Temperature ADC MAX145 +#NET "ADC_Data_in_p" LOC = "L4"; +#NET "ADC_Data_in_n" LOC = "L3"; +#NET "ADC_Clk_p" LOC = "T9"; +#NET "ADC_Clk_n" LOC = "R9"; +#NET "ADC_nCS_p" LOC = "U3"; +#NET "ADC_nCS_n" LOC = "T3"; + +NET "iHSIOtrigger(0)" LOC="J14"; +NET "iHSIOtrigger(0)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(0)" SLEW=FAST; + +NET "iHSIOtrigger(1)" LOC="L14"; +NET "iHSIOtrigger(1)" IOSTANDARD="LVTTL"; +NET "iHSIOtrigger(1)" SLEW=FAST; + +NET "oHSIOtrigger" LOC="L15"; +NET "oHSIOtrigger" IOSTANDARD="LVTTL"; +NET "oHSIOtrigger" SLEW=FAST; + +NET "iHSIObusy" LOC="H19"; +NET "iHSIObusy" IOSTANDARD="LVTTL"; +NET "iHSIObusy" SLEW=FAST; +NET "iHSIObusy" PULLDOWN; + +NET "iExtreload" LOC = "G15"; +NET "iExtreload" IOSTANDARD="LVCMOS25"; +NET "iExtreload" PULLUP; + +NET "doricreset1" LOC = "AJ11"; +NET "doricreset1" IOSTANDARD="LVCMOS25"; +NET "doricreset2" LOC = "AK11"; +NET "doricreset2" IOSTANDARD="LVCMOS25"; + +NET "iExtrst" LOC = "K18"; +NET "iExtrst" IOSTANDARD="LVCMOS33"; +NET "iExtrst" SLEW=FAST; +NET "iExttrigger" LOC = "K19"; +NET "iExttrigger" IOSTANDARD="LVCMOS33"; +NET "iExttrigger" SLEW=FAST; +NET "oExttrgclk" LOC = "K16"; +NET "oExttrgclk" IOSTANDARD="LVCMOS33"; +NET "oExttrgclk" SLEW=FAST; +NET "oExtBusy" LOC = "J16"; +NET "oExtBusy" IOSTANDARD="LVCMOS33"; +NET "oExtBusy" SLEW=FAST; + + +NET "serialout_p(1)" LOC = "AM13"; +NET "serialout_n(1)" LOC = "AM12"; +NET "serialout_p(0)" LOC = "AM8"; +NET "serialout_n(0)" LOC = "AM7"; +NET "serialout_p(3)" LOC = "AK14"; +NET "serialout_n(3)" LOC = "AL14"; +NET "serialout_p(2)" LOC = "AK13"; +NET "serialout_n(2)" LOC = "AL13"; +NET "serialout_p(5)" LOC = "AL11"; +NET "serialout_n(5)" LOC = "AM11"; +NET "serialout_p(4)" LOC = "AL9"; +NET "serialout_n(4)" LOC = "AK9"; +NET "serialout_p(7)" LOC = "AL10"; +NET "serialout_n(7)" LOC = "AM10"; +NET "serialout_p(6)" LOC = "AF9"; +NET "serialout_n(6)" LOC = "AE9"; + +NET "serialout_p(9)" LOC = "AK7"; +NET "serialout_n(9)" LOC = "AJ7"; +NET "serialout_p(8)" LOC = "AJ9"; +NET "serialout_n(8)" LOC = "AH9"; +NET "serialout_p(11)" LOC = "AF11"; +NET "serialout_n(11)" LOC = "AG11"; +NET "serialout_p(10)" LOC = "AH8"; +NET "serialout_n(10)" LOC = "AH7"; +NET "serialout_p(13)" LOC = "AJ12"; +NET "serialout_n(13)" LOC = "AK12"; +NET "serialout_p(12)" LOC = "AH10"; +NET "serialout_n(12)" LOC = "AJ10"; +NET "serialout_p(15)" LOC = "AH14"; +NET "serialout_n(15)" LOC = "AJ14"; +NET "serialout_p(14)" LOC = "AF10"; +NET "serialout_n(14)" LOC = "AG10"; + +NET "serialin_p(8)" LOC = "AC12"; +NET "serialin_n(8)" LOC = "AB12"; +NET "serialin_p(10)" LOC = "AG13"; +NET "serialin_n(10)" LOC = "AH13"; +NET "serialin_p(12)" LOC = "AD11"; +NET "serialin_n(12)" LOC = "AE11"; +NET "serialin_p(14)" LOC = "AD10"; +NET "serialin_n(14)" LOC = "AD9"; +NET "serialin_p(9)" LOC = "AE14"; +NET "serialin_n(9)" LOC = "AF14"; +NET "serialin_p(11)" LOC = "AB11"; +NET "serialin_n(11)" LOC = "AA11"; +NET "serialin_p(13)" LOC = "AD14"; +NET "serialin_n(13)" LOC = "AC13"; +NET "serialin_p(15)" LOC = "AB13"; +NET "serialin_n(15)" LOC = "AA13"; + +NET "serialin_p(0)" LOC = "AH15"; +NET "serialin_n(0)" LOC = "AJ15"; +NET "serialin_p(2)" LOC = "AF15"; +NET "serialin_n(2)" LOC = "AG15"; +NET "serialin_p(4)" LOC = "AE13"; +NET "serialin_n(4)" LOC = "AF13"; +NET "serialin_p(6)" LOC = "AJ16"; +NET "serialin_n(6)" LOC = "AK16"; +NET "serialin_p(1)" LOC = "H24"; +NET "serialin_n(1)" LOC = "J24"; +NET "serialin_p(3)" LOC = "G22"; +NET "serialin_n(3)" LOC = "H22"; +NET "serialin_p(5)" LOC = "E24"; +NET "serialin_n(5)" LOC = "F24"; +NET "serialin_p(7)" LOC = "J25"; +NET "serialin_n(7)" LOC = "H25"; + + +#NET "discinP(0)" LOC = "AD7"; +#NET "discinP(1)" LOC = "AD6"; +#NET "discinP(2)" LOC = "AM6"; +#NET "discinP(3)" LOC = "AL6"; + +#NET "discinP(0)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(1)" IOSTANDARD = "LVCMOS33"; +#NET "discinP(2)" IOSTANDARD= "LVCMOS33"; +#NET "discinP(3)" IOSTANDARD = "LVCMOS33"; + +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; + +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; diff --git a/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.vhd b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.vhd new file mode 100755 index 0000000000000000000000000000000000000000..1a369aedb4e8c05e295dc95b7ae33db67da7692d --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/hdl/HsioStave0.vhd @@ -0,0 +1,886 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : HsioCosmic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity HsioStave0 is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + iMgtRxN2 : in std_logic; + iMgtRxP2 : in std_logic; + oMgtTxN2 : out std_logic; + oMgtTxP2 : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(15 downto 0); + serialout : out std_logic_vector(15 downto 0); + serialout_p : out std_logic_vector(15 downto 0); + serialout_n : out std_logic_vector(15 downto 0); + serialin_p : in std_logic_vector(15 downto 0); + serialin_n : in std_logic_vector(15 downto 0); + discinP : in std_logic_vector(3 downto 0); + HITOR : in std_logic; +-- discinN : in std_logic_vector(1 downto 0); + clkout40 : out std_logic; + refclk_p : out std_logic; + refclk_n : out std_logic; + xclk_p : out std_logic; + xclk_n : out std_logic; + + -- Reset button + iResetInL : in std_logic; + -- Reload firmware + oReload : out std_logic; + iExtreload : in std_logic; + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(7 downto 0); + + -- Eudet trigger + iExttrigger : in std_logic; + iExtrst : in std_logic; + oExtbusy : out std_logic; + oExttrgclk : out std_logic; + + --HSIO trigger IF + iHSIOtrigger : in std_logic_vector(1 downto 0); + oHSIOtrigger : out std_logic; + oHSIObusy : out std_logic; + iHSIObusy : in std_logic; + + oExtrstP : out std_logic; + oExtrstN : out std_logic; + oExttriggerP : out std_logic; + oExttriggerN : out std_logic; + + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic; + transDis2 : out std_logic; + + -- Doric resets + doricreset1: out std_logic; + doricreset2: out std_logic; + --unused_p : out std_logic_vector(3 downto 0); + --unused_n : out std_logic_vector(3 downto 0); + + -- Fiber modules + TX_EN : out std_logic; + TX_DIS : out std_logic; + TX_RESET : out std_logic; + TX_FAULT : in std_logic; + RX0_RX_EN : out std_logic; + RX0_EN_SD : out std_logic; + RX0_SD : in std_logic; + RX0_SQ_EN : out std_logic; + RX1_RX_EN : out std_logic; + RX1_EN_SD : out std_logic; + RX1_SD : in std_logic; + RX1_SQ_EN : out std_logic + ); +end HsioStave0; + + +-- Define architecture for top level module +architecture HsioStave0 of HsioStave0 is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of HsioStave0 : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of HsioStave0 : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of HsioStave0 : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := TRUE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; +--component ila + --PORT ( + --CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + --CLK : IN STD_LOGIC; + --DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; + --component icon + --PORT ( + --CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- + --end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal pgpReset : std_logic; + signal clk320 : std_logic; + signal oClk320 : std_logic; + signal reload1 : std_logic; + signal reload2 : std_logic; + signal reload : std_logic; + signal resetOut : std_logic; + signal resetOut1 : std_logic; + signal resetOut2 : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal mgtRxN2 : std_logic; + signal mgtRxP2 : std_logic; + signal mgtTxN2 : std_logic; + signal mgtTxP2 : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(7 downto 0); + signal sysClk125i : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal halfclock : std_logic; + signal quarterclock : std_logic; + signal exttrigger : std_logic; + signal extrst : std_logic; + signal exttriggero : std_logic; + signal extrsto : std_logic; + signal extbusy : std_logic; + signal exttrgclk : std_logic; + signal hsiobusyb : std_logic; + signal hsiobusyinb : std_logic; + signal hsiobusyb1 : std_logic; + signal hsiobusyb2 : std_logic; + signal hsiotriggerb : std_logic_vector(1 downto 0); + signal doricresetb1 : std_logic; + signal doricresetb2 : std_logic; + signal serialoutb : std_logic_vector(7 downto 0); + signal serialoutb1 : std_logic_vector(15 downto 0); + signal serialoutb2 : std_logic_vector(15 downto 0); + signal serialinb : std_logic_vector(15 downto 0); + signal serialinb1 : std_logic_vector(15 downto 0); + signal serialinb2 : std_logic_vector(15 downto 0); + signal serialininv : std_logic_vector(15 downto 0); + signal discinb : std_logic_vector(3 downto 0); + signal ccontrol: std_logic_vector(35 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(0 downto 0); + signal clockb : std_logic_vector(7 downto 0); + signal extreload : std_logic; + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal holdrst : std_logic; + signal hitorb : std_logic; + + signal txfault : std_logic; + signal rx0sd : std_logic; + signal rx1sd : std_logic; + + signal pgpClkUnbuf : std_logic; + signal pgpClk90Unbuf : std_logic; + signal sysClkUnbuf : std_logic; + signal disc : std_logic_vector(4 downto 0); + + signal calibmode1 : std_logic_vector(1 downto 0); + signal calibmode2 : std_logic_vector(1 downto 0); + signal calibmode : std_logic_vector(1 downto 0); + signal eudaqdone : std_logic; + signal eudaqtrgword : std_logic_vector(14 downto 0); + signal trigenabled1 : std_logic; + signal trigenabled2 : std_logic; + signal trigenabled : std_logic; + signal paused1 : std_logic; + signal paused2 : std_logic; + signal paused : std_logic; + signal triggermask1 : std_logic_vector(15 downto 0); + signal triggermask2 : std_logic_vector(15 downto 0); + signal triggermask : std_logic_vector(15 downto 0); + signal resetdelay1 : std_logic; + signal resetdelay2 : std_logic; + signal resetdelay : std_logic; + signal incrementdelay1: std_logic_vector(4 downto 0); + signal incrementdelay2: std_logic_vector(4 downto 0); + signal incrementdelay: std_logic_vector(4 downto 0); + signal discop1 : std_logic_vector(15 downto 0); + signal discop2 : std_logic_vector(15 downto 0); + signal discop : std_logic_vector(15 downto 0); + signal telescopeop1 : std_logic_vector(2 downto 0); + signal telescopeop2 : std_logic_vector(2 downto 0); + signal telescopeop : std_logic_vector(2 downto 0); + signal period1 : std_logic_vector(31 downto 0); + signal period2 : std_logic_vector(31 downto 0); + signal period : std_logic_vector(31 downto 0); + signal fifothresh : std_logic; + signal fifothresh1 : std_logic; + signal fifothresh2 : std_logic; + signal serbusy1 : std_logic; + signal serbusy2 : std_logic; + signal serbusy : std_logic; + signal tdcreadoutbusy1: std_logic; + signal tdcreadoutbusy2: std_logic; + signal tdcreadoutbusy: std_logic; + signal tcounter1 : std_logic_vector(31 downto 0); + signal tcounter2 : std_logic_vector(31 downto 0); + signal l1a1 : std_logic; + signal l1a2 : std_logic; + signal l1a : std_logic; + signal triggerword : std_logic_vector(7 downto 0); + signal busy : std_logic; + signal rstFromCore1 : std_logic; + signal rstFromCore2 : std_logic; + signal rstFromCore : std_logic; + signal hitbus : std_logic_vector(1 downto 0); + signal present : std_logic_vector(1 downto 0); + signal phaseclksel : std_logic; + signal phaseclksel1 : std_logic; + signal phaseclksel2 : std_logic; + signal startmeas : std_logic; + signal startmeas1 : std_logic; + signal startmeas2 : std_logic; + signal hitbusout : std_logic; + signal hitbusoutgated: std_logic; + signal phasebusySelc : is array (1 downto 0) of std_logic_vector(1 downto 0); + signal phasebusySel : std_logic_vector(1 downto 0); + signal phasebusyEnc : std_logic_vector(1 downto 0); + signal phasebusyEn : std_logic; + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + signal holdctr : std_logic_vector(24 downto 0); + signal clockidctrl : std_logic; + signal idctrlrst : std_logic; + signal idcounter : std_logic_vector(2 downto 0); + component ODDR port ( + Q : out std_logic; + CE : in std_logic; + C : in std_logic; + D1 : in std_logic; + D2 : in std_logic; + R : in std_logic; + S : in std_logic + ); + end component; + + -- Black Box Attributes +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of IBUF : component is TRUE; + attribute syn_noprune of IBUF : component is TRUE; + attribute syn_black_box of OBUF : component is TRUE; + attribute syn_noprune of OBUF : component is TRUE; + attribute syn_black_box of IBUFDS : component is TRUE; + attribute syn_noprune of IBUFDS : component is TRUE; + attribute syn_black_box of OBUFDS : component is TRUE; + attribute syn_noprune of OBUFDS : component is TRUE; + attribute syn_black_box of BUFGMUX : component is TRUE; + attribute syn_noprune of BUFGMUX : component is TRUE; + attribute syn_hier: string; + attribute syn_hier of HsioStave0: architecture is "hard"; + attribute xc_props : string; + attribute xc_props of HsioStave0 : architecture is "KEEP_HIERARCHY=TRUE"; + attribute syn_noprune of U_idelayctrl: label is true; +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: entity work.PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + clk320 => clk320, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125, + pgpClkUnbuf => pgpClkUnbuf, + pgpClk90Unbuf => pgpClk90Unbuf, + locClkUnbuf => sysClkUnbuf + + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK125: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + mgtRxN2 <= iMgtRxN2; + mgtRxP2 <= iMgtRxP2; + oMgtTxN2 <= mgtTxN2; + oMgtTxP2 <= mgtTxP2; + + -- fiber modules + U_TX_EN : OBUF port map ( I => '1' , O => TX_EN ); + U_TX_DIS : OBUF port map ( I => '0' , O => TX_DIS ); + U_TX_RESET : OBUF port map ( I => '1' , O => TX_RESET ); + U_RX0_RX_EN: OBUF port map ( I => '1' , O => RX0_RX_EN ); + U_RX0_EN_SD: OBUF port map ( I => '0' , O => RX0_EN_SD ); + U_RX0_SQ_EN: OBUF port map ( I => '0' , O => RX0_SQ_EN ); + U_RX1_RX_EN: OBUF port map ( I => '1' , O => RX1_RX_EN ); + U_RX1_EN_SD: OBUF port map ( I => '0' , O => RX1_EN_SD ); + U_RX1_SQ_EN: OBUF port map ( I => '0' , O => RX1_SQ_EN ); + U_TX_FAULT: IBUF port map ( O => txfault , I => TX_FAULT ); + U_RX0_SD: IBUF port map ( O => rx0sd , I => RX0_SD ); + U_RX1_SD: IBUF port map ( O => rx1sd , I => RX1_SD ); + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_reload : OBUF port map ( I => reload , O => oReload ); + U_clkout40 : OBUF port map ( I => sysClk125i , O => clkout40 ); + U_refclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => refclk_p , OB => refclk_n ); + U_xclk : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => sysClk125i , O => xclk_p , OB => xclk_n ); + +-- U_Clk320 : ODDR port map ( +-- Q => oClk320, +-- CE => '1', +-- C => clk320, +-- D1 => '0', +-- D2 => '1', +-- R => '0', +-- S => '0' +-- ); +-- U_clk320buf : OBUFDS generic map ( IOSTANDARD=>"LVDS_25") +-- port map ( I => oClk320 , O => oDebug(4) , OB => oDebug(5) ); + +-- U_bit0out : OBUFDS generic map ( IOSTANDARD=>"LVDS_25") +-- port map ( I => debug(7) , O => oDebug(6) , OB => oDebug(7) ); + + --UNUSED_IO_DATA: + --for I in 0 to 3 generate + --U_unused : OBUFDS generic map ( IOSTANDARD=>"LVDS_25") + -- port map ( I => '0' , O => unused_p(I) , OB => unused_n(I) ); + --end generate UNUSED_IO_DATA; + -- Debug + U_Debug0 : OBUF port map ( I => debug(0) , O => oDebug(0) ); + U_Debug1 : OBUF port map ( I => debug(1) , O => oDebug(1) ); + U_Debug2 : OBUF port map ( I => debug(2) , O => oDebug(2) ); + U_Debug3 : OBUF port map ( I => debug(3) , O => oDebug(3) ); + U_Debug4 : OBUF port map ( I => debug(4) , O => oDebug(4) ); + U_Debug5 : OBUF port map ( I => debug(5) , O => oDebug(5) ); + U_Debug6 : OBUF port map ( I => debug(6) , O => oDebug(6) ); + U_Debug7 : OBUF port map ( I => debug(7) , O => oDebug(7) ); + + U_transdis : OBUF port map ( I => '0' , O => transDis1 ); + U_transdis2 : OBUF port map ( I => '0' , O => transDis2 ); + + U_rstb_1 : OBUF port map ( I => doricresetb1 , O => doricreset1 ); + U_rstb_2 : OBUF port map ( I => doricresetb2 , O => doricreset2 ); + + U_exttrgclk : OBUF port map ( I => exttrgclk , O => oExttrgclk ); + + U_extbusy : OBUF port map ( I => extbusy , O => oExtBusy ); + + U_exttrigger : IBUF port map ( O => exttrigger , I => iExttrigger ); + + U_extrst : IBUF port map ( O => extrst , I => iExtrst ); + + --U_exttriggero : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + -- port map ( I => exttriggero , O => oExttriggerP , OB => oExttriggerN ); + U_exttriggero : OBUF port map ( I => exttriggero , O => oExttriggerP ); + + U_extrsto : OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => extrsto , O => oExtrstP , OB => oExtrstN ); + + U_HSIObusy : OBUF port map ( I => hsiobusyb , O => oHSIObusy); + hitbusoutgated <= hitbusout and trigenabled and not paused; + U_HSIOtriggero : OBUF port map ( I => hitbusoutgated , O => oHSIOtrigger); + U_HSIOtrigger : IBUF port map ( O => hsiotriggerb(0) , I => iHSIOtrigger(0) ); + U_HSIOtrigger2 : IBUF port map ( O => hsiotriggerb(1) , I => iHSIOtrigger(1) ); + U_hsiobusyin : IBUF port map ( O => hsiobusyinb , I => iHSIObusy ); + U_extreload : IBUF port map ( O => extreload , I => iExtreload ); + + SERIALOUT_IO_DATA: + for I in 0 to 7 generate + U_serialout_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I*2) , OB => serialout_n(I*2) ); + U_Clk320 : ODDR port map ( + Q => clockb(I), + CE => '1', + C => sysClk125, + D1 => '0', + D2 => '1', + R => '0', + S => '0' + ); + U_serialoutclock_pn :OBUFDS generic map ( IOSTANDARD=>"LVDS_25", SLEW=>"FAST") + port map ( I => clockb(I) , O => serialout_p(I*2+1) , OB => serialout_n(I*2+1) ); + end generate SERIALOUT_IO_DATA; + + SERIALIN_IO_DATA: + for I in 0 to 15 generate + U_serialin_pn : IBUFDS generic map ( DIFF_TERM=>TRUE, IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialininv(I) ); + serialinb(I)<=not serialininv(I); + + end generate SERIALIN_IO_DATA; + + + --DISC_1: IBUFDS port map ( O => discinb(0), I => discinP(0) , IB => discinN(0) ); + --DISC_2: IBUFDS port map ( O => discinb(1), I => discinP(1) , IB => discinN(1) ); + DISC_1: IBUF port map ( O => discinb(0), I => discinP(0) ); + DISC_2: IBUF port map ( O => discinb(1), I => discinP(1) ); + DISC_3: IBUF port map ( O => discinb(2), I => discinP(2) ); + DISC_4: IBUF port map ( O => discinb(3), I => discinP(3) ); + DISC_5: IBUF port map ( O => hitorb, I => HITOR); + + -- Display Controller A + U_DispCntrlA: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: entity work.DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + + -- Output LED Data + dispDat <= dispDatA or dispDatB; + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + + end if; + end process; + + + --debug(7 downto 0)<=serialinb(7 downto 0); + paused <= paused1 or paused2; + resetdelay <= resetdelay1 or resetdelay2; + incrementdelay <= incrementdelay1 or incrementdelay2; + serbusy <= (serbusy1 and present(0)) or (serbusy2 and present(1)); + tdcreadoutbusy<= tdcreadoutbusy1 or tdcreadoutbusy2; + rstFromCore <= rstFromCore1 or rstFromCore2; + + phasebusyEn <= phasebusyEnc(0) or phasebusyEnc(1); + phasebusySel <= phasebusySelc(0) or phasebusySelc(1); + + fifothresh <= (fifothresh1 and present(0)) or (fifothresh2 and present(1)); + trigenabled <= (trigenabled1 or not present(0)) and (trigenabled2 or not present(1)) and (present(0) or present(1)); + l1a1 <= l1a and present(0); + l1a2 <= l1a and present(1); + + with present select discop <= discop2 when "10", discop1 when others; + with present select calibmode <= calibmode2 when "10", calibmode1 when others; + with present select triggermask <= triggermask2 when "10", triggermask1 when others; + with present select period <= period2 when "10", period1 when others; + with present select telescopeop <= telescopeop2 when "10", telescopeop1 when others; + with present select phaseclksel <= phaseclksel2 when "10", phaseclksel1 when others; + with present select startmeas <= startmeas2 when "10", startmeas1 when others; + + + U_triggerlogic: entity work.triggerlogic + port map( + clk => sysClk125, + rst => rstFromCore, + clk160 => pgpClk, + rst160 => pgpReset, + -- hardware inputs + discin => discinb, + hitbusin => hitbus, + -- HSIO trigger + HSIObusy => hsiobusyb, + HSIOtrigger => hsiotriggerb, + HSIObusyin => hsiobusyinb, + hitbusout => hitbusout, + + -- eudet trigger + exttrigger => exttrigger, + extrst => extrst, + extbusy => extbusy, + exttrgclk => exttrgclk, + + calibmode => calibmode, + startmeas => startmeas, + eudaqdone => eudaqdone, + eudaqtrgword => eudaqtrgword, + tcounter1 => tcounter1, + tcounter2 => tcounter2, + + trigenabled => trigenabled, + paused => paused, + triggermask => triggermask, + resetdelay => resetdelay, + incrementdelay => incrementdelay, + discop => discop, + telescopeop => telescopeop, + period => period, + fifothresh => fifothresh, + serbusy => serbusy, + tdcreadoutbusy => tdcreadoutbusy, + phaseclksel => phaseclksel, + phasebusyEn => phasebusyEn, + phasebusySel => phasebusySel, + l1a => l1a, + triggerword => triggerword, + busy =>busy, + coincd =>open +); + -- FPGA Core + U_HsioStave0Core1: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 7, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 4096, + buffersizetdc => 16384, + encodingDefault => "00", + hitbusreadout => '1') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload1, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb1, + serialout => serialoutb1, clock160 => mainClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut1, l1a => l1a1, + latchtriggerword => triggerword, tcounter1 => tcounter1, + tcounter2 => tcounter2, busy => busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode1, startmeas => startmeas1, + pausedout => paused1, present => present(0), + trgenabledout => trigenabled1, rstFromCore => rstFromCore1, + fifothresh => fifothresh1, triggermask => triggermask1, + discop => discop1, period => period1, + telescopeop => telescopeop1, resetdelay => resetdelay1, + incrementdelay => incrementdelay1, + sbusy => serbusy1, tdcbusy => tdcreadoutbusy1, + phaseclksel => phaseclksel1 , hitbus => hitbus(0), + debug => debug, + exttriggero => exttriggero, extrsto => extrsto, + doricreset => doricresetb1, + phasebusyEn => phasebusyEnc(0), phasebusySel => phasebusySelc(0), + dispDigitA => dispDigitE, dispDigitB => dispDigitF, + dispDigitC => open, dispDigitD => dispDigitH, + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => open, + sendAdcData => '0', adcData => (others => (others => '0')) + ); + dispDigitC<="0000000"&present(0); + dispDigitG<="0000000"&present(1); + U_HsioStave0Core2: entity work.HsioPixelCore + generic map( framedFirstChannel=> 0, + framedLastChannel=> 7, + rawFirstChannel => 11, + rawLastChannel => 10, + buffersizefe => 4096, + buffersizetdc => 16384, + encodingDefault => "00", + hitbusreadout => '1') + port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, pgpReset => pgpReset, + clk320 => clk320, reload => reload2, + mgtRxN => mgtRxN2, + mgtRxP => mgtRxP2, mgtTxN => mgtTxN2, + mgtTxP => mgtTxP2, serialin => serialinb2, + serialout => serialoutb2, clock160 => mainClk, + clock80 => halfclock, clock40 => quarterclock, + resetOut => resetOut2, l1a => l1a2, + latchtriggerword => triggerword, tcounter1=>tcounter1, + tcounter2=>tcounter2, busy =>busy, + eudaqdone => eudaqdone, eudaqtrgword => eudaqtrgword, + calibmodeout => calibmode2, startmeas => startmeas2, + pausedout => paused2, present => present(1), + trgenabledout => trigenabled2, rstFromCore => rstFromCore2, + fifothresh => fifothresh2, triggermask => triggermask2, + discop => discop2, period => period2, + telescopeop => telescopeop2, resetdelay => resetdelay2, + incrementdelay => incrementdelay2, + sbusy => serbusy2, tdcbusy => tdcreadoutbusy2, + phaseclksel=>phaseclksel2, hitbus => hitbus(1), + debug => open, + exttriggero => open, extrsto => open, + doricreset => doricresetb2, + phasebusyEn => phasebusyEnc(1), phasebusySel => phasebusySelc(1), + dispDigitA => dispDigitA, dispDigitB => dispDigitB, + dispDigitC => open, dispDigitD => dispDigitD, + dispDigitE => open, dispDigitF => open, + dispDigitG => open, dispDigitH => open, + pgpClkUnbuf => pgpClkUnbuf, pgpClk90Unbuf => pgpClk90Unbuf, + sysClkUnbuf => sysClkUnbuf, trigAdc => open, + sendAdcData => '0', adcData => (others => (others => '0')) + ); + serialoutb<= serialoutb2(3 downto 0) & serialoutb1(3 downto 0); + serialinb1(7 downto 0)<=serialinb(7 downto 0); + serialinb2(7 downto 0)<=serialinb(15 downto 8); + --dispDigitC<="0000000"&txfault; +-- serialout(15 downto 8) <= "00000000"; + + --dispDigitD<=x"02"; + + sysClk125i <= not sysClk125; + reload <= reload1 and reload2 and extreload; -- active low + resetOut <= resetOut1 or resetOut2; + --sysClk125i<=debug(0); + U_clock160: entity work.clock160 port map( + CLKIN_N_IN => iMainClkN, + CLKIN_P_IN => iMainClkP, + RST_IN => sysRst125, + CLKFX_OUT => mainClk, + CLKIN_IBUFGDS_OUT => clkin, + CLK0_OUT => clk0, + LOCKED_OUT => open); + + process(mainClk) + begin + if(mainClk'event and mainClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + --cdata(7 downto 0)<=serialinb(7 downto 0); + --cdata(31 downto 8) <=(others=>'0'); + --ctrig(0)<='0'; + --chipscope : ila + --port map ( + --CONTROL => ccontrol, + --CLK => mainClk, + --DATA => cdata, + --TRIG0 => ctrig); + --chipscopeicon : icon + --port map ( + --CONTROL0 => ccontrol); + U_idelctrlclk: entity work.clock200 port map( + CLKIN_IN => mainClk, + RST_IN => holdrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (holdctr(24)='0') then + holdrst<='0'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end process; + + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + + +end HsioStave0; diff --git a/rce/fw-hsio/projects/HsioStave0/images/.gitignore b/rce/fw-hsio/projects/HsioStave0/images/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d6b7ef32c8478a48c3994dcadc86837f4371184d --- /dev/null +++ b/rce/fw-hsio/projects/HsioStave0/images/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/rce/fw-hsio/projects/IBLcableTester/Makefile b/rce/fw-hsio/projects/IBLcableTester/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5c82cd853d84dbb484b348c2b7f4fdef5592551e --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/Makefile @@ -0,0 +1,12 @@ +# Project Name +export PROJECT = $(notdir $(PWD)) + +# List of build core directories. Relative to current directory. +CORE_DIRS = coregen ../../modules/pgp/coregen ../../modules/pgp2/coregen ../../modules/pixelcore/coregen + +# Optional ELF file to include. Relative to ./boot directory +#BOOT_ELF = udiTest.elf + +# Use top level makefile +include ../../system.mk + diff --git a/rce/fw-hsio/projects/IBLcableTester/Readme.txt b/rce/fw-hsio/projects/IBLcableTester/Readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0ba752b3e18a22530900255b57e6e1df48afd87 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/Readme.txt @@ -0,0 +1,59 @@ +This is a DPM project specific Readme.txt file. + +The files in this directory are used to build +the DPM project in this directory. The project +name matches the name of the directory in which +this file is found. + +The Makefile in this directory may be used to build +this project with a simple 'gmake' command. + +The Version.vhd file in this directory is used to +generate the software readable version constant +in the build and is also used to set the name of +the files added to the images directory. + +The following sub directories exist in this project: + +boot: + This directory contains boot loader files which are + used to program the boot loader code in the DPM. The + files in this directory include: + +config: + This directory contains Xilinx configuration files for + various steps in the synthesis process. The files in this + directory include: + + bitgen_options.txt: Options for bitgen + map_options.txt: Options for map + ngdbuild_options.txt: Options for ngdbuild + par_options.txt: Options for par + trce_options.txt: Options for trce + xst_options.txt: Options for xst + sources.txt Source file list used by xst + +coregen: + This directory holds the coregen project and any modules + generated by coregen that are specific to this project. + +debug: + This directory holds any debug files for the project. + +hdl: + This directory contains the source files (.vhd and .v) for + the project and the constraints file (.ucf) for the project. + The top level module name, its source file name and the ucf + file name should match the name of the project. + +images: + + This directory contains the result of the project compile. + The resulting .mcs and .bit files for the project are + added to this directory. The name of the copied file will + be: project_version.mcs/.bit. + +sim: + + Directory for simulation Makefile and test bench. + diff --git a/rce/fw-hsio/projects/IBLcableTester/Version.vhd b/rce/fw-hsio/projects/IBLcableTester/Version.vhd new file mode 100644 index 0000000000000000000000000000000000000000..449ef270a5e7d36f6af47d960ec6faf813db9163 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/Version.vhd @@ -0,0 +1,26 @@ +------------------------------------------------------------------------------- +-- Title : Version Constant File +-- Project : HSIO +------------------------------------------------------------------------------- +-- File : Version.vhd +-- Author : Martin Kocian, kocian@slac.stanford.edu +-- Created : 01/07/2013 +------------------------------------------------------------------------------- +-- Description: +-- Version Constant Module +------------------------------------------------------------------------------- +-- Copyright (c) 2012 by SLAC. All rights reserved. +------------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; + +package Version is + +constant FpgaVersion : std_logic_vector(31 downto 0) := x"00000001"; -- MAKE_VERSION + +end Version; + +------------------------------------------------------------------------------- +-- Revision History: +-- 01/07/2013 (0x00000001): Initial XST version +------------------------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/config/bitgen_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/bitgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..abf29c69b7888da03e96c154d93bc2f56add8ccd --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/bitgen_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx bitgen options file +##----------------------------------------------------------------------------- +-intstyle silent +-w diff --git a/rce/fw-hsio/projects/IBLcableTester/config/map_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/map_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..6cef41ff642fa23ed75c9e6516aa65c1c9c961af --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/map_options.txt @@ -0,0 +1,21 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx map options file +##----------------------------------------------------------------------------- + +#-intstyle silent +-ol high +-xe n +-t 1 +-register_duplication on +#-global_opt off +#-equivalent_register_removal on +#-u +#-cm Area +-detail +#-ir off +#-pr off +#-lc off +#-mt 2 + + + diff --git a/rce/fw-hsio/projects/IBLcableTester/config/ngdbuild_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/ngdbuild_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..95ca0eea7e533ba749eb765d1e8cdd2068359eab --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/ngdbuild_options.txt @@ -0,0 +1,5 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx ngdbuild options file +##----------------------------------------------------------------------------- +-nt timestamp + diff --git a/rce/fw-hsio/projects/IBLcableTester/config/par_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/par_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2cdd3ad019144a5e3f99c255af2010411238e4ea --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/par_options.txt @@ -0,0 +1,9 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx place and route options file +##----------------------------------------------------------------------------- +#-intstyle ise +-ol high +-xe n +#-mt 4 + + diff --git a/rce/fw-hsio/projects/IBLcableTester/config/promgen_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/promgen_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2c2257bee87830d2f7251e8db6d2b735977d3c56 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/promgen_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx promgen options file +##----------------------------------------------------------------------------- +-x xcf32p +-w +-p mcs +-c FF diff --git a/rce/fw-hsio/projects/IBLcableTester/config/sources.txt b/rce/fw-hsio/projects/IBLcableTester/config/sources.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8a33f5dd167cd832714f374340ae868c45504dd --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/sources.txt @@ -0,0 +1,40 @@ +# Version Constant +vhdl work "_PROJ_DIR_/Version.vhd" + +# PGP + +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpVersion.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpAckRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellRx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCellTx.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpMgtWrap.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPhy.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRxTrack.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTxSched.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpTop.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpClkGen.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpCmdSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpRegSlave.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpPicRemBuff.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDataBuffer.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpFrontEnd.vhd" +vhdl work "_PROJ_DIR_/../../modules/pgp/hdl/PgpDsBuff.vhd" + +# Pixel core +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayCharacters.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/DisplayControl.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock160.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/clock200.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/syncdatac.vhd" +vhdl work "_PROJ_DIR_/../../modules/pixelcore/hdl/phaseshift.vhd" + + +# Local Files +vhdl work "_PROJ_DIR_/hdl/serbiphase.vhd" +vhdl work "_PROJ_DIR_/hdl/deser16.vhd" +vhdl work "_PROJ_DIR_/hdl/pattern_mem.vhd" +vhdl work "_PROJ_DIR_/hdl/pattern_cmd.vhd" +vhdl work "_PROJ_DIR_/hdl/ser.vhd" +vhdl work "_PROJ_DIR_/hdl/deser.vhd" +vhdl work "_PROJ_DIR_/hdl/IBLcableTesterCore.vhd" +vhdl work "_PROJ_DIR_/hdl/IBLcableTester.vhd" diff --git a/rce/fw-hsio/projects/IBLcableTester/config/trce_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/trce_options.txt new file mode 100755 index 0000000000000000000000000000000000000000..2656ff46d3ef8bf070390954affed019ee28ca82 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/trce_options.txt @@ -0,0 +1,7 @@ +##----------------------------------------------------------------------------- +## Title : Xilinx trace options file +##----------------------------------------------------------------------------- +-intstyle silent +-l 30 +-v 30 +-tsi DpmTest.tsi diff --git a/rce/fw-hsio/projects/IBLcableTester/config/xst_options.txt b/rce/fw-hsio/projects/IBLcableTester/config/xst_options.txt new file mode 100644 index 0000000000000000000000000000000000000000..65969499a92eff3db486312259d700979ea110b0 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/config/xst_options.txt @@ -0,0 +1,50 @@ +run +-ofn IBLcableTester +-top IBLcableTester +-p XC4VFX60-11-FF1152 +-ifn "sources.txt" +-opt_mode Speed +-opt_level 2 +-power NO +-iuc NO +-keep_hierarchy No +-netlist_hierarchy As_Optimized +-rtlview Yes +-glob_opt AllClockNets +-write_timing_constraints No +-cross_clock_analysis NO +-hierarchy_separator / +-bus_delimiter <> +-case Maintain +-slice_utilization_ratio 100 +-bram_utilization_ratio 100 +-dsp_utilization_ratio 100 +-verilog2001 YES +-fsm_extract YES -fsm_encoding Auto +-safe_implementation No +-fsm_style LUT +-ram_extract Yes +-ram_style Auto +-rom_extract Yes +-mux_style Auto +-decoder_extract YES +-priority_extract Yes +-shreg_extract YES +-shift_extract YES +-xor_collapse YES +-resource_sharing Yes +-use_dsp48 Auto +-async_to_sync No +-iobuf Yes +-max_fanout 100000 +-bufg 32 +-register_duplication YES +-equivalent_register_removal Yes +-register_balancing No +-iob Auto +-slice_packing YES +-use_clock_enable Auto +-use_sync_set Auto +-use_sync_reset Auto +-optimize_primitives No + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/counter30.xco b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30.xco new file mode 100644 index 0000000000000000000000000000000000000000..68de958da465fb1ee4e93d38aec0d8a9f07be460 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30.xco @@ -0,0 +1,64 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Wed Sep 9 21:20:06 2009 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Binary_Counter family Xilinx,_Inc. 8.0 +# END Select +# BEGIN Parameters +CSET aclr=true +CSET ainit=false +CSET ainit_value=0 +CSET aset=false +CSET async_threshold_output=false +CSET ce=true +CSET component_name=counter30 +CSET count_mode=UP +CSET cycle_early_threshold_output=false +CSET final_count_value=1 +CSET increment_value=1 +CSET load=false +CSET load_ce_priority=CE_Overrides_Load +CSET output_width=30 +CSET restrict_count=false +CSET sclr=false +CSET sinit=false +CSET sinit_value=0 +CSET sset=false +CSET sync_ce_priority=Sync_Overrides_CE +CSET sync_threshold_output=true +CSET syncctrlpriority=Reset_Overrides_Set +CSET threshold_value=3ffffffe +# END Parameters +GENERATE +# CRC: d766a50a + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_c_counter_binary_v8_0_xst_1.ngc_xst.xrpt b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_c_counter_binary_v8_0_xst_1.ngc_xst.xrpt new file mode 100644 index 0000000000000000000000000000000000000000..853123257e8c342441e6972137947643aac87432 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_c_counter_binary_v8_0_xst_1.ngc_xst.xrpt @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<document OS="lin" product="ISE" version="10.1.03"> + + <!--The data in this file is primarily intended for consumption by Xilinx tools. + The structure and the elements are likely to change over the next few releases. + This means code written to parse this file will need to be revisited each subsequent release.--> + + <application stringID="Xst" timeStamp="Wed Sep 9 14:19:27 2009"> + <section stringID="XST_HDL_SYNTHESIS_REPORT"> + <item dataType="int" stringID="XST_REGISTERS" value="2"> + <item dataType="int" stringID="XST_1BIT_REGISTER" value="1"/> + <item dataType="int" stringID="XST_30BIT_REGISTER" value="1"/> + </item> + </section> + <section stringID="XST_ADVANCED_HDL_SYNTHESIS_REPORT"> + <item dataType="int" stringID="XST_REGISTERS" value="31"> + <item dataType="int" stringID="XST_FLIPFLOPS" value="31"/> + </item> + </section> + <section stringID="XST_FINAL_REGISTER_REPORT"> + <item dataType="int" stringID="XST_REGISTERS" value="31"> + <item dataType="int" stringID="XST_FLIPFLOPS" value="31"/> + </item> + </section> + <section stringID="XST_PARTITION_REPORT"> + <section stringID="XST_PARTITION_IMPLEMENTATION_STATUS"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + </section> + <section stringID="XST_FINAL_REPORT"> + <section stringID="XST_FINAL_RESULTS"> + <item stringID="XST_TOP_LEVEL_OUTPUT_FILE_NAME" value="/afs/slac/u/ec/kocian/minilat/xilinx/xil_cores/tmp/_cg/counter30_c_counter_binary_v8_0_xst_1.ngc"/> + <item stringID="XST_OUTPUT_FORMAT" value="NGC"/> + <item stringID="XST_OPTIMIZATION_GOAL" value="SPEED"/> + <item stringID="XST_KEEP_HIERARCHY" value="no"/> + </section> + <section stringID="XST_DESIGN_STATISTICS"> + <item stringID="XST_IOS" value="104"/> + </section> + <section stringID="XST_CELL_USAGE"> + <item dataType="int" stringID="XST_BELS" value="107"> + <item dataType="int" stringID="XST_GND" value="1"/> + <item dataType="int" stringID="XST_INV" value="1"/> + <item dataType="int" stringID="XST_LUT1" value="29"/> + <item dataType="int" stringID="XST_LUT2" value="1"/> + <item dataType="int" stringID="XST_LUT4" value="7"/> + <item dataType="int" stringID="XST_MUXCY" value="37"/> + <item dataType="int" stringID="XST_VCC" value="1"/> + <item dataType="int" stringID="XST_XORCY" value="30"/> + </item> + <item dataType="int" stringID="XST_FLIPFLOPSLATCHES" value="31"> + <item dataType="int" stringID="XST_FDCE" value="31"/> + </item> + </section> + </section> + <section stringID="XST_DEVICE_UTILIZATION_SUMMARY"> + <item stringID="XST_SELECTED_DEVICE" value="4vfx60ff672-12"/> + <item AVAILABLE="25280" dataType="int" stringID="XST_NUMBER_OF_SLICES" value="20"/> + <item AVAILABLE="50560" dataType="int" stringID="XST_NUMBER_OF_SLICE_FLIP_FLOPS" value="31"/> + <item AVAILABLE="50560" dataType="int" stringID="XST_NUMBER_OF_4_INPUT_LUTS" value="38"/> + <item dataType="int" stringID="XST_NUMBER_OF_IOS" value="104"/> + <item AVAILABLE="352" dataType="int" stringID="XST_NUMBER_OF_BONDED_IOBS" value="0"/> + </section> + <section stringID="XST_PARTITION_RESOURCE_SUMMARY"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + <section stringID="XST_ERRORS_STATISTICS"> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_ERRORS" value="0"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_WARNINGS" value="87"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_INFOS" value="2"/> + </section> + </application> + +</document> diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_xmdf.tcl b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_xmdf.tcl new file mode 100644 index 0000000000000000000000000000000000000000..3717db15186ed02b97e2c66e4837119ed89dc2c9 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/counter30_xmdf.tcl @@ -0,0 +1,68 @@ +# The package naming convention is <core_name>_xmdf +package provide counter30_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::counter30_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::counter30_xmdf::xmdfInit { instance } { +# Variable containg name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name counter30 +} +# ::counter30_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::counter30_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be magically +# available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30.vhd +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30.vho +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30_c_counter_binary_v8_0_xst_1.ngc_xst.xrpt +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path counter30_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module counter30 +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo.xco b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo.xco new file mode 100644 index 0000000000000000000000000000000000000000..0d9adf03aa6bc32aa605bf825529e51c90a5a476 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo.xco @@ -0,0 +1,217 @@ +############################################################## +# +# Xilinx Core Generator version 13.2 +# Date: Thu Oct 6 00:36:33 2011 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# Generated from component: xilinx.com:ip:fifo_generator:8.2 +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = false +SET vhdlsim = true +# END Project Options +# BEGIN Select +SELECT Fifo_Generator xilinx.com:ip:fifo_generator:8.2 +# END Select +# BEGIN Parameters +CSET add_ngc_constraint_axi=false +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET aruser_width=1 +CSET awuser_width=1 +CSET axi_address_width=32 +CSET axi_data_width=64 +CSET axi_type=AXI4_Stream +CSET axis_type=FIFO +CSET buser_width=1 +CSET clock_enable_type=Slave_Interface_Clock_Enable +CSET clock_type_axi=Common_Clock +CSET component_name=iblfifo +CSET data_count=false +CSET data_count_width=9 +CSET disable_timing_violations=false +CSET disable_timing_violations_axi=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=19 +CSET empty_threshold_assert_value_axis=1022 +CSET empty_threshold_assert_value_rach=1022 +CSET empty_threshold_assert_value_rdch=1022 +CSET empty_threshold_assert_value_wach=1022 +CSET empty_threshold_assert_value_wdch=1022 +CSET empty_threshold_assert_value_wrch=1022 +CSET empty_threshold_negate_value=20 +CSET enable_aruser=false +CSET enable_awuser=false +CSET enable_buser=false +CSET enable_common_overflow=false +CSET enable_common_underflow=false +CSET enable_data_counts_axis=false +CSET enable_data_counts_rach=false +CSET enable_data_counts_rdch=false +CSET enable_data_counts_wach=false +CSET enable_data_counts_wdch=false +CSET enable_data_counts_wrch=false +CSET enable_ecc=false +CSET enable_ecc_axis=false +CSET enable_ecc_rach=false +CSET enable_ecc_rdch=false +CSET enable_ecc_wach=false +CSET enable_ecc_wdch=false +CSET enable_ecc_wrch=false +CSET enable_handshake_flag_options_axis=false +CSET enable_handshake_flag_options_rach=false +CSET enable_handshake_flag_options_rdch=false +CSET enable_handshake_flag_options_wach=false +CSET enable_handshake_flag_options_wdch=false +CSET enable_handshake_flag_options_wrch=false +CSET enable_read_channel=false +CSET enable_read_pointer_increment_by2=false +CSET enable_reset_synchronization=true +CSET enable_ruser=false +CSET enable_tdata=false +CSET enable_tdest=false +CSET enable_tid=false +CSET enable_tkeep=false +CSET enable_tlast=false +CSET enable_tready=true +CSET enable_tstrobe=false +CSET enable_tuser=false +CSET enable_write_channel=false +CSET enable_wuser=false +CSET fifo_application_type_axis=Data_FIFO +CSET fifo_application_type_rach=Data_FIFO +CSET fifo_application_type_rdch=Data_FIFO +CSET fifo_application_type_wach=Data_FIFO +CSET fifo_application_type_wdch=Data_FIFO +CSET fifo_application_type_wrch=Data_FIFO +CSET fifo_implementation=Independent_Clocks_Builtin_FIFO +CSET fifo_implementation_axis=Common_Clock_Block_RAM +CSET fifo_implementation_rach=Common_Clock_Block_RAM +CSET fifo_implementation_rdch=Common_Clock_Block_RAM +CSET fifo_implementation_wach=Common_Clock_Block_RAM +CSET fifo_implementation_wdch=Common_Clock_Block_RAM +CSET fifo_implementation_wrch=Common_Clock_Block_RAM +CSET full_flags_reset_value=0 +CSET full_threshold_assert_value=523 +CSET full_threshold_assert_value_axis=1023 +CSET full_threshold_assert_value_rach=1023 +CSET full_threshold_assert_value_rdch=1023 +CSET full_threshold_assert_value_wach=1023 +CSET full_threshold_assert_value_wdch=1023 +CSET full_threshold_assert_value_wrch=1023 +CSET full_threshold_negate_value=522 +CSET id_width=4 +CSET inject_dbit_error=false +CSET inject_dbit_error_axis=false +CSET inject_dbit_error_rach=false +CSET inject_dbit_error_rdch=false +CSET inject_dbit_error_wach=false +CSET inject_dbit_error_wdch=false +CSET inject_dbit_error_wrch=false +CSET inject_sbit_error=false +CSET inject_sbit_error_axis=false +CSET inject_sbit_error_rach=false +CSET inject_sbit_error_rdch=false +CSET inject_sbit_error_wach=false +CSET inject_sbit_error_wdch=false +CSET inject_sbit_error_wrch=false +CSET input_data_width=36 +CSET input_depth=512 +CSET input_depth_axis=1024 +CSET input_depth_rach=16 +CSET input_depth_rdch=1024 +CSET input_depth_wach=16 +CSET input_depth_wdch=1024 +CSET input_depth_wrch=16 +CSET interface_type=Native +CSET output_data_width=36 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_flag_axi=false +CSET overflow_sense=Active_High +CSET overflow_sense_axi=Active_High +CSET performance_options=Standard_FIFO +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_empty_type_axis=Empty +CSET programmable_empty_type_rach=Empty +CSET programmable_empty_type_rdch=Empty +CSET programmable_empty_type_wach=Empty +CSET programmable_empty_type_wdch=Empty +CSET programmable_empty_type_wrch=Empty +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET programmable_full_type_axis=Full +CSET programmable_full_type_rach=Full +CSET programmable_full_type_rdch=Full +CSET programmable_full_type_wach=Full +CSET programmable_full_type_wdch=Full +CSET programmable_full_type_wrch=Full +CSET rach_type=FIFO +CSET rdch_type=FIFO +CSET read_clock_frequency=160 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET register_slice_mode_axis=Fully_Registered +CSET register_slice_mode_rach=Fully_Registered +CSET register_slice_mode_rdch=Fully_Registered +CSET register_slice_mode_wach=Fully_Registered +CSET register_slice_mode_wdch=Fully_Registered +CSET register_slice_mode_wrch=Fully_Registered +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET ruser_width=1 +CSET tdata_width=64 +CSET tdest_width=4 +CSET tid_width=8 +CSET tkeep_width=4 +CSET tstrb_width=4 +CSET tuser_width=4 +CSET underflow_flag=false +CSET underflow_flag_axi=false +CSET underflow_sense=Active_High +CSET underflow_sense_axi=Active_High +CSET use_clock_enable=false +CSET use_dout_reset=false +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET wach_type=FIFO +CSET wdch_type=FIFO +CSET wrch_type=FIFO +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=160 +CSET write_data_count=false +CSET write_data_count_width=9 +CSET wuser_width=1 +# END Parameters +# BEGIN Extra information +MISC pkg_timestamp=2011-03-14T07:12:32.000Z +# END Extra information +GENERATE +# CRC: 1619f87d diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_fifo_generator_v4_4_xst_1.ngc_xst.xrpt b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_fifo_generator_v4_4_xst_1.ngc_xst.xrpt new file mode 100644 index 0000000000000000000000000000000000000000..cedd25e872d1c30286264daf1eb6666a27fc1f31 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_fifo_generator_v4_4_xst_1.ngc_xst.xrpt @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<document OS="lin" product="ISE" version="10.1.03"> + + <!--The data in this file is primarily intended for consumption by Xilinx tools. + The structure and the elements are likely to change over the next few releases. + This means code written to parse this file will need to be revisited each subsequent release.--> + + <application stringID="Xst" timeStamp="Sat Aug 22 13:49:02 2009"> + <section stringID="XST_HDL_SYNTHESIS_REPORT"> + <item dataType="int" stringID="XST_RAMS" value="1"></item> + <item dataType="int" stringID="XST_COUNTERS" value="2"> + <item dataType="int" stringID="XST_4BIT_UP_COUNTER" value="2"/> + </item> + <item dataType="int" stringID="XST_REGISTERS" value="38"> + <item dataType="int" stringID="XST_1BIT_REGISTER" value="23"/> + <item dataType="int" stringID="XST_2BIT_REGISTER" value="1"/> + <item dataType="int" stringID="XST_3BIT_REGISTER" value="1"/> + <item dataType="int" stringID="XST_36BIT_REGISTER" value="1"/> + <item dataType="int" stringID="XST_4BIT_REGISTER" value="12"/> + </item> + <item dataType="int" stringID="XST_XORS" value="32"> + <item dataType="int" stringID="XST_1BIT_XOR2" value="32"/> + </item> + </section> + <section stringID="XST_ADVANCED_HDL_SYNTHESIS_REPORT"> + <item dataType="int" stringID="XST_RAMS" value="1"></item> + <item dataType="int" stringID="XST_COUNTERS" value="2"> + <item dataType="int" stringID="XST_4BIT_UP_COUNTER" value="2"/> + </item> + <item dataType="int" stringID="XST_REGISTERS" value="112"> + <item dataType="int" stringID="XST_FLIPFLOPS" value="112"/> + </item> + <item dataType="int" stringID="XST_XORS" value="32"> + <item dataType="int" stringID="XST_1BIT_XOR2" value="32"/> + </item> + </section> + <section stringID="XST_FINAL_REGISTER_REPORT"> + <item dataType="int" stringID="XST_REGISTERS" value="115"> + <item dataType="int" stringID="XST_FLIPFLOPS" value="115"/> + </item> + </section> + <section stringID="XST_PARTITION_REPORT"> + <section stringID="XST_PARTITION_IMPLEMENTATION_STATUS"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + </section> + <section stringID="XST_FINAL_REPORT"> + <section stringID="XST_FINAL_RESULTS"> + <item stringID="XST_TOP_LEVEL_OUTPUT_FILE_NAME" value="/afs/slac/u/ec/kocian/minilat/xilinx/BnlAsic/xil_cores/tmp/_cg/iblfifo_fifo_generator_v4_4_xst_1.ngc"/> + <item stringID="XST_OUTPUT_FORMAT" value="NGC"/> + <item stringID="XST_OPTIMIZATION_GOAL" value="SPEED"/> + <item stringID="XST_KEEP_HIERARCHY" value="no"/> + </section> + <section stringID="XST_DESIGN_STATISTICS"> + <item stringID="XST_IOS" value="177"/> + </section> + <section stringID="XST_CELL_USAGE"> + <item dataType="int" stringID="XST_BELS" value="51"> + <item dataType="int" stringID="XST_GND" value="1"/> + <item dataType="int" stringID="XST_INV" value="3"/> + <item dataType="int" stringID="XST_LUT2" value="22"/> + <item dataType="int" stringID="XST_LUT3" value="5"/> + <item dataType="int" stringID="XST_LUT3L" value="1"/> + <item dataType="int" stringID="XST_LUT4" value="16"/> + <item dataType="int" stringID="XST_LUT4D" value="1"/> + <item dataType="int" stringID="XST_LUT4L" value="2"/> + </item> + <item dataType="int" stringID="XST_FLIPFLOPSLATCHES" value="115"> + <item dataType="int" stringID="XST_FD" value="4"/> + <item dataType="int" stringID="XST_FDC" value="35"/> + <item dataType="int" stringID="XST_FDCE" value="19"/> + <item dataType="int" stringID="XST_FDE" value="36"/> + <item dataType="int" stringID="XST_FDP" value="11"/> + <item dataType="int" stringID="XST_FDPE" value="10"/> + </item> + <item dataType="int" stringID="XST_RAMS" value="37"> + <item dataType="int" stringID="XST_RAM16X1D" value="36"/> + </item> + </section> + </section> + <section stringID="XST_DEVICE_UTILIZATION_SUMMARY"> + <item stringID="XST_SELECTED_DEVICE" value="4vfx60ff672-12"/> + <item AVAILABLE="25280" dataType="int" stringID="XST_NUMBER_OF_SLICES" value="123"/> + <item AVAILABLE="50560" dataType="int" stringID="XST_NUMBER_OF_SLICE_FLIP_FLOPS" value="115"/> + <item AVAILABLE="50560" dataType="int" stringID="XST_NUMBER_OF_4_INPUT_LUTS" value="122"/> + <item dataType="int" stringID="XST_NUMBER_USED_AS_LOGIC" value="50"/> + <item dataType="int" stringID="XST_NUMBER_USED_AS_RAMS" value="72"/> + <item dataType="int" stringID="XST_NUMBER_OF_IOS" value="177"/> + <item AVAILABLE="352" dataType="int" stringID="XST_NUMBER_OF_BONDED_IOBS" value="0"/> + </section> + <section stringID="XST_PARTITION_RESOURCE_SUMMARY"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + <section stringID="XST_ERRORS_STATISTICS"> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_ERRORS" value="0"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_WARNINGS" value="158"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_INFOS" value="5"/> + </section> + </application> + +</document> diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.ucf b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.ucf new file mode 100755 index 0000000000000000000000000000000000000000..33471d1c2871c9442277e1caff6444efd1a44df6 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.ucf @@ -0,0 +1,59 @@ +################################################################################ +# (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +# +# This file contains confidential and proprietary information +# of Xilinx, Inc. and is protected under U.S. and +# international copyright and other intellectual property +# laws. +# +# DISCLAIMER +# This disclaimer is not a license and does not grant any +# rights to the materials distributed herewith. Except as +# otherwise provided in a valid license issued to you by +# Xilinx, and to the maximum extent permitted by applicable +# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +# (2) Xilinx shall not be liable (whether in contract or tort, +# including negligence, or under any other theory of +# liability) for any loss or damage of any kind or nature +# related to, arising under or in connection with these +# materials, including for any direct, or any indirect, +# special, incidental, or consequential loss or damage +# (including loss of data, profits, goodwill, or any type of +# loss or damage suffered as a result of any action brought +# by a third party) even if such damage or loss was +# reasonably foreseeable or Xilinx had been advised of the +# possibility of the same. +# +# CRITICAL APPLICATIONS +# Xilinx products are not designed or intended to be fail- +# safe, or for use in any application requiring fail-safe +# performance, such as life-support or safety devices or +# systems, Class III medical devices, nuclear facilities, +# applications related to the deployment of airbags, or any +# other applications that could lead to death, personal +# injury, or severe property or environmental damage +# (individually and collectively, "Critical +# Applications"). Customer assumes the sole risk and +# liability of any use of Xilinx products in Critical +# Applications, subject only to applicable laws and +# regulations governing limitations on product liability. +# +# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +# PART OF THIS FILE AT ALL TIMES. +# +################################################################################ + +# Core Period Constraint. This constraint can be modified, and is +# valid as long as it is met after place and route. + NET "RD_CLK" TNM_NET = "RD_CLK"; + NET "WR_CLK" TNM_NET = "WR_CLK"; + TIMESPEC "TS_RD_CLK" = PERIOD "RD_CLK" 50 MHZ; + TIMESPEC "TS_WR_CLK" = PERIOD "WR_CLK" 50 MHZ; + + + +################################################################################ diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.vhd b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.vhd new file mode 100755 index 0000000000000000000000000000000000000000..3062b60e082a1c602e3c535f936920ea24f9a01e --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.vhd @@ -0,0 +1,358 @@ +-------------------------------------------------------------------------------- +-- +-- FIFO Generator v8.2 Core - Top-level core wrapper +-- +-------------------------------------------------------------------------------- +-- +-- (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +-- +-- This file contains confidential and proprietary information +-- of Xilinx, Inc. and is protected under U.S. and +-- international copyright and other intellectual property +-- laws. +-- +-- DISCLAIMER +-- This disclaimer is not a license and does not grant any +-- rights to the materials distributed herewith. Except as +-- otherwise provided in a valid license issued to you by +-- Xilinx, and to the maximum extent permitted by applicable +-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +-- (2) Xilinx shall not be liable (whether in contract or tort, +-- including negligence, or under any other theory of +-- liability) for any loss or damage of any kind or nature +-- related to, arising under or in connection with these +-- materials, including for any direct, or any indirect, +-- special, incidental, or consequential loss or damage +-- (including loss of data, profits, goodwill, or any type of +-- loss or damage suffered as a result of any action brought +-- by a third party) even if such damage or loss was +-- reasonably foreseeable or Xilinx had been advised of the +-- possibility of the same. +-- +-- CRITICAL APPLICATIONS +-- Xilinx products are not designed or intended to be fail- +-- safe, or for use in any application requiring fail-safe +-- performance, such as life-support or safety devices or +-- systems, Class III medical devices, nuclear facilities, +-- applications related to the deployment of airbags, or any +-- other applications that could lead to death, personal +-- injury, or severe property or environmental damage +-- (individually and collectively, "Critical +-- Applications"). Customer assumes the sole risk and +-- liability of any use of Xilinx products in Critical +-- Applications, subject only to applicable laws and +-- regulations governing limitations on product liability. +-- +-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +-- PART OF THIS FILE AT ALL TIMES. +-------------------------------------------------------------------------------- +-- +-- Filename: <componenet name>_top.vhd +-- +-- Description: +-- This is the actual FIFO core wrapper. +-- +-------------------------------------------------------------------------------- +-- Library Declarations +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library unisim; +use unisim.vcomponents.all; + +-------------------------------------------------------------------------------- +-- Entity Declaration +-------------------------------------------------------------------------------- +entity iblfifo_top is + PORT ( + CLK : IN STD_LOGIC; + BACKUP : IN STD_LOGIC; + BACKUP_MARKER : IN STD_LOGIC; + DIN : IN STD_LOGIC_VECTOR(36-1 downto 0); + PROG_EMPTY_THRESH : IN STD_LOGIC_VECTOR(9-1 downto 0); + PROG_EMPTY_THRESH_ASSERT : IN STD_LOGIC_VECTOR(9-1 downto 0); + PROG_EMPTY_THRESH_NEGATE : IN STD_LOGIC_VECTOR(9-1 downto 0); + PROG_FULL_THRESH : IN STD_LOGIC_VECTOR(9-1 downto 0); + PROG_FULL_THRESH_ASSERT : IN STD_LOGIC_VECTOR(9-1 downto 0); + PROG_FULL_THRESH_NEGATE : IN STD_LOGIC_VECTOR(9-1 downto 0); + RD_CLK : IN STD_LOGIC; + RD_EN : IN STD_LOGIC; + RD_RST : IN STD_LOGIC; + RST : IN STD_LOGIC; + SRST : IN STD_LOGIC; + WR_CLK : IN STD_LOGIC; + WR_EN : IN STD_LOGIC; + WR_RST : IN STD_LOGIC; + INJECTDBITERR : IN STD_LOGIC; + INJECTSBITERR : IN STD_LOGIC; + ALMOST_EMPTY : OUT STD_LOGIC; + ALMOST_FULL : OUT STD_LOGIC; + DATA_COUNT : OUT STD_LOGIC_VECTOR(9-1 downto 0); + DOUT : OUT STD_LOGIC_VECTOR(36-1 downto 0); + EMPTY : OUT STD_LOGIC; + FULL : OUT STD_LOGIC; + OVERFLOW : OUT STD_LOGIC; + PROG_EMPTY : OUT STD_LOGIC; + PROG_FULL : OUT STD_LOGIC; + VALID : OUT STD_LOGIC; + RD_DATA_COUNT : OUT STD_LOGIC_VECTOR(9-1 downto 0); + UNDERFLOW : OUT STD_LOGIC; + WR_ACK : OUT STD_LOGIC; + WR_DATA_COUNT : OUT STD_LOGIC_VECTOR(9-1 downto 0); + SBITERR : OUT STD_LOGIC; + DBITERR : OUT STD_LOGIC; + -- AXI Global Signal + M_ACLK : IN std_logic; + S_ACLK : IN std_logic; + S_ARESETN : IN std_logic; + M_ACLK_EN : IN std_logic; + S_ACLK_EN : IN std_logic; + -- AXI Full/Lite Slave Write Channel (write side) + S_AXI_AWID : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_AWADDR : IN std_logic_vector(32-1 DOWNTO 0); + S_AXI_AWLEN : IN std_logic_vector(8-1 DOWNTO 0); + S_AXI_AWSIZE : IN std_logic_vector(3-1 DOWNTO 0); + S_AXI_AWBURST : IN std_logic_vector(2-1 DOWNTO 0); + S_AXI_AWLOCK : IN std_logic_vector(2-1 DOWNTO 0); + S_AXI_AWCACHE : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_AWPROT : IN std_logic_vector(3-1 DOWNTO 0); + S_AXI_AWQOS : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_AWREGION : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_AWUSER : IN std_logic_vector(1-1 DOWNTO 0); + S_AXI_AWVALID : IN std_logic; + S_AXI_AWREADY : OUT std_logic; + S_AXI_WID : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_WDATA : IN std_logic_vector(64-1 DOWNTO 0); + S_AXI_WSTRB : IN std_logic_vector(8-1 DOWNTO 0); + S_AXI_WLAST : IN std_logic; + S_AXI_WUSER : IN std_logic_vector(1-1 DOWNTO 0); + S_AXI_WVALID : IN std_logic; + S_AXI_WREADY : OUT std_logic; + S_AXI_BID : OUT std_logic_vector(4-1 DOWNTO 0); + S_AXI_BRESP : OUT std_logic_vector(2-1 DOWNTO 0); + S_AXI_BUSER : OUT std_logic_vector(1-1 DOWNTO 0); + S_AXI_BVALID : OUT std_logic; + S_AXI_BREADY : IN std_logic; + -- AXI Full/Lite Master Write Channel (Read side) + M_AXI_AWID : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_AWADDR : OUT std_logic_vector(32-1 DOWNTO 0); + M_AXI_AWLEN : OUT std_logic_vector(8-1 DOWNTO 0); + M_AXI_AWSIZE : OUT std_logic_vector(3-1 DOWNTO 0); + M_AXI_AWBURST : OUT std_logic_vector(2-1 DOWNTO 0); + M_AXI_AWLOCK : OUT std_logic_vector(2-1 DOWNTO 0); + M_AXI_AWCACHE : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_AWPROT : OUT std_logic_vector(3-1 DOWNTO 0); + M_AXI_AWQOS : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_AWREGION : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_AWUSER : OUT std_logic_vector(1-1 DOWNTO 0); + M_AXI_AWVALID : OUT std_logic; + M_AXI_AWREADY : IN std_logic; + M_AXI_WID : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_WDATA : OUT std_logic_vector(64-1 DOWNTO 0); + M_AXI_WSTRB : OUT std_logic_vector(8-1 DOWNTO 0); + M_AXI_WLAST : OUT std_logic; + M_AXI_WUSER : OUT std_logic_vector(1-1 DOWNTO 0); + M_AXI_WVALID : OUT std_logic; + M_AXI_WREADY : IN std_logic; + M_AXI_BID : IN std_logic_vector(4-1 DOWNTO 0); + M_AXI_BRESP : IN std_logic_vector(2-1 DOWNTO 0); + M_AXI_BUSER : IN std_logic_vector(1-1 DOWNTO 0); + M_AXI_BVALID : IN std_logic; + M_AXI_BREADY : OUT std_logic; + -- AXI Full/Lite Slave Read Channel (Write side) + S_AXI_ARID : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_ARADDR : IN std_logic_vector(32-1 DOWNTO 0); + S_AXI_ARLEN : IN std_logic_vector(8-1 DOWNTO 0); + S_AXI_ARSIZE : IN std_logic_vector(3-1 DOWNTO 0); + S_AXI_ARBURST : IN std_logic_vector(2-1 DOWNTO 0); + S_AXI_ARLOCK : IN std_logic_vector(2-1 DOWNTO 0); + S_AXI_ARCACHE : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_ARPROT : IN std_logic_vector(3-1 DOWNTO 0); + S_AXI_ARQOS : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_ARREGION : IN std_logic_vector(4-1 DOWNTO 0); + S_AXI_ARUSER : IN std_logic_vector(1-1 DOWNTO 0); + S_AXI_ARVALID : IN std_logic; + S_AXI_ARREADY : OUT std_logic; + S_AXI_RID : OUT std_logic_vector(4-1 DOWNTO 0); + S_AXI_RDATA : OUT std_logic_vector(64-1 DOWNTO 0); + S_AXI_RRESP : OUT std_logic_vector(2-1 DOWNTO 0); + S_AXI_RLAST : OUT std_logic; + S_AXI_RUSER : OUT std_logic_vector(1-1 DOWNTO 0); + S_AXI_RVALID : OUT std_logic; + S_AXI_RREADY : IN std_logic; + -- AXI Full/Lite Master Read Channel (Read side) + M_AXI_ARID : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_ARADDR : OUT std_logic_vector(32-1 DOWNTO 0); + M_AXI_ARLEN : OUT std_logic_vector(8-1 DOWNTO 0); + M_AXI_ARSIZE : OUT std_logic_vector(3-1 DOWNTO 0); + M_AXI_ARBURST : OUT std_logic_vector(2-1 DOWNTO 0); + M_AXI_ARLOCK : OUT std_logic_vector(2-1 DOWNTO 0); + M_AXI_ARCACHE : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_ARPROT : OUT std_logic_vector(3-1 DOWNTO 0); + M_AXI_ARQOS : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_ARREGION : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXI_ARUSER : OUT std_logic_vector(1-1 DOWNTO 0); + M_AXI_ARVALID : OUT std_logic; + M_AXI_ARREADY : IN std_logic; + M_AXI_RID : IN std_logic_vector(4-1 DOWNTO 0); + M_AXI_RDATA : IN std_logic_vector(64-1 DOWNTO 0); + M_AXI_RRESP : IN std_logic_vector(2-1 DOWNTO 0); + M_AXI_RLAST : IN std_logic; + M_AXI_RUSER : IN std_logic_vector(1-1 DOWNTO 0); + M_AXI_RVALID : IN std_logic; + M_AXI_RREADY : OUT std_logic; + -- AXI Streaming Slave Signals (Write side) + S_AXIS_TVALID : IN std_logic; + S_AXIS_TREADY : OUT std_logic; + S_AXIS_TDATA : IN std_logic_vector(64-1 DOWNTO 0); + S_AXIS_TSTRB : IN std_logic_vector(4-1 DOWNTO 0); + S_AXIS_TKEEP : IN std_logic_vector(4-1 DOWNTO 0); + S_AXIS_TLAST : IN std_logic; + S_AXIS_TID : IN std_logic_vector(8-1 DOWNTO 0); + S_AXIS_TDEST : IN std_logic_vector(4-1 DOWNTO 0); + S_AXIS_TUSER : IN std_logic_vector(4-1 DOWNTO 0); + -- AXI Streaming Master Signals (Read side) + M_AXIS_TVALID : OUT std_logic; + M_AXIS_TREADY : IN std_logic; + M_AXIS_TDATA : OUT std_logic_vector(64-1 DOWNTO 0); + M_AXIS_TSTRB : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXIS_TKEEP : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXIS_TLAST : OUT std_logic; + M_AXIS_TID : OUT std_logic_vector(8-1 DOWNTO 0); + M_AXIS_TDEST : OUT std_logic_vector(4-1 DOWNTO 0); + M_AXIS_TUSER : OUT std_logic_vector(4-1 DOWNTO 0); + -- AXI Full/Lite Write Address Channel Signals + AXI_AW_INJECTSBITERR : IN std_logic; + AXI_AW_INJECTDBITERR : IN std_logic; + AXI_AW_PROG_FULL_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_AW_PROG_EMPTY_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_AW_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AW_WR_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AW_RD_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AW_SBITERR : OUT std_logic; + AXI_AW_DBITERR : OUT std_logic; + AXI_AW_OVERFLOW : OUT std_logic; + AXI_AW_UNDERFLOW : OUT std_logic; + -- AXI Full/Lite Write Data Channel Signals + AXI_W_INJECTSBITERR : IN std_logic; + AXI_W_INJECTDBITERR : IN std_logic; + AXI_W_PROG_FULL_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXI_W_PROG_EMPTY_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXI_W_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_W_WR_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_W_RD_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_W_SBITERR : OUT std_logic; + AXI_W_DBITERR : OUT std_logic; + AXI_W_OVERFLOW : OUT std_logic; + AXI_W_UNDERFLOW : OUT std_logic; + -- AXI Full/Lite Write Response Channel Signals + AXI_B_INJECTSBITERR : IN std_logic; + AXI_B_INJECTDBITERR : IN std_logic; + AXI_B_PROG_FULL_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_B_PROG_EMPTY_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_B_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_B_WR_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_B_RD_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_B_SBITERR : OUT std_logic; + AXI_B_DBITERR : OUT std_logic; + AXI_B_OVERFLOW : OUT std_logic; + AXI_B_UNDERFLOW : OUT std_logic; + -- AXI Full/Lite Read Address Channel Signals + AXI_AR_INJECTSBITERR : IN std_logic; + AXI_AR_INJECTDBITERR : IN std_logic; + AXI_AR_PROG_FULL_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_AR_PROG_EMPTY_THRESH : IN std_logic_vector(4-1 DOWNTO 0); + AXI_AR_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AR_WR_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AR_RD_DATA_COUNT : OUT std_logic_vector(4 DOWNTO 0); + AXI_AR_SBITERR : OUT std_logic; + AXI_AR_DBITERR : OUT std_logic; + AXI_AR_OVERFLOW : OUT std_logic; + AXI_AR_UNDERFLOW : OUT std_logic; + -- AXI Full/Lite Read Data Channel Signals + AXI_R_INJECTSBITERR : IN std_logic; + AXI_R_INJECTDBITERR : IN std_logic; + AXI_R_PROG_FULL_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXI_R_PROG_EMPTY_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXI_R_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_R_WR_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_R_RD_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXI_R_SBITERR : OUT std_logic; + AXI_R_DBITERR : OUT std_logic; + AXI_R_OVERFLOW : OUT std_logic; + AXI_R_UNDERFLOW : OUT std_logic; + -- AXI Streaming FIFO Related Signals + AXIS_INJECTSBITERR : IN std_logic; + AXIS_INJECTDBITERR : IN std_logic; + AXIS_PROG_FULL_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXIS_PROG_EMPTY_THRESH : IN std_logic_vector(10-1 DOWNTO 0); + AXIS_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXIS_WR_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXIS_RD_DATA_COUNT : OUT std_logic_vector(10 DOWNTO 0); + AXIS_SBITERR : OUT std_logic; + AXIS_DBITERR : OUT std_logic; + AXIS_OVERFLOW : OUT std_logic; + AXIS_UNDERFLOW : OUT std_logic); + +end iblfifo_top; + + + +architecture xilinx of iblfifo_top is + + SIGNAL WR_CLK_i : std_logic; + SIGNAL RD_CLK_i : std_logic; + + + + component iblfifo is + PORT ( + WR_CLK : IN std_logic; + RD_CLK : IN std_logic; + RST : IN std_logic; + WR_EN : IN std_logic; + RD_EN : IN std_logic; + DIN : IN std_logic_vector(36-1 DOWNTO 0); + DOUT : OUT std_logic_vector(36-1 DOWNTO 0); + FULL : OUT std_logic; + EMPTY : OUT std_logic); + end component; + + +begin + + fg0 : iblfifo + port map ( + WR_CLK => WR_CLK_i, + RD_CLK => RD_CLK_i, + RST => RST, + WR_EN => WR_EN, + RD_EN => RD_EN, + DIN => DIN, + DOUT => DOUT, + FULL => FULL, + EMPTY => EMPTY); + + +wr_clk_buf: bufg + PORT map( + i => WR_CLK, + o => WR_CLK_i + ); + +rd_clk_buf: bufg + PORT map( + i => RD_CLK, + o => RD_CLK_i + ); + + +end xilinx; diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.xdc b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.xdc new file mode 100755 index 0000000000000000000000000000000000000000..d0bafcd390c6b5a7fb92675102e449d7872ba27d --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/example_design/iblfifo_top.xdc @@ -0,0 +1,57 @@ +################################################################################ +# (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +# +# This file contains confidential and proprietary information +# of Xilinx, Inc. and is protected under U.S. and +# international copyright and other intellectual property +# laws. +# +# DISCLAIMER +# This disclaimer is not a license and does not grant any +# rights to the materials distributed herewith. Except as +# otherwise provided in a valid license issued to you by +# Xilinx, and to the maximum extent permitted by applicable +# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +# (2) Xilinx shall not be liable (whether in contract or tort, +# including negligence, or under any other theory of +# liability) for any loss or damage of any kind or nature +# related to, arising under or in connection with these +# materials, including for any direct, or any indirect, +# special, incidental, or consequential loss or damage +# (including loss of data, profits, goodwill, or any type of +# loss or damage suffered as a result of any action brought +# by a third party) even if such damage or loss was +# reasonably foreseeable or Xilinx had been advised of the +# possibility of the same. +# +# CRITICAL APPLICATIONS +# Xilinx products are not designed or intended to be fail- +# safe, or for use in any application requiring fail-safe +# performance, such as life-support or safety devices or +# systems, Class III medical devices, nuclear facilities, +# applications related to the deployment of airbags, or any +# other applications that could lead to death, personal +# injury, or severe property or environmental damage +# (individually and collectively, "Critical +# Applications"). Customer assumes the sole risk and +# liability of any use of Xilinx products in Critical +# Applications, subject only to applicable laws and +# regulations governing limitations on product liability. +# +# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +# PART OF THIS FILE AT ALL TIMES. +# +################################################################################ + +# Core Period Constraint. This constraint can be modified, and is +# valid as long as it is met after place and route. +create_clock -name "TS_RD_CLK" -period 20.0 [ get_ports RD_CLK ] +create_clock -name "TS_WR_CLK" -period 20.0 [ get_ports WR_CLK ] + + + +################################################################################ diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.bat b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.bat new file mode 100755 index 0000000000000000000000000000000000000000..903e453bb64cb5c22693e3324b0f95ec1539d0bb --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.bat @@ -0,0 +1,88 @@ +rem (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +rem +rem This file contains confidential and proprietary information +rem of Xilinx, Inc. and is protected under U.S. and +rem international copyright and other intellectual property +rem laws. +rem +rem DISCLAIMER +rem This disclaimer is not a license and does not grant any +rem rights to the materials distributed herewith. Except as +rem otherwise provided in a valid license issued to you by +rem Xilinx, and to the maximum extent permitted by applicable +rem law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +rem WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +rem AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +rem BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +rem INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +rem (2) Xilinx shall not be liable (whether in contract or tort, +rem including negligence, or under any other theory of +rem liability) for any loss or damage of any kind or nature +rem related to, arising under or in connection with these +rem materials, including for any direct, or any indirect, +rem special, incidental, or consequential loss or damage +rem (including loss of data, profits, goodwill, or any type of +rem loss or damage suffered as a result of any action brought +rem by a third party) even if such damage or loss was +rem reasonably foreseeable or Xilinx had been advised of the +rem possibility of the same. +rem +rem CRITICAL APPLICATIONS +rem Xilinx products are not designed or intended to be fail- +rem safe, or for use in any application requiring fail-safe +rem performance, such as life-support or safety devices or +rem systems, Class III medical devices, nuclear facilities, +rem applications related to the deployment of airbags, or any +rem other applications that could lead to death, personal +rem injury, or severe property or environmental damage +rem (individually and collectively, "Critical +rem Applications"). Customer assumes the sole risk and +rem liability of any use of Xilinx products in Critical +rem Applications, subject only to applicable laws and +rem regulations governing limitations on product liability. +rem +rem THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +rem PART OF THIS FILE AT ALL TIMES. + +rem Clean up the results directory +rmdir /S /Q results +mkdir results + +rem Synthesize the VHDL Wrapper Files + +#Synthesize the Wrapper Files + +echo 'Synthesizing example design with XST'; +xst -ifn xst.scr +copy iblfifo_top.ngc .\results\ + + +rem Copy the netlist generated by Coregen +echo 'Copying files from the netlist directory to the results directory' +copy ..\..\iblfifo.ngc results\ + + +rem Copy the constraints files generated by Coregen +echo 'Copying files from constraints directory to results directory' +copy ..\example_design\iblfifo_top.ucf results\ + +cd results + +echo 'Running ngdbuild' + +ngdbuild -p xc4vlx200-ff1513-10 -sd ../../../ iblfifo_top + +echo 'Running map' +map iblfifo_top -o mapped.ncd + +echo 'Running par' +par mapped.ncd routed.ncd + +echo 'Running trce' +trce -e 10 routed.ncd mapped.pcf -o routed + +echo 'Running design through bitgen' +bitgen -w routed + +echo 'Running netgen to create gate level VHDL model' +netgen -ofmt vhdl -sim -tm iblfifo_top -pcf mapped.pcf -w routed.ncd routed.vhd diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.sh b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.sh new file mode 100755 index 0000000000000000000000000000000000000000..a4b86aafb0691de51bd866e9e48e4159b3c63423 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/implement.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +# +# This file contains confidential and proprietary information +# of Xilinx, Inc. and is protected under U.S. and +# international copyright and other intellectual property +# laws. +# +# DISCLAIMER +# This disclaimer is not a license and does not grant any +# rights to the materials distributed herewith. Except as +# otherwise provided in a valid license issued to you by +# Xilinx, and to the maximum extent permitted by applicable +# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +# (2) Xilinx shall not be liable (whether in contract or tort, +# including negligence, or under any other theory of +# liability) for any loss or damage of any kind or nature +# related to, arising under or in connection with these +# materials, including for any direct, or any indirect, +# special, incidental, or consequential loss or damage +# (including loss of data, profits, goodwill, or any type of +# loss or damage suffered as a result of any action brought +# by a third party) even if such damage or loss was +# reasonably foreseeable or Xilinx had been advised of the +# possibility of the same. +# +# CRITICAL APPLICATIONS +# Xilinx products are not designed or intended to be fail- +# safe, or for use in any application requiring fail-safe +# performance, such as life-support or safety devices or +# systems, Class III medical devices, nuclear facilities, +# applications related to the deployment of airbags, or any +# other applications that could lead to death, personal +# injury, or severe property or environmental damage +# (individually and collectively, "Critical +# Applications"). Customer assumes the sole risk and +# liability of any use of Xilinx products in Critical +# Applications, subject only to applicable laws and +# regulations governing limitations on product liability. +# +# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +# PART OF THIS FILE AT ALL TIMES. + +# Clean up the results directory +rm -rf results +mkdir results + +#Synthesize the Wrapper Files + +echo 'Synthesizing example design with XST'; +xst -ifn xst.scr +cp iblfifo_top.ngc ./results/ + + +# Copy the netlist generated by Coregen +echo 'Copying files from the netlist directory to the results directory' +cp ../../iblfifo.ngc results/ + +# Copy the constraints files generated by Coregen +echo 'Copying files from constraints directory to results directory' +cp ../example_design/iblfifo_top.ucf results/ + +cd results + +echo 'Running ngdbuild' + +ngdbuild -p xc4vlx200-ff1513-10 -sd ../../../ iblfifo_top + +echo 'Running map' +map iblfifo_top -o mapped.ncd + +echo 'Running par' +par mapped.ncd routed.ncd + +echo 'Running trce' +trce -e 10 routed.ncd mapped.pcf -o routed + +echo 'Running design through bitgen' +bitgen -w routed + +echo 'Running netgen to create gate level VHDL model' +netgen -ofmt vhdl -sim -tm iblfifo_top -pcf mapped.pcf -w routed.ncd routed.vhd + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.bat b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.bat new file mode 100755 index 0000000000000000000000000000000000000000..85210855e6bcc40bdf6b7f7381b8859ac432439b --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.bat @@ -0,0 +1,55 @@ +#!/bin/sh +rem (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +rem +rem This file contains confidential and proprietary information +rem of Xilinx, Inc. and is protected under U.S. and +rem international copyright and other intellectual property +rem laws. +rem +rem DISCLAIMER +rem This disclaimer is not a license and does not grant any +rem rights to the materials distributed herewith. Except as +rem otherwise provided in a valid license issued to you by +rem Xilinx, and to the maximum extent permitted by applicable +rem law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +rem WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +rem AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +rem BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +rem INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +rem (2) Xilinx shall not be liable (whether in contract or tort, +rem including negligence, or under any other theory of +rem liability) for any loss or damage of any kind or nature +rem related to, arising under or in connection with these +rem materials, including for any direct, or any indirect, +rem special, incidental, or consequential loss or damage +rem (including loss of data, profits, goodwill, or any type of +rem loss or damage suffered as a result of any action brought +rem by a third party) even if such damage or loss was +rem reasonably foreseeable or Xilinx had been advised of the +rem possibility of the same. +rem +rem CRITICAL APPLICATIONS +rem Xilinx products are not designed or intended to be fail- +rem safe, or for use in any application requiring fail-safe +rem performance, such as life-support or safety devices or +rem systems, Class III medical devices, nuclear facilities, +rem applications related to the deployment of airbags, or any +rem other applications that could lead to death, personal +rem injury, or severe property or environmental damage +rem (individually and collectively, "Critical +rem Applications"). Customer assumes the sole risk and +rem liability of any use of Xilinx products in Critical +rem Applications, subject only to applicable laws and +rem regulations governing limitations on product liability. +rem +rem THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +rem PART OF THIS FILE AT ALL TIMES. + +rem ----------------------------------------------------------------------------- +rem Script to synthesize and implement the Coregen FIFO Generator +rem ----------------------------------------------------------------------------- +rmdir /S /Q results +mkdir results +cd results +copy ..\..\..\tmp\iblfifo.edf . +planAhead -mode batch -source ..\planAhead_rdn.tcl diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.sh b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.sh new file mode 100755 index 0000000000000000000000000000000000000000..9c19db71251199577c812cccce194c1f3afe4153 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +# +# This file contains confidential and proprietary information +# of Xilinx, Inc. and is protected under U.S. and +# international copyright and other intellectual property +# laws. +# +# DISCLAIMER +# This disclaimer is not a license and does not grant any +# rights to the materials distributed herewith. Except as +# otherwise provided in a valid license issued to you by +# Xilinx, and to the maximum extent permitted by applicable +# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +# (2) Xilinx shall not be liable (whether in contract or tort, +# including negligence, or under any other theory of +# liability) for any loss or damage of any kind or nature +# related to, arising under or in connection with these +# materials, including for any direct, or any indirect, +# special, incidental, or consequential loss or damage +# (including loss of data, profits, goodwill, or any type of +# loss or damage suffered as a result of any action brought +# by a third party) even if such damage or loss was +# reasonably foreseeable or Xilinx had been advised of the +# possibility of the same. +# +# CRITICAL APPLICATIONS +# Xilinx products are not designed or intended to be fail- +# safe, or for use in any application requiring fail-safe +# performance, such as life-support or safety devices or +# systems, Class III medical devices, nuclear facilities, +# applications related to the deployment of airbags, or any +# other applications that could lead to death, personal +# injury, or severe property or environmental damage +# (individually and collectively, "Critical +# Applications"). Customer assumes the sole risk and +# liability of any use of Xilinx products in Critical +# Applications, subject only to applicable laws and +# regulations governing limitations on product liability. +# +# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +# PART OF THIS FILE AT ALL TIMES. + +#----------------------------------------------------------------------------- +# Script to synthesize and implement the Coregen FIFO Generator +#----------------------------------------------------------------------------- +rm -rf results +mkdir results +cd results +cp ../../../tmp/iblfifo.edf . +planAhead -mode batch -source ../planAhead_rdn.tcl diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.tcl b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.tcl new file mode 100755 index 0000000000000000000000000000000000000000..b97647dd1e2dd8ae9939374e8c3e94c98e65aa55 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/planAhead_rdn.tcl @@ -0,0 +1,67 @@ +# (c) Copyright 2009 - 2010 Xilinx, Inc. All rights reserved. +# +# This file contains confidential and proprietary information +# of Xilinx, Inc. and is protected under U.S. and +# international copyright and other intellectual property +# laws. +# +# DISCLAIMER +# This disclaimer is not a license and does not grant any +# rights to the materials distributed herewith. Except as +# otherwise provided in a valid license issued to you by +# Xilinx, and to the maximum extent permitted by applicable +# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +# (2) Xilinx shall not be liable (whether in contract or tort, +# including negligence, or under any other theory of +# liability) for any loss or damage of any kind or nature +# related to, arising under or in connection with these +# materials, including for any direct, or any indirect, +# special, incidental, or consequential loss or damage +# (including loss of data, profits, goodwill, or any type of +# loss or damage suffered as a result of any action brought +# by a third party) even if such damage or loss was +# reasonably foreseeable or Xilinx had been advised of the +# possibility of the same. +# +# CRITICAL APPLICATIONS +# Xilinx products are not designed or intended to be fail- +# safe, or for use in any application requiring fail-safe +# performance, such as life-support or safety devices or +# systems, Class III medical devices, nuclear facilities, +# applications related to the deployment of airbags, or any +# other applications that could lead to death, personal +# injury, or severe property or environmental damage +# (individually and collectively, "Critical +# Applications"). Customer assumes the sole risk and +# liability of any use of Xilinx products in Critical +# Applications, subject only to applicable laws and +# regulations governing limitations on product liability. +# +# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +# PART OF THIS FILE AT ALL TIMES. + + +set device xc4vfx60ff1152-10 +set projName iblfifo +set design iblfifo +set projDir [file dirname [info script]] +create_project $projName $projDir/results/$projName -part $device -force +set_property design_mode RTL [current_fileset -srcset] +set top_module iblfifo_top +add_files -norecurse {../../example_design/iblfifo_top.vhd} +add_files -norecurse {./iblfifo.edf} +import_files -fileset [get_filesets constrs_1] -force -norecurse {../../example_design/iblfifo_top.xdc} +set_property top iblfifo_top [get_property srcset [current_run]] +synth_design +opt_design +place_design +route_design +write_sdf -rename_top_module iblfifo_top -file routed.sdf +write_verilog -nolib -mode sim -sdf_anno false -rename_top_module iblfifo_top routed.vhd +report_timing -nworst 30 -path_type full -file routed.twr +report_drc +#write_bitstream diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.prj b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.prj new file mode 100755 index 0000000000000000000000000000000000000000..59db9f66e303f313b463fea9eb7dfb11cb6c97b9 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.prj @@ -0,0 +1 @@ +work ../example_design/iblfifo_top.vhd diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.scr b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.scr new file mode 100755 index 0000000000000000000000000000000000000000..acf6372c590cd372c8baecb1b39562bb3e921cd4 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_ste/implement/xst.scr @@ -0,0 +1,13 @@ +run +-ifmt VHDL +-ent iblfifo_top +-p xc4vlx200-ff1513-10 +-ifn xst.prj +-write_timing_constraints No +-iobuf YES +-max_fanout 100 +-ofn iblfifo_top +-ofmt NGC +-bus_delimiter () +-hierarchy_separator / +-case Maintain diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_upgrade.txt b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_upgrade.txt new file mode 100644 index 0000000000000000000000000000000000000000..0612390f8a825b5806177478d5fb62cf9c73a53a --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_upgrade.txt @@ -0,0 +1,129 @@ +Thu Oct 6 00:36:20 2011 + +Upgraded iblfifo from Fifo Generator 4.4 to Fifo Generator 8.2 + +Added parameter enable_reset_synchronization with value true +Added parameter inject_dbit_error with value false +Added parameter inject_sbit_error with value false +Removed parameter enable_int_clk +Added parameter add_ngc_constraint_axi with value false +Added parameter aruser_width with value 1 +Added parameter awuser_width with value 1 +Added parameter axi_address_width with value 32 +Added parameter axi_data_width with value 64 +Added parameter axi_type with value AXI4_Stream +Added parameter axis_type with value FIFO +Added parameter buser_width with value 1 +Added parameter clock_enable_type with value Slave_Interface_Clock_Enable +Added parameter clock_type_axi with value Common_Clock +Added parameter disable_timing_violations_axi with value false +Added parameter empty_threshold_assert_value_axis with value 1022 +Added parameter empty_threshold_assert_value_rach with value 1022 +Added parameter empty_threshold_assert_value_rdch with value 1022 +Added parameter empty_threshold_assert_value_wach with value 1022 +Added parameter empty_threshold_assert_value_wdch with value 1022 +Added parameter empty_threshold_assert_value_wrch with value 1022 +Added parameter enable_aruser with value false +Added parameter enable_awuser with value false +Added parameter enable_buser with value false +Added parameter enable_common_overflow with value false +Added parameter enable_common_underflow with value false +Added parameter enable_data_counts_axis with value false +Added parameter enable_data_counts_rach with value false +Added parameter enable_data_counts_rdch with value false +Added parameter enable_data_counts_wach with value false +Added parameter enable_data_counts_wdch with value false +Added parameter enable_data_counts_wrch with value false +Added parameter enable_ecc_axis with value false +Added parameter enable_ecc_rach with value false +Added parameter enable_ecc_rdch with value false +Added parameter enable_ecc_wach with value false +Added parameter enable_ecc_wdch with value false +Added parameter enable_ecc_wrch with value false +Added parameter enable_handshake_flag_options_axis with value false +Added parameter enable_handshake_flag_options_rach with value false +Added parameter enable_handshake_flag_options_rdch with value false +Added parameter enable_handshake_flag_options_wach with value false +Added parameter enable_handshake_flag_options_wdch with value false +Added parameter enable_handshake_flag_options_wrch with value false +Added parameter enable_read_channel with value false +Added parameter enable_ruser with value false +Added parameter enable_tdata with value false +Added parameter enable_tdest with value false +Added parameter enable_tid with value false +Added parameter enable_tkeep with value false +Added parameter enable_tlast with value false +Added parameter enable_tready with value true +Added parameter enable_tstrobe with value false +Added parameter enable_tuser with value false +Added parameter enable_write_channel with value false +Added parameter enable_wuser with value false +Added parameter fifo_application_type_axis with value Data_FIFO +Added parameter fifo_application_type_rach with value Data_FIFO +Added parameter fifo_application_type_rdch with value Data_FIFO +Added parameter fifo_application_type_wach with value Data_FIFO +Added parameter fifo_application_type_wdch with value Data_FIFO +Added parameter fifo_application_type_wrch with value Data_FIFO +Added parameter fifo_implementation_axis with value Common_Clock_Block_RAM +Added parameter fifo_implementation_rach with value Common_Clock_Block_RAM +Added parameter fifo_implementation_rdch with value Common_Clock_Block_RAM +Added parameter fifo_implementation_wach with value Common_Clock_Block_RAM +Added parameter fifo_implementation_wdch with value Common_Clock_Block_RAM +Added parameter fifo_implementation_wrch with value Common_Clock_Block_RAM +Added parameter full_threshold_assert_value_axis with value 1023 +Added parameter full_threshold_assert_value_rach with value 1023 +Added parameter full_threshold_assert_value_rdch with value 1023 +Added parameter full_threshold_assert_value_wach with value 1023 +Added parameter full_threshold_assert_value_wdch with value 1023 +Added parameter full_threshold_assert_value_wrch with value 1023 +Added parameter id_width with value 4 +Added parameter inject_dbit_error_axis with value false +Added parameter inject_dbit_error_rach with value false +Added parameter inject_dbit_error_rdch with value false +Added parameter inject_dbit_error_wach with value false +Added parameter inject_dbit_error_wdch with value false +Added parameter inject_dbit_error_wrch with value false +Added parameter inject_sbit_error_axis with value false +Added parameter inject_sbit_error_rach with value false +Added parameter inject_sbit_error_rdch with value false +Added parameter inject_sbit_error_wach with value false +Added parameter inject_sbit_error_wdch with value false +Added parameter inject_sbit_error_wrch with value false +Added parameter input_depth_axis with value 1024 +Added parameter input_depth_rach with value 16 +Added parameter input_depth_rdch with value 1024 +Added parameter input_depth_wach with value 16 +Added parameter input_depth_wdch with value 1024 +Added parameter input_depth_wrch with value 16 +Added parameter interface_type with value Native +Added parameter overflow_flag_axi with value false +Added parameter overflow_sense_axi with value Active_High +Added parameter programmable_empty_type_axis with value Empty +Added parameter programmable_empty_type_rach with value Empty +Added parameter programmable_empty_type_rdch with value Empty +Added parameter programmable_empty_type_wach with value Empty +Added parameter programmable_empty_type_wdch with value Empty +Added parameter programmable_empty_type_wrch with value Empty +Added parameter programmable_full_type_axis with value Full +Added parameter programmable_full_type_rach with value Full +Added parameter programmable_full_type_rdch with value Full +Added parameter programmable_full_type_wach with value Full +Added parameter programmable_full_type_wdch with value Full +Added parameter programmable_full_type_wrch with value Full +Added parameter rach_type with value FIFO +Added parameter rdch_type with value FIFO +Added parameter ruser_width with value 1 +Added parameter tdata_width with value 64 +Added parameter tdest_width with value 4 +Added parameter tid_width with value 8 +Added parameter tkeep_width with value 4 +Added parameter tstrb_width with value 4 +Added parameter tuser_width with value 4 +Added parameter underflow_flag_axi with value false +Added parameter underflow_sense_axi with value Active_High +Added parameter use_clock_enable with value false +Added parameter wach_type with value FIFO +Added parameter wdch_type with value FIFO +Added parameter wrch_type with value FIFO +Added parameter wuser_width with value 1 + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_xmdf.tcl b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_xmdf.tcl new file mode 100644 index 0000000000000000000000000000000000000000..71e51b1da89b67b44a0d062bd24d16a9c861295a --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/iblfifo_xmdf.tcl @@ -0,0 +1,115 @@ +# The package naming convention is <core_name>_xmdf +package provide iblfifo_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::iblfifo_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::iblfifo_xmdf::xmdfInit { instance } { +# Variable containing name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name iblfifo +} +# ::iblfifo_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::iblfifo_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_generator_ug175.pdf +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_generator_v8_2_readme.txt +utilities_xmdf::xmdfSetData $instance FileSet $fcount type text +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo.vhd +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo.vho +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/example_design/iblfifo_top.ucf +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/example_design/iblfifo_top.vhd +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/example_design/iblfifo_top.xdc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/implement.bat +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/implement.sh +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/planAhead_rdn.bat +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/planAhead_rdn.sh +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/planAhead_rdn.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/xst.prj +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_ste/implement/xst.scr +utilities_xmdf::xmdfSetData $instance FileSet $fcount type Ignore +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_upgrade.txt +utilities_xmdf::xmdfSetData $instance FileSet $fcount type text +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path iblfifo_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module iblfifo +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.ngc b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.ngc new file mode 100644 index 0000000000000000000000000000000000000000..78b1bc8c46d9cd398baa1f3dbad249dcccc4ccd0 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.4e +$26b4g<,[o}e~g`n;"2*413&;$>"9 > %71?*ga{&ygmn!z/da,ojenig%fecgcau-{mioip&He`L}fc.zjhZehzly$x`~ _be,tdrsm{dTnaePmdo-jbi>39:;<=>?0163?56789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012346=6&9;87<>5IORVP?gcl{k757>112924?OIX\^1mij}b=;94;7338?1EC^ZT;CG@WG;9=0;2<:4148JJUSS2HNO^O2>4;2=55=62@D[YY4xe`>3>58682;1EC^ZT;uff96=87;97><5IORVP?BNI59:6=0>2:11>LHW]]0OEO2<1;2=56=4:3CE\XZ5dhlb867=87;87><5IORVP?bnfk68=7>112906?IR\Y__6IAN<2394;743:81CXZ_UU8GKG:493:5=85<2;MVPUSS2me~xl2<1;2=50=4:3E^X][[:emvpg:493:5=<5;:HLSQQ<CAYK7?7>11097>LHW]]0OE]L33;2=55=32@D[YY4XE@>0>58682>1EC^ZT;UFF95=87;9794@UURVP?BHXH686=0>2:69KPRW]]0OC]L33;2=b>2qnq<;jk?>53/24==FLMXJ0=06;@FGVD:68730MIJ]A=32:<=FLMXJ0<<19:CG@WG;9:4i7LJKR@>20?6912KOH_O315<;?DBCZH6:255NDEPB878?3HNO^L2<>99B@ATF4=437LJKR@>6:==FLMXJ0;07;@FGVD:0611JHI\N<9<;?DBCZH62255NDEPA858>3HNO^O2>0?;8EABUJ5;:245NDEPA844912KOH_L312<a?DBCZK6:87>19:CG@WD;9=437LJKRC>2:==FLMXI0?07;@FGVG:4611JHI\M<5<;?DBCZK6>255NDEPA838?3HNO^O28>99B@ATE41437LJKRC>::6=FDE90NX<7;CWP[LHAGh1HM^MNDDKMEd=DIZIJHHGABc9@EVEFLLE^XLl4C@Q@EACH]]H:>6MGEBI\HLEBFZOTXT^J4:AOOD2<KEAI56M@MLKWP@B6<2ID^HQHEOGQEQOHFVCEJB94CSGBP@B13MCJ0=08;EKB8469?2NBM1?>>69GMD:6:7=0HDO312<4?AOF48>5;6JFA=36:2=CAH6::394DHC?52803MCJ0<617:FJE97>6?1OEL2>>69GMD:587=0HDO320<4?AOF4;85;6JFA=00:2=CAH698394DHC?60803MCJ0?817:FJE9406>1OEL2=8?58@LG;:04=7IGN<3<4?AOF4::556JFA=12>5803MCJ0>?16:FJE959>2NBM1:16:FJE939>2NBM1816:FJE919>2NBM1616:FJE9?9>2NBN1>17:FJF9776>1OEO2>1?58@LD;9;4<7IGM<01=3>BNJ5;?2:5KIC>21;1<L@H7=;08;EKA8419?2NBN1?7>69GMG:617<0HDL31?58@LD;:94<7IGM<33=3>BNJ5892:5KIC>17;1<L@H7>908;EKA8739?2NBN1<9>69GMG:5?7=0HDL329<4?AOE4;35:6JFB=0=3>BNJ59;245KIC>05?69?2NBN1=>>79GMG:46?1OEO2;>79GMG:26?1OEO29>79GMG:06?1OEO27>79GMG:>6>1OE]O30?58@LVF484<7IG_A=0==>BNXH686=08;EKSE959?2NB\O2?>69GMUD;97=0HD^M<3<:?AOWJ591<394DHRA86813MEJ0=08;EMB8469?2NDM1?>>69GKD:6:7=0HBO312<4?AIF48>5;6J@A=36:2=CGH6::394DNC?52803MEJ0<617:FLE97>6?1OCL2>>69GKD:587=0HBO320<4?AIF4;85;6J@A=00:2=CGH698394DNC?60803MEJ0?817:FLE9406>1OCL2=8?58@JG;:04=7IAN<3<4?AIF4::556J@A=12>5803MEJ0>?16:FLE959>2NDM1:16:FLE939>2NDM1816:FLE919>2NDM1616:FLE9?9?2NDMR\JG79GKG:76>1OCO2>0?58@JD;984<7IAM<00=3>BHJ5;82:5KOC>20;1<LFH7=808;EMA8409?2NDN1?8>69GKG:607=0HBL318<5?AIE484<7IAM<32=3>BHJ58:2:5KOC>16;1<LFH7>>08;EMA8729?2NDN1<:>69GKG:5>7=0HBL326<4?AIE4;25;6J@B=0::3=CGK692:5KOC>04;?<LFH7?<4?>69GKG:497<0HBL33?48@JD;<7<0HBL35?48@JD;>7<0HBL37?48@JD;07<0HBL39?58@JDXZLM<7IA_A=2=3>BHXH6:2:5KOQC?6;?<LFZJ0>4?>69GKUG;;7=0HB^M<1<4?AIWJ5;5;6J@PC>1:<=CGYH7?7>17:FLTG:46:1NBL=4EO@6?CGK[L;0K>5HNE:8MKOSXV:;46GAIUR\44><AGC_\R>=8:KMMQVX8:20ECG[P^27<>OIA]ZT<864IOKWTZ6102CEEY^P0658MKOSW9:<7D@FT^223>OIA]U;>:5FNHV\461<AGC_S=:8;HLJPZ62?2CEEYQ?669JJLRX8>=0ECG[_1:4?LHN\V:2;6GAIU]3E2=NF@^T<O94IOKW[5E03@DBXR>K7:KMMQY7M>1BBDZP0G58MKOSW8:<7D@FT^323>OIA]U:>:5FNHV\561<AGC_S<:8;HLJPZ72?2CEEYQ>669JJLRX9>=0ECG[_0:4?LHN\V;2;6GAIU]2E2=NF@^T=O94IOKW[4E03@DBXR?K7:KMMQY6M>1BBDZP1G58MKOSW;:<7D@FT^023>OIA]U9>:5FNHV\661<AGC_S?:8;HLJPZ42?2CEEYQ=669JJLRX:>=0ECG[_3:4?LHN\V82;6GAIU]1E2=NF@^T>O94IOKW[7E03@DBXR<K7:KMMQY5M>1BBDZP2G58MKOSW::<7D@FT^123>OIA]U8>:5FNHV\761<AGC_S>:8;HLJPZ52?2CEEYQ<669JJLRX;>=0ECG[_2:4?LHN\V92;6GAIU]0E2=NF@^T?O94IOKW[6E03@DBXR=K7:KMMQY4M>1BBDZP3G48MKOSWH<0ECG[_C;8MKOSWOCGI<<4IOTFVQYDDBUOCLQ]EF31?LHQM[^TOAEPDN@\V@A13EEJHHJ8;MMDMFGKk2Gjfb|Yesqjkke<E`dd~[k}shmm7>H68=1E==>;;O3351=I998?7C??359M55233G;;995A1147?K77?=1E==6;;O33=6=I98>0B<??4:L2542<F8;986@>1268J473<2D:=8:4N0350>H69>>0B<?74:L25<5<F88?7C?=059M57733G;9>95A1317?K75<=1E=?8;;O31<1=I9;387C?<4:L2752<F89:86@>3368J454<2D:?9:4N0160>H6;?>0B<=84:L27=2<F892?6@>459M51633G;?=95A1507?K73;=1E=9:;;O3711=I9=<?7C?;759M51>33G;?5>5A1468J437<2D:9<:4N0710>H6=:>0B<;;4:L2102<F8?=86@>5668J43?<2D:94=4N040?K70;2D:4>5A1808J75<F;:87C<>3:L166=I::90B?:<;O067>H5>:1E>:=4N3:0?K4>:2D8?6@<029M745<F:887C=<3:L006=I;<90B>8<;O147>H40:1E?4<4N518J1643G>:?6@;229M065<F=>87C::3:L736=I<080B8=4N420?K36;2D>>>5A5218J0243G?>?6@:629M125<F<287C;62:L57>H18:1E:<=4N700?K04;2D=8>5A6418J3043G<<?6@9829M2<4<F>90B:><;O527>H0::1E;>=4N660?K12;2D<:>5A7618J2>43G=2>6@73:L;46=I0890B5<<;O:07>H?<:1E48=4N940?K>0;2D34>5A8808J<5<F0:87C7>3:L:66=I1:90B4:<;O;67>H>>:1E5:=4N8:0?K?>n2DISO[\PHL\TWIW[>1EIYY@RJ68JJHB12DDSNFNNFG1?JM63Y>0\L\[a:RJJZDR[@NSn6^FN^@VWKGJM?1YM@L>6g9QEHYBP]OE_DAA_@d8VDKXMQ^NB^G@N^@`?WCFLV]BHYFPAb9QADBX_@N_DRL9;SGDG@G13[OLOHL7;RCUAAGSI890_DCPCNNOMVOHFVICINE9;RMVVFC03ZX]MAQN7:QQRDJXJ=1X__O;;RQQF1=SQYO>86[?/cnh[hcjWnoeio{os-ueioc&jy~"|nmmmlt^6Z&{kf"!y4^kmmq(uid%_^XKPDQ,PMKAKMVZYE@ [DQ77?P6(jeaTahcPgdlfvdrhz&|j`dj!crvq+wgjdfe{W<S!r`o-v*p3W`dbx#|nm.VQQ@YCX'YBBJBJ_QPJI+RCXh1^_H\PAMKBWf=R[LXTZD]FBMG0?SED12\BIZQ[YQG5?RCF494=7ZKN<0<5?RCF4;437ZKN<283:3=PMH682;5XEC>3:3=PMK6:2;5XEC>1:==PMK686=09;VGA868d3^XBXHQBOEG\Ef=PZ@^NS@AKE^@g?RTN\LU\EIZG_@f8SWOSMV]BHYFPB0f8\LJNFQ'SHO.?.0"PPPD'8';+M^MFI79[WQJNJ>1S_YQHNE`8\ZEHZLUBBKA9;Yfa[Lba3QncS]|fmWgqwlii991Sh`QBakmqR`ttafd:<6Vkm^OjjjtQm{ybcc64aefqe-6.02koho'1(:8eabui!8"46okdsc+7,><imnym%:&8:cg`wg/= 20mij}a)4*<>gcl{k#;$64aefqe->.02koho'9(:8eabui5:546okdsc?5;><imnym1<18:cg`wg;;720mij}a=6=<>gcl{k79364aefqe90902koho37?:8eabui525m6okdsc?=?6902koho39?:8eabuj!:"46okds`+5,><imnyn%<&8:cg`wd/; 20mij}b)6*<>gcl{h#9$64aefqf-0.02kohl'7(:8eabuj!2"46okds`+=,><imnyn1>18:cg`wd;9720mij}b=0=<>gcl{h7?364aefqf92902kohl35?:8eabuj5<546okds`?3;><imnyn161a:cg`wd;13:546okds`?=;543kf`S`kb_fgm[s4X0%*Seagax!ALV@&@mgoymya} 02-5+64W`z886mck`68gime?2nieyk}r69gmkg/8 =0hd`n(0+;?aoii!;;%55kioc+54/?3mcem%?=)99gmkg/9:#37igaa)37-==cagk#=8'7;ekme-71!11oeco'16+;?aoii!;3%55kioc+5</03mcem%<&8:fjjd.58 20hd`n(33*<>bnfh"9>$64dhlb,75.02nbbl&=4(:8`lhf ;?"46jfn`*12,><l`dj$?9&8:fjjd.50 20hd`n(3;*3>bnfh"8%55kioc+75/?3mcem%=>)69gmkg/< =0hd`n(4+4?aoii!<";6jfn`*4-2=cagk#4$94dhlb,</03mcem1>18:fjjd:68720hd`n<03=<>bnfh6:>364dhlb845902nbbl2>4?:8`lhf48?546jfn`>22;><l`dj0<918:fjjd:60720hd`n<0;=3>bnfh6:255kioc?658?3mcem1<>>99gmkg;:;437igaa=00:==cagk7>907;ekme942611oeco327<;?aoii58<255kioc?6=8?3mcem1<6>69gmkg;:720hd`n<22=e>bnfh68=7>18:fjjd:497=0hd`n<2<4?aoii5>5;6jfn`>6:2=cagk7:394dhlb82803mcem1617:fjjd:>6>1oecl'0(58`lhe 8#37igab)33-==cagh#=<'7;ekmf-75!11oecl'12+;?aoij!;?%55kio`+50/?3mcen%?9)99gmkd/9>#37igab)3;-==cagh#=4'8;ekmf-4.02nbbo&=0(:8`lhe ;;"46jfnc*16,><l`di$?=&8:fjjg.5< 20hd`m(37*<>bnfk"9:$64dhla,71.02nbbo&=8(:8`lhe ;3";6jfnc*0-==cagh#?='7;ekmf-56!>1oecl'4(58`lhe <#<7igab)4*3>bnfk"<%:5kio`+<,1<l`di$4'8;ekmf96902nbbo2>0?:8`lhe48;546jfnc>26;><l`di0<=18:fjjg:6<720hd`m<07=<>bnfk6::364dhla841902nbbo2>8?:8`lhe4835;6jfnc>2:==cagh7>=07;ekmf946611oecl323<;?aoij588255kio`?618?3mcen1<:>99gmkd;:?437igab=04:==cagh7>507;ekmf94>6>1oecl32?:8`lhe4::5m6jfnc>05?6902nbbo2<1?58`lhe4:4<7igab=6=3>bnfk6>2:5kio`?2;1<l`di0:08;ekmf9>9?2nbbo26>99gkprf 9#37iazt`*2-<=cg|~j$<>&9:flqqg/98#27iazt`*26,?<lfm%?<)89gkprf 8>"56j`uuc+50/>3me~xl&>6(;8`jssi!;<%45kotvb,4>.12ndyyo'18+;?air|h"9%45kotvb,76.12ndyyo'20+:?air|h"9>$74dnwwe-44!01ocxzn(36*=>bh}}k#>8'6;emvpd.5> 30hb{{a)04-<=cg|~j$?6&9:flqqg/:0#37iazt`*0-<=cg|~j$>>&9:flqqg/;8#37iazt`*7-==cg|~j$8'7;emvpd.1!11ocxzn(6+;?air|h"3%55kotvb,</?3me~xl2?>89gkprf48:556j`uuc?548>3me~xl2>2?;8`jssi5;8245kotvb842912ndyyo314<:?air|h6::374dnwwe970601ocxzn<0:==>bh}}k7=407;emvpd:6601ocxzn<32==>bh}}k7><06;emvpd:5:730hb{{a=00:<=cg|~j0?:19:flqqg;:<427iazt`>12;?<lfm1<8>89gkprf4;2556j`uuc?6<8?3me~xl2=>89gkprf4::5n6j`uuc?74<7601ocxzn<23=<>bh}}k7?364dnwwe92902ndyyo35?:8`jssi5<546j`uuc?3;><lfm1618:flqqg;1720hb{{b)2*<>bh}}h#=$74dnwwf-77!01ocxzm(03*=>bh}}h#=?'6;emvpg.6; 30hb{{b)37-<=cg|~i$<;&9:flqqd/9?#27iaztc*23,?<lfn%?7)89gkpre 83"46j`uu`+6,?<lfn%<?)89gkpre ;;"56j`uu`+67/>3me~xo&=3(;8`jssj!8?%45kotva,73.12ndyyl'27+:?air|k"9;$74dnwwf-4?!01ocxzm(3;*<>bh}}h#?$74dnwwf-57!01ocxzm(23*<>bh}}h#8$64dnwwf-3.02ndyyl'6(:8`jssj!="46j`uu`+<,><lfn%7&8:flqqd;8730hb{{b=33:<=cg|~i0<?19:flqqd;9;427iaztc>27;?<lfn1?;>89gkpre48?556j`uu`?538>3me~xo2>7?;8`jssj5;3245kotva84?902ndyyl31?;8`jssj58;245kotva877912ndyyl323<:?air|k69?374dnwwf943601ocxzm<37==>bh}}h7>;06;emvpg:5?730hb{{b=0;:<=cg|~i0?718:flqqd;:730hb{{b=13:g=cg|~i0>?50?;8`jssj59:255kotva868?3me~xo2;>99gkpre4<437iaztc>5:==cg|~i0:07;emvpg:?611ocxzm<8<;?`bnn;dlh>5jn`18akd?3gmhnxgcdg9seqrbzgUi`fQbel0b?ugs|lxeSobd_lgn(gjlWdofSjka_w0\<)HHFL&ECCK<769seqrbzgUi`fQbel.ahnYjmdUlicQy2^:/fYoizUyijmjb<2/gZnf{Vxnknkn=1.`[hcjW}s{i0<#c^rqmhYsqyo6=!mPshljpdYqie7; nQ}e`f\slbs`Vh6??"l_sgb`Zqnl}bTm0==,b]gmvgedlU|m`Pbit\gjjk59&hSd`ft^djh`Yiido6bbQlod]emicXdfkoii"l_vpjp`YjgmoTn0@@_BJBJBC+kV}yeykPmnff[d;IGVICMCIJ,b]nq}YwayogeckPsucdav;7$jUcm~Qbel]lqqvr|Vxnk~Qm=1.`[iiflVceeyQiimg>4)eX`hyTahcPotvsqqYumnyTm0>#c^uqmqcXllzdRl21107(fYpz`~nSikti]b9465<%iTdl}Psrpa95*dWakxS`{w_nwwtprXzlmxSo3?,b]kevYt{{k6<!mPh`q\ip~Xg|~{yyQ}efq\e86+kVkohoPwhfwl877$jUjhi|m_vkgpm;68%iThhhnumv\`drf59&hSx}j_da`95*dWhflcg{hl?2(fYcazki`hQxasl\fmpXzhdli0>#c^uqmqcX`ndRl233.`[rtn|lU|eizg_`?06)eXzlkoSikti]a9465<%iT~hok_egspmYf58:98!mPbxvf[vo}m43'oR}fm^alhiotafdToeklk<COH)eXkfgfccQllj?3(fYr{lUym`l>6cufvZtt|Vhcz0>#c^ufeZqnl}b6=!mPh`q\akd:9%iTdl}Peoc>5)eXlhT{dj{h<3/gZunf`~iS{oc=1.`khvhfldScobe<rbpqcufVhggRcjm-a\qvcXjp~nSzkm=1.`[pubWksiRyja<2/gZstmVnnjl{ct^fbpd;6$t8=7}o{tdpm[gjlWdofSobd_lgn[bciW8T4Rv|t^35?wc`klk=7khcd`4?vdn|lxy86}|r`68wvte>2}nm%>&8:ufe96=87<0{ho30?48s`d/8 20{hl30;2=2>qbj5:5qMN4`08DE~62O0?6<u\478072<328994km>:23`76}i:991=6`=0587?!4793;mh6s\458072<328994km>:23`76=T9:91?>o50;306=`d939:o>=4S56976g=83;8>5hl1;12g60<l:9i6=4>:0yP03<4;>0?6<==8ga2>67d;:1}X<k<:182>4<>jrY?:7=<7;69564?nj;1?<m<3:&2a`<6;=1]>=<52zw270<63|;8:7>4}%3g3?7>3k98n7>59`80><g|@8oh7W=l:9y:>d<22?0:=7?=:e8f>x"6m108?o5+212967`<a:936=44i21:>5<<a:>?6=4+1e;9713<f8n36=54i264>5<#9m31?964n0f;>5=<a;:n6=4+1e;964><f8n36=54i32g>5<#9m31><64n0f;>4=<a;:h6=4+1e;964><f8n36?54i32a>5<#9m31><64n0f;>6=<a;:j6=4+1e;964><f8n36954i32:>5<#9m31><64n0f;>0=<a;:36=4+1e;964><f8n36;54i324>5<#9m31><64n0f;>2=<a;:=6=4+1e;964><f8n36554i326>5<#9m31><64n0f;><=<a;886=4+1e;967b<f8n36=54i301>5<#9m31>?j4n0f;>4=<a;8:6=4+1e;967b<f8n36?54i303>5<#9m31>?j4n0f;>6=<a;;m6=4+1e;967b<f8n36954i33f>5<#9m31>?j4n0f;>0=<a;;o6=4+1e;967b<f8n36;54i33`>5<#9m31>?j4n0f;>2=<a;;i6=4+1e;967b<f8n36554i33b>5<#9m31>?j4n0f;><=<g;in6=4+1e;96`b<f8n36=54o3ag>5<#9m31>hj4n0f;>4=<g;ii6=4+1e;96`b<f8n36?54o3ab>5<#9m31>hj4n0f;>6=<g;i26=4+1e;96`b<f8n36954o3a;>5<#9m31>hj4n0f;>0=<g;i<6=4+1e;96`b<f8n36;54o3a5>5<#9m31>hj4n0f;>2=<g;i>6=4+1e;96`b<f8n36554o3a7>5<#9m31>hj4n0f;><=<g;i86=4+1e;96`b<f8n36l54o3a1>5<#9m31>hj4n0f;>g=<g;i;6=4+1e;96`b<f8n36n54o3`e>5<#9m31>hj4n0f;>a=<g;hn6=4+1e;96`b<f8n36h54o3`g>5<#9m31>hj4n0f;>c=<g;hh6=4+1e;96`b<f8n36<>4;n0af?6=,8n26?kk;o3g<?7632e9nl4?:%3g=?4bl2d:h54>2:9l6g?=83.:h44=ee9m5a>=9:10c?l7:18'5a?=:ln0b<j7:068?j4e?3:1(<j6:3gg?k7c03;>76a=d583>!7c138nh6`>d9822>=h:m91<7*>d881aa=i9m21=:54o3f1>5<#9m31>hj4n0f;>4><3f8o=7>5$0f:>7cc3g;o47?6;:m1`5<72-;o57<jd:l2`=<6i21d>nh50;&2`<<5mm1e=i651c98k7ed290/=i752df8j4b?28i07b<l1;29 4b>2;oo7c?k8;3g?>i5j?0;6)?k9;0f`>h6l10:i65`2c794?"6l009ii5a1e:95c=<g::m6=4+1e;977c<f8n36=54o22f>5<#9m31??k4n0f;>4=<g::h6=4+1e;977c<f8n36?54o22a>5<#9m31??k4n0f;>6=<g::j6=4+1e;977c<f8n36954o22:>5<#9m31??k4n0f;>0=<g::36=4+1e;977c<f8n36;54o224>5<#9m31??k4n0f;>2=<g::=6=4+1e;977c<f8n36554o226>5<#9m31??k4n0f;><=<g::?6=4+1e;977c<f8n36l54o220>5<#9m31??k4n0f;>g=<g:::6=4+1e;977c<f8n36n54o223>5<#9m31??k4n0f;>a=<g;lm6=4+1e;977c<f8n36h54o3df>5<#9m31??k4n0f;>c=<g;lo6=4+1e;977c<f8n36<>4;n0eg?6=,8n26><j;o3g<?7632e9jo4?:%3g=?55m2d:h54>2:9l6cg=83.:h44<2d9m5a>=9:10c?h6:18'5a?=;;o0b<j7:068?j4a03:1(<j6:20f?k7c03;>76a<1483>!7c1399i6`>d9822>=h;8>1<7*>d8806`=i9m21=:54o230>5<#9m31??k4n0f;>4><3f9:>7>5$0f:>64b3g;o47?6;:m054<72-;o57==e:l2`=<6i21d?<>50;&2`<<4:l1e=i651c98k66c290/=i7533g8j4b?28i07b=?2;29 4b>2:8n7c?k8;3g?>i5n>0;6)?k9;11a>h6l10:i65`2g494?"6l008>h5a1e:95c=<a;9;6=44i312>5<<a;>h6=4+1e;963d<f8n36=54i36a>5<#9m31>;l4n0f;>4=<a;>26=4+1e;963d<f8n36?54i36;>5<#9m31>;l4n0f;>6=<a;><6=4+1e;963d<f8n36954i365>5<#9m31>;l4n0f;>0=<a;>>6=4+1e;963d<f8n36;54i367>5<#9m31>;l4n0f;>2=<a;>86=4+1e;963d<f8n36554i361>5<#9m31>;l4n0f;><=<a;>:6=4+1e;963d<f8n36l54i363>5<#9m31>;l4n0f;>g=<a;9n6=4+1e;963d<f8n36n54i31g>5<#9m31>;l4n0f;>a=<a;9h6=4+1e;963d<f8n36h54i31a>5<#9m31>;l4n0f;>c=<a;9j6=4+1e;963d<f8n36<>4;h00=?6=,8n26?8m;o3g<?7632c9?54?:%3g=?41j2d:h54>2:9j661=83.:h44=6c9m5a>=9:10e?=9:18'5a?=:?h0b<j7:068?l44=3:1(<j6:34a?k7c03;>76g=5383>!7c138=n6`>d9822>=n:<;1<7*>d8812g=i9m21=:54i373>5<#9m31>;l4n0f;>4><3`8?j7>5$0f:>70e3g;o47?6;:k10`<72-;o57<9b:l2`=<6i21b>9j50;&2`<<5>k1e=i651c98m72f290/=i7527`8j4b?28i07d<<f;29 4b>2;<i7c?k8;3g?>o5;=0;6)?k9;05f>h6l10:i65f22194?"6l009:o5a1e:95c=<a;2o6=4+1e;96de<f8n36=54i3:`>5<#9m31>lm4n0f;>4=<a;2j6=4+1e;96de<f8n36?54i3::>5<#9m31>lm4n0f;>6=<a;236=4+1e;96de<f8n36954i3:4>5<#9m31>lm4n0f;>0=<a;2=6=4+1e;96de<f8n36;54i3:6>5<#9m31>lm4n0f;>2=<a;2?6=4+1e;96de<f8n36554i3:0>5<#9m31>lm4n0f;><=<a;296=4+1e;96de<f8n36l54i3:2>5<#9m31>lm4n0f;>g=<a;=m6=4+1e;96de<f8n36n54i35f>5<#9m31>lm4n0f;>a=<a;=o6=4+1e;96de<f8n36h54i35`>5<#9m31>lm4n0f;>c=<a;=i6=4+1e;96de<f8n36<>4;h04e?6=,8n26?ol;o3g<?7632c9;44?:%3g=?4fk2d:h54>2:9j62>=83.:h44=ab9m5a>=9:10e?98:18'5a?=:hi0b<j7:068?l40>3:1(<j6:3c`?k7c03;>76g=9283>!7c138jo6`>d9822>=n:081<7*>d881ef=i9m21=:54i3;2>5<#9m31>lm4n0f;>4><3`82<7>5$0f:>7gd3g;o47?6;:k1<c<72-;o57<nc:l2`=<6i21b>5k50;&2`<<5ij1e=i651c98m7>e290/=i752`a8j4b?28i07d<70;29 4b>2;kh7c?k8;3g?>o5?<0;6)?k9;0bg>h6l10:i65f26694?"6l009mn5a1e:95c=<j8oo6=4>:183M7bk2.:i54>ee9l5a0=831vnh;50;394?6|@8oh7)?j8;g6?jc32900qo=m:18b4?5=1kqC=hm4Z2a955}>2h0>6;4>1;31>a<b28;1=?46:`86>3<c2l0v(<k7:21f?!262:9h7):::21g?!7c93;o96g<3983>>o4;00;66g<4383>>o4<:0;66g<3g83>>o4<90;66g<4583>!7c139?96`>d983?>o4<>0;6)?k9;17<>h6l10;76g=0d83>!7c138:46`>d983?>o58m0;6)?k9;02<>h6l10:76g=0b83>!7c138:46`>d981?>o58k0;6)?k9;02<>h6l10876g=0`83>!7c138:46`>d987?>o5800;6)?k9;02<>h6l10>76g=0983>!7c138:46`>d985?>o58>0;6)?k9;02<>h6l10<76g=0783>!7c138:46`>d98;?>o58<0;6)?k9;02<>h6l10276g=2283>!7c1389h6`>d983?>o5:;0;6)?k9;01`>h6l10:76g=2083>!7c1389h6`>d981?>o5:90;6)?k9;01`>h6l10876g=1g83>!7c1389h6`>d987?>o59l0;6)?k9;01`>h6l10>76g=1e83>!7c1389h6`>d985?>o59j0;6)?k9;01`>h6l10<76g=1c83>!7c1389h6`>d98;?>o59h0;6)?k9;01`>h6l10276a<4083>>i5kl0;6)?k9;0f`>h6l10;76a=ce83>!7c138nh6`>d982?>i5kk0;6)?k9;0f`>h6l10976a=c`83>!7c138nh6`>d980?>i5k00;6)?k9;0f`>h6l10?76a=c983>!7c138nh6`>d986?>i5k>0;6)?k9;0f`>h6l10=76a=c783>!7c138nh6`>d984?>i5k<0;6)?k9;0f`>h6l10376a=c583>!7c138nh6`>d98:?>i5k:0;6)?k9;0f`>h6l10j76a=c383>!7c138nh6`>d98a?>i5k90;6)?k9;0f`>h6l10h76a=bg83>!7c138nh6`>d98g?>i5jl0;6)?k9;0f`>h6l10n76a=be83>!7c138nh6`>d98e?>i5jj0;6)?k9;0f`>h6l10:<65`2c`94?"6l009ii5a1e:954=<g;hj6=4+1e;96`b<f8n36<<4;n0a=?6=,8n26?kk;o3g<?7432e9n54?:%3g=?4bl2d:h54>4:9l6g1=83.:h44=ee9m5a>=9<10c?j;:18'5a?=:ln0b<j7:048?j4c;3:1(<j6:3gg?k7c03;<76a=d383>!7c138nh6`>d982<>=h:m;1<7*>d881aa=i9m21=454o3f3>5<#9m31>hj4n0f;>4g<3f8hj7>5$0f:>7cc3g;o47?m;:m1gf<72-;o57<jd:l2`=<6k21d>n?50;&2`<<5mm1e=i651e98k7d1290/=i752df8j4b?28o07b<m5;29 4b>2;oo7c?k8;3e?>i48o0;6)?k9;11a>h6l10;76a<0d83>!7c1399i6`>d982?>i48j0;6)?k9;11a>h6l10976a<0c83>!7c1399i6`>d980?>i48h0;6)?k9;11a>h6l10?76a<0883>!7c1399i6`>d986?>i4810;6)?k9;11a>h6l10=76a<0683>!7c1399i6`>d984?>i48?0;6)?k9;11a>h6l10376a<0483>!7c1399i6`>d98:?>i48=0;6)?k9;11a>h6l10j76a<0283>!7c1399i6`>d98a?>i4880;6)?k9;11a>h6l10h76a<0183>!7c1399i6`>d98g?>i5no0;6)?k9;11a>h6l10n76a=fd83>!7c1399i6`>d98e?>i5nm0;6)?k9;11a>h6l10:<65`2ga94?"6l008>h5a1e:954=<g;li6=4+1e;977c<f8n36<<4;n0ee?6=,8n26><j;o3g<?7432e9j44?:%3g=?55m2d:h54>4:9l6c>=83.:h44<2d9m5a>=9<10c>?::18'5a?=;;o0b<j7:048?j56<3:1(<j6:20f?k7c03;<76a<1283>!7c1399i6`>d982<>=h;881<7*>d8806`=i9m21=454o232>5<#9m31??k4n0f;>4g<3f9:<7>5$0f:>64b3g;o47?m;:m04a<72-;o57==e:l2`=<6k21d?=<50;&2`<<4:l1e=i651e98k7`0290/=i7533g8j4b?28o07b<i6;29 4b>2:8n7c?k8;3e?>o5;90;66g=3083>>o5<j0;6)?k9;05f>h6l10;76g=4c83>!7c138=n6`>d982?>o5<00;6)?k9;05f>h6l10976g=4983>!7c138=n6`>d980?>o5<>0;6)?k9;05f>h6l10?76g=4783>!7c138=n6`>d986?>o5<<0;6)?k9;05f>h6l10=76g=4583>!7c138=n6`>d984?>o5<:0;6)?k9;05f>h6l10376g=4383>!7c138=n6`>d98:?>o5<80;6)?k9;05f>h6l10j76g=4183>!7c138=n6`>d98a?>o5;l0;6)?k9;05f>h6l10h76g=3e83>!7c138=n6`>d98g?>o5;j0;6)?k9;05f>h6l10n76g=3c83>!7c138=n6`>d98e?>o5;h0;6)?k9;05f>h6l10:<65f22;94?"6l009:o5a1e:954=<a;936=4+1e;963d<f8n36<<4;h003?6=,8n26?8m;o3g<?7432c9?;4?:%3g=?41j2d:h54>4:9j663=83.:h44=6c9m5a>=9<10e?;=:18'5a?=:?h0b<j7:048?l4293:1(<j6:34a?k7c03;<76g=5183>!7c138=n6`>d982<>=n:=l1<7*>d8812g=i9m21=454i36f>5<#9m31>;l4n0f;>4g<3`8?h7>5$0f:>70e3g;o47?m;:k10d<72-;o57<9b:l2`=<6k21b>>h50;&2`<<5>k1e=i651e98m753290/=i7527`8j4b?28o07d<<3;29 4b>2;<i7c?k8;3e?>o50m0;6)?k9;0bg>h6l10;76g=8b83>!7c138jo6`>d982?>o50h0;6)?k9;0bg>h6l10976g=8883>!7c138jo6`>d980?>o5010;6)?k9;0bg>h6l10?76g=8683>!7c138jo6`>d986?>o50?0;6)?k9;0bg>h6l10=76g=8483>!7c138jo6`>d984?>o50=0;6)?k9;0bg>h6l10376g=8283>!7c138jo6`>d98:?>o50;0;6)?k9;0bg>h6l10j76g=8083>!7c138jo6`>d98a?>o5?o0;6)?k9;0bg>h6l10h76g=7d83>!7c138jo6`>d98g?>o5?m0;6)?k9;0bg>h6l10n76g=7b83>!7c138jo6`>d98e?>o5?k0;6)?k9;0bg>h6l10:<65f26c94?"6l009mn5a1e:954=<a;=26=4+1e;96de<f8n36<<4;h04<?6=,8n26?ol;o3g<?7432c9;:4?:%3g=?4fk2d:h54>4:9j620=83.:h44=ab9m5a>=9<10e?7<:18'5a?=:hi0b<j7:048?l4>:3:1(<j6:3c`?k7c03;<76g=9083>!7c138jo6`>d982<>=n:0:1<7*>d881ef=i9m21=454i3:e>5<#9m31>lm4n0f;>4g<3`83i7>5$0f:>7gd3g;o47?m;:k1<g<72-;o57<nc:l2`=<6k21b>5>50;&2`<<5ij1e=i651e98m712290/=i752`a8j4b?28o07d<84;29 4b>2;kh7c?k8;3e?>i5;;0;66l>fg83>4<729q/=h65e49K5cc<@8oh7bk;:188yg7bi3:1o?4?:1y'5`>=9mk0D<hj;I3fg>\4k3ip;765b;a956<6<3;>6<85f;33>41=910vbo:50:lg2?6<,88n6?5+13d96>"b>390(h953:&f<?5<,l31?6*ja;18 `d=;2.:i<4j3:&2a1<53-on6>5+eg80?!`72:1/j<4<;%d1>6=#n:087)h;:29'b0<43-l=6>5+f680?!`?2:1/j44<;%db>6=#nk087)hl:29'ba<43-ln6>5+fg80?!778390(<>>:29'554=;2.:<>4<;%330?5<,8:>6>5+11497>"68>087)??8;18 46>2:1/==o53:&24g<43-;;o7=4$02g>6=#99o1?6*>0g80?!768390(<?>:29'544=;2.:=>4<;%320?5<,8;>6>5+10497>"69>087)?>8;18 47>2:1/=<o53:&25g<43-;:o7=4$03g>6=#98o1?6*>1g80?!758390(<<>:29'574=;2.:>>4<;%310?5<,88>6>5+13497>"6:>087)?=8;18 44>2:1/=?o53:&26g<43-;9o7=4$00g>6=#9::1=i=4$012>`5<,8996h=4$0fa>4b43-;oo7?k3:l2`a<6:2d:hh4>2:&2a7<4i2.no7=4$df97>"6n00:h95+1gc95a2<f8li6<<4n0d`>44<,8o>6?5f3e83>>o4m3:17d:=:188m15=831bi<4?::k2`c<722c:i=4?::kf6?6=3`;n:7>5;h3f3?6=3f9m6=44o5294?=n:90;6)?k9;3e?k7c03:07d?j:18'5a?=9o1e=i651:9j5a<72-;o57?i;o3g<?4<3`;h6=4+1e;95c=i9m21?65f1c83>!7c13;m7c?k8;68?l4>290/=i751g9m5a>==21b>54?:%3g=?7a3g;o4784;h04>5<#9m31=k5a1e:93>=n:?0;6)?k9;3e?k7c03207d<::18'5a?=9o1e=i659:9j61<72-;o57?i;o3g<?g<3`886=4+1e;95c=i9m21n65f2383>!7c13;m7c?k8;a8?l46290/=i751g9m5a>=l21b=l4?:%3g=?7a3g;o47k4;h13>5<#9m31>k5a1e:94>=n:l0;6)?k9;0e?k7c03;07d<k:18'5a?=:o1e=i652:9j6f<72-;o57<i;o3g<?5<3`8i6=4+1e;96c=i9m21865f3883>!7c138m7c?k8;78?l5?290/=i752g9m5a>=>21b?:4?:%3g=?4a3g;o4794;h15>5<#9m31>k5a1e:9<>=n;<0;6)?k9;0e?k7c03307d=;:18'5a?=:o1e=i65a:9j76<72-;o57<i;o3g<?d<3`996=4+1e;96c=i9m21o65f3083>!7c138m7c?k8;f8?l4f290/=i752g9m5a>=m21b:=4?:%3g=?3a3g;o47>4;h7f>5<#9m319k5a1e:95>=n=j0;6)?k9;7e?k7c03807d;m:18'5a?==o1e=i653:9j1d<72-;o57;i;o3g<?2<3`?26=4+1e;91c=i9m21965f5983>!7c13?m7c?k8;48?l30290/=i755g9m5a>=?21b9;4?:%3g=?3a3g;o4764;h76>5<#9m319k5a1e:9=>=n==0;6)?k9;7e?k7c03k07d;<:18'5a?==o1e=i65b:9j14<72-;o57;i;o3g<?e<3`?;6=4+1e;91c=i9m21h65f4g83>!7c13?m7c?k8;g8?l2b290/=i755g9m5a>=n21b8i4?:%3g=?3a3g;o47??;:k7g?6=,8n268h4n0f;>47<3`>i6=4+1e;91c=i9m21=?54i5c94?"6l00>j6`>d9827>=n<00;6)?k9;7e?k7c03;?76g;8;29 4b>2<l0b<j7:078?l00290/=i755g9m5a>=9?10e;850;&2`<<2n2d:h54>7:9j20<72-;o57;i;o3g<?7?32c=87>5$0f:>0`<f8n36<74;h40>5<#9m319k5a1e:95d=<a?81<7*>d886b>h6l10:n65f6083>!7c13?m7c?k8;3`?>o2l3:1(<j6:4d8j4b?28n07d;=:18'5a?==o1e=i651d98m11=83.:h44:f:l2`=<6n21b4<4?:%3g=?>73g;o47>4;h5e>5<#9m314=5a1e:95>=n?m0;6)?k9;:3?k7c03807d9l:18'5a?=091e=i653:9j3g<72-;o576?;o3g<?2<3`=j6=4+1e;9<5=i9m21965f7883>!7c132;7c?k8;48?l1?290/=i75819m5a>=?21b;:4?:%3g=?>73g;o4764;h55>5<#9m314=5a1e:9=>=n?<0;6)?k9;:3?k7c03k07d9;:18'5a?=091e=i65b:9j37<72-;o576?;o3g<?e<3`=:6=4+1e;9<5=i9m21h65f7183>!7c132;7c?k8;g8?l0a290/=i75819m5a>=n21b:h4?:%3g=?>73g;o47??;:k5`?6=,8n265>4n0f;>47<3`<h6=4+1e;9<5=i9m21=?54i7`94?"6l003<6`>d9827>=n>h0;6)?k9;:3?k7c03;?76g99;29 4b>21:0b<j7:078?l>?290/=i75819m5a>=9?10e5950;&2`<<?82d:h54>7:9j<3<72-;o576?;o3g<?7?32c397>5$0f:>=6<f8n36<74;h:7>5<#9m314=5a1e:95d=<a191<7*>d88;4>h6l10:n65f8383>!7c132;7c?k8;3`?>o0m3:1(<j6:928j4b?28n07d9<:18'5a?=091e=i651d98m3>=83.:h4470:l2`=<6n21b4i4?:%3g=?>d3g;o47>4;h:a>5<#9m314n5a1e:95>=n0h0;6)?k9;:`?k7c03807d66:18'5a?=0j1e=i653:9j=7<72-;o577>;o3g<?6<3`3;6=4+1e;9=4=i9m21=65f8g83>!7c133:7c?k8;08?l>b290/=i75909m5a>=;21b=k=50;&2`<<6n;1e=i650:9j5c7=83.:h44>f39m5a>=921b=k>50;&2`<<6n;1e=i652:9j5``=83.:h44>f39m5a>=;21b=k650;&2`<<6n>1e=i650:9j5c0=83.:h44>f69m5a>=921b=k;50;&2`<<6n>1e=i652:9j5c2=83.:h44>f69m5a>=;21dmn4?:%3g=?ge3g;o47>4;ncb>5<#9m31mo5a1e:95>=hi10;6)?k9;ca?k7c03807bo8:18'5a?=ik1e=i653:9le3<72-;o57om;o3g<?2<3fk>6=4+1e;9eg=i9m21965`a583>!7c13ki7c?k8;48?jg4290/=i75ac9m5a>=?21dm?4?:%3g=?ge3g;o4764;nc2>5<#9m31mo5a1e:9=>=hi90;6)?k9;ca?k7c03k07b7i:18'5a?=ik1e=i65b:9l=a<72-;o57om;o3g<?e<3f3h6=4+1e;9eg=i9m21h65`9c83>!7c13ki7c?k8;g8?j?f290/=i75ac9m5a>=n21d544?:%3g=?ge3g;o47??;:m:<?6=,8n26ll4n0f;>47<3f3<6=4+1e;9eg=i9m21=?54o8494?"6l00jn6`>d9827>=h1<0;6)?k9;ca?k7c03;?76a64;29 4b>2hh0b<j7:078?jd4290/=i75ac9m5a>=9?10co<50;&2`<<fj2d:h54>7:9lf4<72-;o57om;o3g<?7?32ei<7>5$0f:>dd<f8n36<74;nce>5<#9m31mo5a1e:95d=<gho1<7*>d88bf>h6l10:n65`ae83>!7c13ki7c?k8;3`?>if13:1(<j6:``8j4b?28n07b7j:18'5a?=ik1e=i651d98k<5=83.:h44nb:l2`=<6n21doh4?:%3g=?ec3g;o47>4;na`>5<#9m31oi5a1e:95>=hkh0;6)?k9;ag?k7c03807bm6:18'5a?=km1e=i653:9lg=<72-;o57mk;o3g<?2<3fi<6=4+1e;9ga=i9m21965`c783>!7c13io7c?k8;48?je2290/=i75ce9m5a>=?21do94?:%3g=?ec3g;o4764;na0>5<#9m31oi5a1e:9=>=hk;0;6)?k9;ag?k7c03k07bm>:18'5a?=km1e=i65b:9lfc<72-;o57mk;o3g<?e<3fhn6=4+1e;9ga=i9m21h65`be83>!7c13io7c?k8;g8?jdd290/=i75ce9m5a>=n21dno4?:%3g=?ec3g;o47??;:mae?6=,8n26nj4n0f;>47<3fh26=4+1e;9ga=i9m21=?54oc:94?"6l00hh6`>d9827>=hj>0;6)?k9;ag?k7c03;?76am6;29 4b>2jn0b<j7:078?jb2290/=i75ce9m5a>=9?10ci:50;&2`<<dl2d:h54>7:9l`6<72-;o57mk;o3g<?7?32eo>7>5$0f:>fb<f8n36<74;nf2>5<#9m31oi5a1e:95d=<gm:1<7*>d88``>h6l10:n65`cg83>!7c13io7c?k8;3`?>idj3:1(<j6:bf8j4b?28n07bm?:18'5a?=km1e=i651d98kg3=83.:h44ld:l2`=<6n21dho4?:%3g=?bf3g;o47>4;nf:>5<#9m31hl5a1e:95>=hl10;6)?k9;fb?k7c03807bj8:18'5a?=lh1e=i653:9la5<72-;o57ji;o3g<?6<3fnn6=4+1e;9`c=i9m21=65`de83>!7c13nm7c?k8;08?jbd290/=i75dg9m5a>=;21vn<k6:18`6?6=8r.:i54>d`9K5cc<@8oh7W=l:by4>=<e2j0:?7?;:07953<a28:1=:4>8;mf1<73gn=6=5+13g96>"6:o097)k9:29'a2<43-o36>5+e880?!cf2:1/io4<;%3f5?c43-;n87<4$dg97>"bn390(k>53:&e5?5<,o81?6*i3;18 c2=;2.m97=4$g497>"a?390(k653:&e=?5<,ok1?6*ib;18 ce=;2.mh7=4$gg97>"an390(<>?:29'557=;2.:<?4<;%337?5<,8:?6>5+11797>"68?087)??7;18 46?2:1/==753:&24d<43-;;n7=4$02`>6=#99n1?6*>0d80?!77n390(<??:29'547=;2.:=?4<;%327?5<,8;?6>5+10797>"69?087)?>7;18 47?2:1/=<753:&25d<43-;:n7=4$03`>6=#98n1?6*>1d80?!76n390(<<?:29'577=;2.:>?4<;%317?5<,88?6>5+13797>"6:?087)?=7;18 44?2:1/=?753:&26d<43-;9n7=4$00`>6=#9;n1?6*>3182`6=#9:;1i>5+1209a6=#9mh1=i=4$0f`>4b43g;oh7?=;o3ga?753-;n>7=n;%g`>6=#mm087)?i9;3g0>"6nh0:h95a1g`957=i9oi1=?5+1d796>o4l3:17d=j:188m14=831b8>4?::kf5?6=3`;oj7>5;h3f4?6=3`o96=44i0g5>5<<a8o<6=44o2d94?=h<90;66g=0;29 4b>28l0b<j7:198m4c=83.:h44>f:l2`=<632c:h7>5$0f:>4`<f8n36?54i0a94?"6l00:j6`>d980?>o6j3:1(<j6:0d8j4b?2=10e?750;&2`<<6n2d:h54:;:k1<?6=,8n26<h4n0f;>3=<a;=1<7*>d882b>h6l10<76g=6;29 4b>28l0b<j7:998m73=83.:h44>f:l2`=<>32c987>5$0f:>4`<f8n36l54i3194?"6l00:j6`>d98a?>o5:3:1(<j6:0d8j4b?2j10e??50;&2`<<6n2d:h54k;:k2e?6=,8n26<h4n0f;>`=<a::1<7*>d881b>h6l10;76g=e;29 4b>2;l0b<j7:098m7b=83.:h44=f:l2`=<532c9o7>5$0f:>7`<f8n36>54i3`94?"6l009j6`>d987?>o413:1(<j6:3d8j4b?2<10e>650;&2`<<5n2d:h549;:k03?6=,8n26?h4n0f;>2=<a:<1<7*>d881b>h6l10376g<5;29 4b>2;l0b<j7:898m62=83.:h44=f:l2`=<f32c8?7>5$0f:>7`<f8n36o54i2094?"6l009j6`>d98`?>o493:1(<j6:3d8j4b?2m10e?o50;&2`<<5n2d:h54j;:k54?6=,8n268h4n0f;>5=<a<o1<7*>d886b>h6l10:76g:c;29 4b>2<l0b<j7:398m0d=83.:h44:f:l2`=<432c>m7>5$0f:>0`<f8n36954i4;94?"6l00>j6`>d986?>o203:1(<j6:4d8j4b?2?10e8950;&2`<<2n2d:h548;:k62?6=,8n268h4n0f;>==<a<?1<7*>d886b>h6l10276g:4;29 4b>2<l0b<j7:`98m05=83.:h44:f:l2`=<e32c>=7>5$0f:>0`<f8n36n54i4294?"6l00>j6`>d98g?>o3n3:1(<j6:4d8j4b?2l10e9k50;&2`<<2n2d:h54i;:k7`?6=,8n268h4n0f;>46<3`>h6=4+1e;91c=i9m21=<54i5`94?"6l00>j6`>d9826>=n<h0;6)?k9;7e?k7c03;876g;9;29 4b>2<l0b<j7:068?l2?290/=i755g9m5a>=9<10e;950;&2`<<2n2d:h54>6:9j23<72-;o57;i;o3g<?7032c=97>5$0f:>0`<f8n36<64;h47>5<#9m319k5a1e:95<=<a?91<7*>d886b>h6l10:m65f6383>!7c13?m7c?k8;3a?>o193:1(<j6:4d8j4b?28i07d;k:18'5a?==o1e=i651e98m04=83.:h44:f:l2`=<6m21b8:4?:%3g=?3a3g;o47?i;:k;5?6=,8n265>4n0f;>5=<a>l1<7*>d88;4>h6l10:76g8d;29 4b>21:0b<j7:398m2e=83.:h4470:l2`=<432c<n7>5$0f:>=6<f8n36954i6c94?"6l003<6`>d986?>o013:1(<j6:928j4b?2?10e:650;&2`<<?82d:h548;:k43?6=,8n265>4n0f;>==<a><1<7*>d88;4>h6l10276g85;29 4b>21:0b<j7:`98m22=83.:h4470:l2`=<e32c<>7>5$0f:>=6<f8n36n54i6394?"6l003<6`>d98g?>o083:1(<j6:928j4b?2l10e;h50;&2`<<?82d:h54i;:k5a?6=,8n265>4n0f;>46<3`<o6=4+1e;9<5=i9m21=<54i7a94?"6l003<6`>d9826>=n>k0;6)?k9;:3?k7c03;876g9a;29 4b>21:0b<j7:068?l0>290/=i75819m5a>=9<10e5650;&2`<<?82d:h54>6:9j<2<72-;o576?;o3g<?7032c3:7>5$0f:>=6<f8n36<64;h:6>5<#9m314=5a1e:95<=<a1>1<7*>d88;4>h6l10:m65f8283>!7c132;7c?k8;3a?>o?:3:1(<j6:928j4b?28i07d9j:18'5a?=091e=i651e98m25=83.:h4470:l2`=<6m21b:54?:%3g=?>73g;o47?i;:k;`?6=,8n265m4n0f;>5=<a1h1<7*>d88;g>h6l10:76g7a;29 4b>21i0b<j7:398m=?=83.:h447c:l2`=<432c2>7>5$0f:><7<f8n36=54i8294?"6l002=6`>d982?>o?n3:1(<j6:838j4b?2;10e5k50;&2`<<>92d:h54<;:k2b6<72-;o57?i2:l2`=<732c:j<4?:%3g=?7a:2d:h54>;:k2b5<72-;o57?i2:l2`=<532c:ik4?:%3g=?7a:2d:h54<;:k2b=<72-;o57?i7:l2`=<732c:j;4?:%3g=?7a?2d:h54>;:k2b0<72-;o57?i7:l2`=<532c:j94?:%3g=?7a?2d:h54<;:mbg?6=,8n26ll4n0f;>5=<ghk1<7*>d88bf>h6l10:76an8;29 4b>2hh0b<j7:398kd1=83.:h44nb:l2`=<432ej:7>5$0f:>dd<f8n36954o`794?"6l00jn6`>d986?>if<3:1(<j6:``8j4b?2?10cl=50;&2`<<fj2d:h548;:mb6?6=,8n26ll4n0f;>==<gh;1<7*>d88bf>h6l10276an0;29 4b>2hh0b<j7:`98k<`=83.:h44nb:l2`=<e32e2h7>5$0f:>dd<f8n36n54o8a94?"6l00jn6`>d98g?>i>j3:1(<j6:``8j4b?2l10c4o50;&2`<<fj2d:h54i;:m:=?6=,8n26ll4n0f;>46<3f336=4+1e;9eg=i9m21=<54o8594?"6l00jn6`>d9826>=h1?0;6)?k9;ca?k7c03;876a65;29 4b>2hh0b<j7:068?j?3290/=i75ac9m5a>=9<10co=50;&2`<<fj2d:h54>6:9lf7<72-;o57om;o3g<?7032ei=7>5$0f:>dd<f8n36<64;n`3>5<#9m31mo5a1e:95<=<ghl1<7*>d88bf>h6l10:m65`ad83>!7c13ki7c?k8;3a?>ifl3:1(<j6:``8j4b?28i07bo6:18'5a?=ik1e=i651e98k<c=83.:h44nb:l2`=<6m21d5>4?:%3g=?ge3g;o47?i;:m`a?6=,8n26nj4n0f;>5=<gji1<7*>d88``>h6l10:76ala;29 4b>2jn0b<j7:398kf?=83.:h44ld:l2`=<432eh47>5$0f:>fb<f8n36954ob594?"6l00hh6`>d986?>id>3:1(<j6:bf8j4b?2?10cn;50;&2`<<dl2d:h548;:m`0?6=,8n26nj4n0f;>==<gj91<7*>d88``>h6l10276al2;29 4b>2jn0b<j7:`98kf7=83.:h44ld:l2`=<e32eij7>5$0f:>fb<f8n36n54ocg94?"6l00hh6`>d98g?>iel3:1(<j6:bf8j4b?2l10com50;&2`<<dl2d:h54i;:maf?6=,8n26nj4n0f;>46<3fhj6=4+1e;9ga=i9m21=<54oc;94?"6l00hh6`>d9826>=hj10;6)?k9;ag?k7c03;876am7;29 4b>2jn0b<j7:068?jd1290/=i75ce9m5a>=9<10ci;50;&2`<<dl2d:h54>6:9l`1<72-;o57mk;o3g<?7032eo?7>5$0f:>fb<f8n36<64;nf1>5<#9m31oi5a1e:95<=<gm;1<7*>d88``>h6l10:m65`d183>!7c13io7c?k8;3a?>idn3:1(<j6:bf8j4b?28i07bmm:18'5a?=km1e=i651e98kf6=83.:h44ld:l2`=<6m21dn84?:%3g=?ec3g;o47?i;:mgf?6=,8n26io4n0f;>5=<gm31<7*>d88ge>h6l10:76ak8;29 4b>2mk0b<j7:398ka1=83.:h44ka:l2`=<432en<7>5$0f:>a`<f8n36=54oeg94?"6l00oj6`>d982?>icl3:1(<j6:ed8j4b?2;10cim50;&2`<<cn2d:h54<;:p717=83=8wS<<2:\004=:9ol1i9521dc97a=:9lk1?h521dc95a`<58oj6<k?;<3fe?7b>27:il4>e69>5`g=:916=ho5229>5`g=:;16=ho5209>5`g=9h16=ho5319>5`g=;:16=ho5339>5`g=;816=ho52`9>5`g=>916=ho55d9>5`g==j16=ho55c9>5`g==h16=ho5589>5`g==116=ho5569>5`g==?16=ho5549>5`g===16=ho5529>5`g==816=ho5519>5`g=<o16=ho54d9>5`g=<m16=ho5649>5`g=0816=ho57g9>5`g=?m16=ho57b9>5`g=?k16=ho57`9>5`g=?016=ho5799>5`g=?>16=ho5779>5`g=?<16=ho5759>5`g=?;16=ho5709>5`g=?916=ho56g9>5`g=>l16=ho5879>5`g=0m16=ho58c9>5`g=0h16=ho5889>5`g=1;16=ho5919>5`g=0o16=ho58d9>5`?=;m16=h753d9>5`?=9ml01<k6:0g3?87b13;n:63>e882a2=:9l31>=521d;966=:9l31>?521d;964=:9l31=l521d;975=:9l31?>521d;977=:9l31?<521d;96d=:9l31:=521d;91`=:9l319n521d;91g=:9l319l521d;91<=:9l3195521d;912=:9l319;521d;910=:9l3199521d;916=:9l319<521d;915=:9l318k521d;90`=:9l314<521d;93c=:9l31;i521d;93f=:9l31;o521d;93d=:9l31;4521d;93==:9l31;:521d;933=:9l31;8521d;931=:9l31;?521d;934=:9l31;=521d;92c=:9l314i521d;9<g=:9l315?521d;9=5=z{:936=4<{_10<>;6mh0n=63>e88f5>{t;:31<7=t^21:?87bi3o970?j9;g1?xu5;90;6>uQ222894cf2=801<k6:508yv4493:1?vP=309>5`g=<:16=h75429~w7cb2909wS<le:?2ad<>02wx>hm50;0xZ7ec34;nm778;|q1ad<72;qU>nl4=0gb><0<uz8n57>52z\1gd=:9lk1585rs3g;>5<5sW8h563>e`8:0>{t:l=1<7<t^3a;?87bi3h87p}=e783>7}Y:j=01<kn:c08yv4b=3:1>vP=c79>5`g=j91v?k;:181[4d=27:il4nf:p6`5=838pR?m;;<3fe?gb3ty9i?4?:3y]6f5<58oj6lj4}r0f5?6=:rT9o?521dc9e<=z{;nm6=4={_0`4>;6mh02i6s|2eg94?4|V;hm70?ja;;0?xu5lm0;6?uQ2cg894c>2m20q~<kc;296~X5jm16=h75989~w7be2909wS<mc:?2a<<>02wx>io50;0xZ7de34;n5778;|q1`<<72;qU>oo4=0g:><0<uz8o47>52z\1f<=:9l31585rs3f4>5<5sW8i463>e88:0>{t:m<1<7<t^3`4?87b13h87p}=f483>7}Y:m>01<k6:c08yv4a<3:1>vP=d29>5`?=l>1v?h<:181[4c:27:i44m1:p6c4=838pR?j>;<3f=?d73ty9j<4?:3y]6a6<58o26lh4}r0e4?6=:rT9ok521d;9e`=z{;om6=4={_0`g>;6m00jh6s|2d`94?4|V;i:70?j9;c:?xu5m90;6?uQ2c4894c>20o0q~<k5;296~X5j<16=h75929~w64a2909wS=?f:?2ad<ei2wx??j50;0xZ66b34;nm7l6;|q06g<72;qU?=m4=0gb>g><uz99m7>52z\04g=:9lk1n:5rs20:>5<5sW9;m63>e`8a2>{t;;21<7<t^22:?87bi3n>7p}<2683>7}Y;9201<kn:e68yv55>3:1>vP<069>5`g=l;1v><::181[57>27:il4k1:p772=838pR>>:;<3fe?b73ty8>>4?:3y]752<58oj6nh4}r116?6=:rT8<>521dc9gg=z{:8;6=4={_135>;6mh0h<6s|30d94?4|V::;70?ja;`6?xu49l0;6?uQ2gd894c>2mn0q~=>d;296~X5nl16=h75bc9~w67d2909wS<id:?2a<<ei2wx?<l50;0xZ7`d34;n57l6;|q05d<72;qU>kl4=0g:>g><uz9:57>52z\1bd=:9l31n:5rs23;>5<5sW8m563>e88a2>{t;8=1<7<t^3d;?87b13n>7p}<3783>7}Y;8?01<k6:e68yv54=3:1>vP<159>5`?=lj1v>=;:181[56;27:i44k3:p765=838pR>?=;<3f=?b53ty8??4?:3y]747<58o26i?4}r105?6=:rT8==521d;9`5=z{:9;6=4={_13`>;6m00hj6s|33a94?4|V::970?j9;aa?xu4:80;6?uQ2g5894c>2j:0q~=>6;296~X5n?16=h75b49~w6212902wS=;4:?2ad<6n:16=ho51g3894cf28l;70?ja;3fb>;6m00:j>521d;95c7<58o26<h?;<3f=?7bn2wx?9750;;xZ62034;nm7?i8:?2ad<6n?16=ho51g7894cf28l?70?j9;3e<>;6m00:j;521d;95c3<58o26<h;;|q15<<72:qU>=k4=0gb>4c<58o26<k4}r023?6=;rT9<i521dc95a=:9l31=i5rs335>5<4sW8;o63>e`82g>;6m00:o6s|20794?5|V;:i70?ja;3a?87b13;i7p}=1583>6}Y:9k01<kn:3;894c>2;30q~<>3;297~X58016=ho5299>5`?=:11v??=:180[47027:il4=7:?2a<<5?2wx><?50;1xZ76034;nm7<9;<3f=?413ty9==4?:2y]650<58oj6?;4=0g:>73<uz8;j7>53z\140=:9lk1>9521d;961=z{;8n6=4<{_017>;6mh09i63>e881a>{t:;i1<7=t^301?87bi38o70?j9;0g?xu5:k0;6>uQ233894cf2;i01<k6:3a8yv45i3:1?vP=219>5`g=:k16=h752c9~w74>2908wS<>f:?2ad<4127:i44<9:p67>=839pR??j;<3fe?5?34;n57=7;|q162<72:qU><j4=0gb>61<58o26>94}r012?6=;rT9=n521dc973=:9l31?;5rs306>5<4sW8:n63>e`801>;6m00896s|23694?5|V;;j70?ja;17?87b139?7p}=6b83>7}Y:=i01<kn:5a8yv41i3:1>vP=4c9>5`g=<k1v?87:181[43127:il4;a:p631=838pR?:7;<3fe?2>3ty9:;4?:3y]611<58oj6964}r051?6=:rT98;521dc922=z{;<?6=4={_071>;6mh0=:6s|27194?4|V;>?70?ja;47?xu5>;0;6?uQ251894cf2?90q~<91;296~X5<;16=ho5639~w7072909wS<;1:?2ad<192wx>8h50;0xZ72734;nm7;k;|q11a<72;qU>>k4=0gb>04<uz8>o7>52z\17a=:9lk18:5rs37a>5<5sW88o63>e88;e>{t:<k1<7<t^31a?87b13>o7p}=5883>7}Y::k01<k6:5a8yv4203:1>vP=389>5`?=<k1v?;8:181[44027:i44;a:p600=838pR?=8;<3f=?2>3ty9984?:3y]660<58o26964}r060?6=:rT9?8521d;922=z{;=86=4={_066>;6m00=:6s|26094?4|V;?:70?j9;::?xu5?80;6?uQ242894c>2??0q~<80;296~X5<o16=h75659~w70a2909wS<;e:?2a<<1;2wx>;k50;0xZ72c34;n578=;|q12a<72;qU>9o4=0g:>37<uz8=57>52z\17c=:9l319i5rs37f>5<5sW88863>e8866>{t:<91<7<t^310?87b13><7p}=ae83>7}Y:1n01<kn:7f8yv4fj3:1>vP=8b9>5`g=>j1v?o6:181[4?i27:il49b:p6d>=838pR?66;<3fe?0f3ty9m:4?:3y]6=><58oj6;74}r0b2?6=:rT94:521dc9<==z{;k>6=4={_0;2>;6mh03;6s|2`694?4|V;2>70?ja;:6?xu5i:0;6?uQ296894cf21>0q~<n2;296~X50:16=ho5829~w7g62909wS<72:?2ad<?:2wx>l>50;0xZ7>634;nm79j;|q1=`<72;qU>:h4=0gb>25<uz82h7>52z\13`=:9lk1:55rs3;`>5<5sW8<h63>e88;b>{t:0h1<7<t^35`?87b13<n7p}=9`83>7}Y:>h01<k6:7f8yv4>13:1>vP=7`9>5`?=>j1v?77:181[40127:i449b:p6<1=838pR?97;<3f=?0f3ty95;4?:3y]621<58o26;74}r0:1?6=:rT9;;521d;9<==z{;h?6=4={_0:7>;6m003;6s|2c194?4|V;3970?j9;:f?xu5j;0;6?uQ283894c>21<0q~<m1;296~X51916=h75849~w7d72909wS<7f:?2a<<?<2wx>lh50;0xZ7>b34;n576<;|q1e`<72;qU>5l4=0g:>=4<uz8jm7>52z\1<5=:9l31;h5rs3;e>5<5sW8<963>e8847>{t:0>1<7<t^357?87b13<37ps|22294?4|V;9;70=m:313?!7bj3;<n6s|27a94?4|V;>h70=m:36`?!7bj3;3:6s|27c94?4|V;>i70=m:36a?!7bj3;2=6s|27:94?4|V;>270=m:36:?!7bj3;2m6s|27594?4|V;>370=m:36;?!7bj3;j96s|27494?4|V;><70=m:364?!7bj3;i<6s|27794?4|V;>=70=m:365?!7bj3;in6s|27694?4|V;>>70=m:366?!7bj3;h:6s|27194?4|V;>?70=m:367?!7bj3;8;6s|27094?4|V;>870=m:360?!7bj3;?>6s|27394?4|V;>970=m:361?!7bj3;?h6s|27294?4|V;>:70=m:362?!7bj3;>:6s|24d94?4|V;>;70=m:363?!7bj3;==6s|24f94?4|V;9n70=m:31f?!7bj3;=o6s|24a94?4|V;9o70=m:31g?!7bj3;<;6s|24`94?4|V;9h70=m:31`?!7bj3;<46s|24c94?4|V;9i70=m:31a?!7bj3;<56s|24;94?4|V;9j70=m:31b?!7bj3;<m6s|24:94?4|V;9270=m:31:?!7bj3;<o6s|24594?4|V;9370=m:31;?!7bj3;<h6s|24494?4|V;9<70=m:314?!7bj3;<i6s|24794?4|V;9=70=m:315?!7bj3;<j6s|24694?4|V;9>70=m:316?!7bj3;3<6s|26194?4|V;?970=m:371?!7bj3;3=6s|26094?4|V;?:70=m:372?!7bj3;3>6s|26394?4|V;?;70=m:373?!7bj3;3?6s|26294?4|V;>m70=m:36e?!7bj3;386s|27d94?4|V;>n70=m:36f?!7bj3;396s|27g94?4|V;>o70=m:36g?!7bj3;3;6s|27f94?4|V;>j70=m:36b?!7bj3;346s|27;94?4|V;9m70=m:31e?!7bj3;356s|24g94?4|V;9?70=m:317?!7bj3;3m6s|24194?4|V;9870=m:310?!7bj3;3n6s|20;94?4|V;:n70=m:32f?!7bj3;3o6s|20594?4|V;:o70=m:32g?!7bj3;3h6s|20494?4|V;:h70=m:32`?!7bj3;3i6s|20794?4|V;:i70=m:32a?!7bj3;3j6s|20694?4|V;:j70=m:32b?!7bj3;2<6s|20194?4|V;:270=m:32:?!7bj3;2>6s|20094?4|V;:370=m:32;?!7bj3;2?6s|20394?4|V;:<70=m:324?!7bj3;286s|20294?4|V;:=70=m:325?!7bj3;296s|21d94?4|V;:>70=m:326?!7bj3;2:6s|32:94?4|V:9370=m:21;?!7bj3;2;6s|35494?4|V:>?70=m:267?!7bj3;246s|2dg94?4|V;in70=m:3af?!7bj3;256s|2da94?4|V;io70=m:3ag?!7bj3;2n6s|2dc94?4|V;ii70=m:3aa?!7bj3;2o6s|2d;94?4|V;ij70=m:3ab?!7bj3;2h6s|2d:94?4|V;i270=m:3a:?!7bj3;2i6s|2d594?4|V;i370=m:3a;?!7bj3;2j6s|2d494?4|V;i<70=m:3a4?!7bj3;j<6s|2d794?4|V;i=70=m:3a5?!7bj3;j=6s|2d694?4|V;i>70=m:3a6?!7bj3;j>6s|2d194?4|V;i?70=m:3a7?!7bj3;j?6s|2d094?4|V;i870=m:3a0?!7bj3;j86s|2d394?4|V;i970=m:3a1?!7bj3;j:6s|2ed94?4|V;i;70=m:3a3?!7bj3;j;6s|2eg94?4|V;hm70=m:3`e?!7bj3;j46s|2ef94?4|V;hn70=m:3`f?!7bj3;j56s|2ea94?4|V;ho70=m:3`g?!7bj3;jm6s|2e`94?4|V;hh70=m:3``?!7bj3;jn6s|2ec94?4|V;hi70=m:3`a?!7bj3;jo6s|2e;94?4|V;hj70=m:3`b?!7bj3;jh6s|2e:94?4|V;h270=m:3`:?!7bj3;ji6s|2e594?4|V;h370=m:3`;?!7bj3;jj6s|2e494?4|V;h<70=m:3`4?!7bj3;i=6s|2g794?4|V;n?70=m:3f7?!7bj3;i>6s|2g694?4|V;n870=m:3f0?!7bj3;i?6s|2g194?4|V;n970=m:3f1?!7bj3;i86s|2g094?4|V;n:70=m:3f2?!7bj3;i96s|2g394?4|V;n;70=m:3f3?!7bj3;i:6s|2g294?4|V;im70=m:3ae?!7bj3;i;6s|2dd94?4|V;ih70=m:3a`?!7bj3;i46s|2d`94?4|V;i:70=m:3a2?!7bj3;i56s|2d294?4|V;h=70=m:3`5?!7bj3;im6s|2e794?4|V;h>70=m:3`6?!7bj3;io6s|22394?4|V;9:70=m:312?!7bj3;ih6s|2`f94?4|V;2o70=m:3:g?!7bj3;ii6s|2``94?4|V;2h70=m:3:`?!7bj3;ij6s|2`;94?4|V;2j70=m:3:b?!7bj3;h<6s|2`:94?4|V;2270=m:3::?!7bj3;h=6s|2`594?4|V;2370=m:3:;?!7bj3;h>6s|2`494?4|V;2<70=m:3:4?!7bj3;h?6s|2`794?4|V;2=70=m:3:5?!7bj3;h86s|2`694?4|V;2>70=m:3:6?!7bj3;h96s|2`194?4|V;2?70=m:3:7?!7bj3;h;6s|2`094?4|V;2870=m:3:0?!7bj3;h46s|2`394?4|V;2970=m:3:1?!7bj3;h56s|2`294?4|V;2:70=m:3:2?!7bj3;hm6s|28g94?4|V;=m70=m:35e?!7bj3;hn6s|28f94?4|V;=n70=m:35f?!7bj3;ho6s|28a94?4|V;=o70=m:35g?!7bj3;hh6s|28`94?4|V;=h70=m:35`?!7bj3;hi6s|28c94?4|V;=i70=m:35a?!7bj3;hj6s|28;94?4|V;=j70=m:35b?!7bj3;o<6s|28:94?4|V;=270=m:35:?!7bj3;846s|28594?4|V;=370=m:35;?!7bj3;856s|28494?4|V;=<70=m:354?!7bj3;8m6s|28794?4|V;==70=m:355?!7bj3;8n6s|2c694?4|V;3870=m:3;0?!7bj3;8o6s|2c194?4|V;3970=m:3;1?!7bj3;8h6s|2c094?4|V;3:70=m:3;2?!7bj3;8i6s|2c394?4|V;3;70=m:3;3?!7bj3;8j6s|2c294?4|V;2m70=m:3:e?!7bj3;?<6s|2`d94?4|V;2n70=m:3:f?!7bj3;?=6s|2`g94?4|V;2i70=m:3:a?!7bj3;??6s|2`c94?4|V;2;70=m:3:3?!7bj3;?86s|28d94?4|V;=>70=m:356?!7bj3;?96s|28694?4|V;=?70=m:357?!7bj3;?:6s|23g94?4|V;8870=m:300?!7bj3;?;6s|23a94?4|V;8970=m:301?!7bj3;?46s|23`94?4|V;8:70=m:302?!7bj3;?56s|23c94?4|V;8;70=m:303?!7bj3;?m6s|23;94?4|V;;m70=m:33e?!7bj3;?n6s|23:94?4|V;;n70=m:33f?!7bj3;?o6s|23594?4|V;;o70=m:33g?!7bj3;?i6s|23494?4|V;;h70=m:33`?!7bj3;?j6s|23794?4|V;;i70=m:33a?!7bj3;><6s|23694?4|V;;j70=m:33b?!7bj3;>=6s|32;94?4|V:9270=m:21:?!7bj3;>>6s|35;94?4|V:><70=m:264?!7bj3;>?6s|33d94?4|V::m70=m:22e?!7bj3;>86s|33f94?4|V::n70=m:22f?!7bj3;>96s|33`94?4|V::h70=m:22`?!7bj3;>;6s|33c94?4|V::i70=m:22a?!7bj3;>46s|33;94?4|V::j70=m:22b?!7bj3;>56s|33:94?4|V::270=m:22:?!7bj3;>m6s|33594?4|V::370=m:22;?!7bj3;>n6s|33494?4|V::<70=m:224?!7bj3;>o6s|33794?4|V::=70=m:225?!7bj3;>h6s|33694?4|V::>70=m:226?!7bj3;>i6s|33194?4|V::?70=m:227?!7bj3;>j6s|33094?4|V::870=m:220?!7bj3;=<6s|33294?4|V:::70=m:222?!7bj3;=>6s|30d94?4|V::;70=m:223?!7bj3;=?6s|30g94?4|V;lm70=m:3de?!7bj3;=86s|30f94?4|V;ln70=m:3df?!7bj3;=96s|30a94?4|V;lo70=m:3dg?!7bj3;=:6s|30`94?4|V;lh70=m:3d`?!7bj3;=;6s|30c94?4|V;li70=m:3da?!7bj3;=46s|30;94?4|V;lj70=m:3db?!7bj3;=56s|30:94?4|V;l270=m:3d:?!7bj3;=m6s|30594?4|V;l370=m:3d;?!7bj3;=n6s|32494?4|V:;>70=m:236?!7bj3;=h6s|32794?4|V:;?70=m:237?!7bj3;=i6s|32694?4|V:;870=m:230?!7bj3;=j6s|32194?4|V:;970=m:231?!7bj3;<<6s|32094?4|V:;:70=m:232?!7bj3;<=6s|32394?4|V:;;70=m:233?!7bj3;<>6s|32294?4|V::o70=m:22g?!7bj3;<?6s|33a94?4|V::970=m:221?!7bj3;<86s|33394?4|V;l<70=m:3d4?!7bj3;<96s|30494?4|V;l=70=m:3d5?!7bj3;<:6srn24g>5<5sA;no6sa37g94?4|@8oh7p`<6g83>7}O9li0qc=80;296~N6mj1vb>9>:181M7bk2we?:<50;0xL4cd3td8;>4?:3yK5`e<ug9<87>52zJ2af=zf:=>6=4={I3fg>{i;><1<7<tH0g`?xh4?>0;6?uG1da8yk5003:1>vF>eb9~j61>2909wE?jc:m72g=838pD<kl;|l03g<72;qC=hm4}o14g?6=:rB:in5rn25g>5<5sA;no6sa36g94?4|@8oh7p`<7g83>7}O9li0qc=70;296~N6mj1vb>6>:181M7bk2we?5<50;0xL4cd3td84>4?:3yK5`e<ug9387>52zJ2af=zf:2>6=4={I3fg>{i;1<1<7<tH0g`?xh40>0;6?uG1da8yk5?03:1>vF>eb9~j6>>2909wE?jc:m7=g=838pD<kl;|l0<g<72;qC=hm4}o1;g?6=:rB:in5rn2:g>5<5sA;no6sa39g94?4|@8oh7p`<8g83>7}O9li0qc=60;296~N6mj1vb>7>:181M7bk2we?4<50;0xL4cd3td85>4?:3yK5`e<ug9287>52zJ2af=zf:3>6=4={I3fg>{i;0<1<7<tH0g`?xh41>0;6?uG1da8yk5>03:1>vF>eb9~j6?>2909wE?jc:m7<g=838pD<kl;|l0=g<72;qC=hm4}o1:g?6=:rB:in5rn2;g>5<5sA;no6sa38g94?4|@8oh7p`<9g83>7}O9li0qc=n0;296~N6mj1vb>o>:181M7bk2we?l<50;0xL4cd3td8m>4?:3yK5`e<ug9j87>52zJ2af=zf:k>6=4={I3fg>{i;h<1<7<tH0g`?xh4i>0;6?uG1da8yk5f03:1>vF>eb9~j6g>2909wE?jc:m7dg=838pD<kl;|l0eg<72;qC=hm4}o1bg?6=:rB:in5rn2cg>5<5sA;no6sa3`g94?4|@8oh7p`<ag83>7}O9li0qc=m0;296~N6mj1vb>l>:181M7bk2we?o<50;0xL4cd3td8n>4?:3yK5`e<ug9i87>52zJ2af=zf:h>6=4={I3fg>{i;k<1<7<tH0g`?xh4j>0;6?uG1da8yk5e03:1>vF>eb9~j6d>2909wE?jc:m7gg=838pD<kl;|l0fg<72;qC=hm4}o1ag?6=:rB:in5rn2`g>5<5sA;no6sa3cg94?4|@8oh7p`<bg83>7}O9li0qc=l0;296~N6mj1vb>m>:181M7bk2we?n<50;0xL4cd3td8o>4?:3yK5`e<ug9h87>52zJ2af=zf:i>6=4={I3fg>{i;j<1<7<tH0g`?xh4k>0;6?uG1da8yk5d03:1>vF>eb9~j6e>2909wE?jc:m7fg=838pD<kl;|l0gg<72;qC=hm4}o1`g?6=:rB:in5rn2ag>5<5sA;no6sa3bg94?4|@8oh7p`<cg83>7}O9li0qc=k0;296~N6mj1vb>j>:181M7bk2we?i<50;0xL4cd3td8h>4?:3yK5`e<ug9o87>52zJ2af=zf:n>6=4={I3fg>{i;m<1<7<tH0g`?xh4l>0;6?uG1da8yk5c03:1>vF>eb9~j6b>2909wE?jc:m7ag=838pD<kl;|l0`g<72;qC=hm4}o1gg?6=:rB:in5rn2fg>5<5sA;no6sa3eg94?4|@8oh7p`<dg83>7}O9li0qc=j0;296~N6mj1vb>k>:181M7bk2we?h<50;0xL4cd3td8i>4?:3yK5`e<ug9n87>52zJ2af=zf:o>6=4={I3fg>{i;l<1<7<tH0g`?xh4m>0;6?uG1da8yk5b03:1>vF>eb9~j6c>2909wE?jc:m7`g=838pD<kl;|l0ag<72;qC=hm4}o1fg?6=:rB:in5rn2gg>5<5sA;no6sa3dg94?4|@8oh7p`<eg83>7}O9li0qc=i0;296~N6mj1vb>h>:181M7bk2we?k<50;0xL4cd3td8j>4?:3yK5`e<ug9m87>52zJ2af=zf:l>6=4={I3fg>{i;o<1<7<tH0g`?xh4n>0;6?uG1da8yk5a03:1>vF>eb9~j6`>2909wE?jc:m7cg=838pD<kl;|l0bg<72;qC=hm4}o1eg?6=:rB:in5rn2dg>5<5sA;no6sa3gg94?4|@8oh7p`<fg83>7}O9li0qc:?0;296~N6mj1vb9>>:181M7bk2we8=<50;0xL4cd3td?<>4?:3yK5`e<ug>;87>52zJ2af=zf=:>6=4={I3fg>{i<9<1<7<tH0g`?xh5l;0;6<uG1da8yx{zHIIp8l<5a76;e5c4uIJIw=sO@Qy~DE \ No newline at end of file diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vhd b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vhd new file mode 100644 index 0000000000000000000000000000000000000000..80684cd1bdaed3da7666fc0238802063f58576d5 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vhd @@ -0,0 +1,145 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- You must compile the wrapper file pattern_blk_mem.vhd when simulating +-- the core, pattern_blk_mem. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + +-- The synthesis directives "translate_off/translate_on" specified +-- below are supported by Xilinx, Mentor Graphics and Synplicity +-- synthesis tools. Ensure they are correct for your synthesis tool(s). + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +-- synthesis translate_off +Library XilinxCoreLib; +-- synthesis translate_on +ENTITY pattern_blk_mem IS + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +END pattern_blk_mem; + +ARCHITECTURE pattern_blk_mem_a OF pattern_blk_mem IS +-- synthesis translate_off +component wrapped_pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; + +-- Configuration specification + for all : wrapped_pattern_blk_mem use entity XilinxCoreLib.blk_mem_gen_v2_8(behavioral) + generic map( + c_has_regceb => 0, + c_has_regcea => 0, + c_mem_type => 2, + c_prim_type => 1, + c_sinita_val => "0", + c_read_width_b => 32, + c_family => "virtex4", + c_read_width_a => 32, + c_disable_warn_bhv_coll => 0, + c_write_mode_b => "NO_CHANGE", + c_init_file_name => "no_coe_file_loaded", + c_write_mode_a => "NO_CHANGE", + c_mux_pipeline_stages => 0, + c_has_mem_output_regs_b => 0, + c_load_init_file => 0, + c_xdevicefamily => "virtex4", + c_has_mem_output_regs_a => 0, + c_write_depth_b => 1024, + c_write_depth_a => 1024, + c_has_ssrb => 0, + c_has_mux_output_regs_b => 0, + c_has_ssra => 0, + c_has_mux_output_regs_a => 0, + c_addra_width => 10, + c_addrb_width => 10, + c_default_data => "0", + c_use_ecc => 0, + c_algorithm => 1, + c_disable_warn_bhv_range => 0, + c_write_width_b => 32, + c_write_width_a => 32, + c_read_depth_b => 1024, + c_read_depth_a => 1024, + c_byte_size => 9, + c_sim_collision_check => "ALL", + c_use_ramb16bwer_rst_bhv => 0, + c_common_clk => 0, + c_wea_width => 1, + c_has_enb => 1, + c_web_width => 1, + c_has_ena => 1, + c_sinitb_val => "0", + c_use_byte_web => 0, + c_use_byte_wea => 0, + c_use_default_data => 1); +-- synthesis translate_on +BEGIN +-- synthesis translate_off +U0 : wrapped_pattern_blk_mem + port map ( + clka => clka, + dina => dina, + addra => addra, + ena => ena, + wea => wea, + douta => douta, + clkb => clkb, + dinb => dinb, + addrb => addrb, + enb => enb, + web => web, + doutb => doutb); +-- synthesis translate_on + +END pattern_blk_mem_a; + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vho b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vho new file mode 100644 index 0000000000000000000000000000000000000000..6c359283052d21874b2a497576e7a99728645a64 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.vho @@ -0,0 +1,74 @@ +-------------------------------------------------------------------------------- +-- This file is owned and controlled by Xilinx and must be used -- +-- solely for design, simulation, implementation and creation of -- +-- design files limited to Xilinx devices or technologies. Use -- +-- with non-Xilinx devices or technologies is expressly prohibited -- +-- and immediately terminates your license. -- +-- -- +-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" -- +-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR -- +-- XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION -- +-- AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION -- +-- OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS -- +-- IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, -- +-- AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE -- +-- FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY -- +-- WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE -- +-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR -- +-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF -- +-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- +-- FOR A PARTICULAR PURPOSE. -- +-- -- +-- Xilinx products are not intended for use in life support -- +-- appliances, devices, or systems. Use in such applications are -- +-- expressly prohibited. -- +-- -- +-- (c) Copyright 1995-2007 Xilinx, Inc. -- +-- All rights reserved. -- +-------------------------------------------------------------------------------- +-- The following code must appear in the VHDL architecture header: + +------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG +component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; + +-- COMP_TAG_END ------ End COMPONENT Declaration ------------ + +-- The following code must appear in the VHDL architecture +-- body. Substitute your own instance name and net names. + +------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG +your_instance_name : pattern_blk_mem + port map ( + clka => clka, + dina => dina, + addra => addra, + ena => ena, + wea => wea, + douta => douta, + clkb => clkb, + dinb => dinb, + addrb => addrb, + enb => enb, + web => web, + doutb => doutb); +-- INST_TAG_END ------ End INSTANTIATION Template ------------ + +-- You must compile the wrapper file pattern_blk_mem.vhd when simulating +-- the core, pattern_blk_mem. When compiling the wrapper file, be sure to +-- reference the XilinxCoreLib VHDL simulation library. For detailed +-- instructions, please refer to the "CORE Generator Help". + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.xco b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.xco new file mode 100644 index 0000000000000000000000000000000000000000..ef82ce5d639c037d9e3bd2816d3096049c4474e7 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem.xco @@ -0,0 +1,78 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Mon Aug 17 20:38:30 2009 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator family Xilinx,_Inc. 2.8 +# END Select +# BEGIN Parameters +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=false +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=pattern_blk_mem +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET enable_a=Use_ENA_Pin +CSET enable_b=Use_ENB_Pin +CSET fill_remaining_memory_locations=true +CSET load_init_file=false +CSET memory_type=True_Dual_Port_RAM +CSET operating_mode_a=NO_CHANGE +CSET operating_mode_b=NO_CHANGE +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET primitive=8kx2 +CSET read_width_a=32 +CSET read_width_b=32 +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET remaining_memory_locations=0 +CSET single_bit_ecc=false +CSET use_byte_write_enable=false +CSET use_ramb16bwer_reset_behavior=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_ssra_pin=false +CSET use_ssrb_pin=false +CSET write_depth_a=1024 +CSET write_width_a=32 +CSET write_width_b=32 +# END Parameters +GENERATE +# CRC: d212e058 + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt new file mode 100644 index 0000000000000000000000000000000000000000..b4dcf62f44ce3b9683995963171a0511d4440ccd --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<document OS="lin" product="ISE" version="10.1.03"> + + <!--The data in this file is primarily intended for consumption by Xilinx tools. + The structure and the elements are likely to change over the next few releases. + This means code written to parse this file will need to be revisited each subsequent release.--> + + <application stringID="Xst" timeStamp="Mon Aug 17 13:37:53 2009"> + <section stringID="XST_ADVANCED_HDL_SYNTHESIS_REPORTFOUND_NO_MACRO"/> + <section stringID="XST_FINAL_REGISTER_REPORTFOUND_NO_MACRO"/> + <section stringID="XST_PARTITION_REPORT"> + <section stringID="XST_PARTITION_IMPLEMENTATION_STATUS"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + </section> + <section stringID="XST_FINAL_REPORT"> + <section stringID="XST_FINAL_RESULTS"> + <item stringID="XST_TOP_LEVEL_OUTPUT_FILE_NAME" value="/afs/slac/u/ec/kocian/minilat/xilinx/BnlAsic/xil_cores/tmp/_cg/pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc"/> + <item stringID="XST_OUTPUT_FORMAT" value="NGC"/> + <item stringID="XST_OPTIMIZATION_GOAL" value="SPEED"/> + <item stringID="XST_KEEP_HIERARCHY" value="no"/> + </section> + <section stringID="XST_DESIGN_STATISTICS"> + <item stringID="XST_IOS" value="160"/> + </section> + <section stringID="XST_CELL_USAGE"> + <item dataType="int" stringID="XST_BELS" value="1"> + <item dataType="int" stringID="XST_GND" value="1"/> + </item> + <item dataType="int" stringID="XST_RAMS" value="2"></item> + </section> + </section> + <section stringID="XST_DEVICE_UTILIZATION_SUMMARY"> + <item stringID="XST_SELECTED_DEVICE" value="4vfx60ff672-12"/> + <item AVAILABLE="25280" dataType="int" stringID="XST_NUMBER_OF_SLICES" value="0"/> + <item dataType="int" stringID="XST_NUMBER_OF_IOS" value="160"/> + <item AVAILABLE="352" dataType="int" stringID="XST_NUMBER_OF_BONDED_IOBS" value="0"/> + </section> + <section stringID="XST_PARTITION_RESOURCE_SUMMARY"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + <section stringID="XST_ERRORS_STATISTICS"> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_ERRORS" value="0"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_WARNINGS" value="112"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_INFOS" value="15"/> + </section> + </application> + +</document> diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_flist.txt b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_flist.txt new file mode 100644 index 0000000000000000000000000000000000000000..6bfdd4350080accf4179ecac72b9f49254948ecf --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_flist.txt @@ -0,0 +1,8 @@ +# Output products list for <pattern_blk_mem> +pattern_blk_mem.ngc +pattern_blk_mem.vhd +pattern_blk_mem.vho +pattern_blk_mem.xco +pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt +pattern_blk_mem_flist.txt +pattern_blk_mem_xmdf.tcl diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_readme.txt b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..e4f5cebb498f90223bd13eaa4fbfb093ae3af8d6 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_readme.txt @@ -0,0 +1,39 @@ +The following files were generated for 'pattern_blk_mem' in directory +/a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores/: + +pattern_blk_mem.ngc: + Binary Xilinx implementation netlist file containing the information + required to implement the module in a Xilinx (R) FPGA. + +pattern_blk_mem.vhd: + VHDL wrapper file provided to support functional simulation. This + file contains simulation model customization data that is passed to + a parameterized simulation model for the core. + +pattern_blk_mem.vho: + VHO template file containing code that can be used as a model for + instantiating a CORE Generator module in a VHDL design. + +pattern_blk_mem.xco: + CORE Generator input file containing the parameters used to + regenerate a core. + +pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt: + Please see the core data sheet. + +pattern_blk_mem_flist.txt: + Text file listing all of the output files produced when a customized + core was generated in the CORE Generator. + +pattern_blk_mem_readme.txt: + Text file indicating the files generated and how they are used. + +pattern_blk_mem_xmdf.tcl: + ISE Project Navigator interface file. ISE uses this file to determine + how the files output by CORE Generator for the core can be integrated + into your ISE project. + + +Please see the Xilinx CORE Generator online help for further details on +generated files and how to use them. + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_xmdf.tcl b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_xmdf.tcl new file mode 100644 index 0000000000000000000000000000000000000000..d1919217c09ad0d9c6fd841375c62c188faac5f0 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/pattern_blk_mem_xmdf.tcl @@ -0,0 +1,68 @@ +# The package naming convention is <core_name>_xmdf +package provide pattern_blk_mem_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::pattern_blk_mem_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::pattern_blk_mem_xmdf::xmdfInit { instance } { +# Variable containg name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name pattern_blk_mem +} +# ::pattern_blk_mem_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::pattern_blk_mem_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be magically +# available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem.vhd +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem.vho +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path pattern_blk_mem_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module pattern_blk_mem +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter.xco b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter.xco new file mode 100644 index 0000000000000000000000000000000000000000..19b7548f25bc3525729a570b5be950bb85559414 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter.xco @@ -0,0 +1,78 @@ +############################################################## +# +# Xilinx Core Generator version K.39 +# Date: Tue Sep 1 16:45:51 2009 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = False +SET asysymbol = False +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = False +SET designentry = VHDL +SET device = xc4vfx60 +SET devicefamily = virtex4 +SET flowvendor = Other +SET formalverification = False +SET foundationsym = False +SET implementationfiletype = Ngc +SET package = ff1152 +SET removerpms = False +SET simulationfiles = Behavioral +SET speedgrade = -10 +SET verilogsim = False +SET vhdlsim = True +# END Project Options +# BEGIN Select +SELECT Block_Memory_Generator family Xilinx,_Inc. 2.8 +# END Select +# BEGIN Parameters +CSET algorithm=Minimum_Area +CSET assume_synchronous_clk=false +CSET byte_size=9 +CSET coe_file=no_coe_file_loaded +CSET collision_warnings=ALL +CSET component_name=wordcounter +CSET disable_collision_warnings=false +CSET disable_out_of_range_warnings=false +CSET ecc=false +CSET enable_a=Always_Enabled +CSET enable_b=Always_Enabled +CSET fill_remaining_memory_locations=false +CSET load_init_file=false +CSET memory_type=Simple_Dual_Port_RAM +CSET operating_mode_a=READ_FIRST +CSET operating_mode_b=READ_FIRST +CSET output_reset_value_a=0 +CSET output_reset_value_b=0 +CSET pipeline_stages=0 +CSET primitive=8kx2 +CSET read_width_a=64 +CSET read_width_b=64 +CSET register_porta_output_of_memory_core=false +CSET register_porta_output_of_memory_primitives=false +CSET register_portb_output_of_memory_core=false +CSET register_portb_output_of_memory_primitives=false +CSET remaining_memory_locations=0 +CSET single_bit_ecc=false +CSET use_byte_write_enable=false +CSET use_ramb16bwer_reset_behavior=false +CSET use_regcea_pin=false +CSET use_regceb_pin=false +CSET use_ssra_pin=false +CSET use_ssrb_pin=false +CSET write_depth_a=2 +CSET write_width_a=64 +CSET write_width_b=64 +# END Parameters +GENERATE +# CRC: 2d2b874a + diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt new file mode 100644 index 0000000000000000000000000000000000000000..0468ac4c8e0d205b1b69c87295a48ebc8348a2a1 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<document OS="lin" product="ISE" version="10.1.03"> + + <!--The data in this file is primarily intended for consumption by Xilinx tools. + The structure and the elements are likely to change over the next few releases. + This means code written to parse this file will need to be revisited each subsequent release.--> + + <application stringID="Xst" timeStamp="Tue Sep 1 09:45:16 2009"> + <section stringID="XST_ADVANCED_HDL_SYNTHESIS_REPORTFOUND_NO_MACRO"/> + <section stringID="XST_FINAL_REGISTER_REPORTFOUND_NO_MACRO"/> + <section stringID="XST_PARTITION_REPORT"> + <section stringID="XST_PARTITION_IMPLEMENTATION_STATUS"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + </section> + <section stringID="XST_FINAL_REPORT"> + <section stringID="XST_FINAL_RESULTS"> + <item stringID="XST_TOP_LEVEL_OUTPUT_FILE_NAME" value="/afs/slac/u/ec/kocian/minilat/xilinx/BnlAsic/xil_cores/tmp/_cg/wordcounter_blk_mem_gen_v2_8_xst_1.ngc"/> + <item stringID="XST_OUTPUT_FORMAT" value="NGC"/> + <item stringID="XST_OPTIMIZATION_GOAL" value="SPEED"/> + <item stringID="XST_KEEP_HIERARCHY" value="no"/> + </section> + <section stringID="XST_DESIGN_STATISTICS"> + <item stringID="XST_IOS" value="270"/> + </section> + <section stringID="XST_CELL_USAGE"> + <item dataType="int" stringID="XST_BELS" value="2"> + <item dataType="int" stringID="XST_GND" value="1"/> + <item dataType="int" stringID="XST_VCC" value="1"/> + </item> + <item dataType="int" stringID="XST_RAMS" value="2"></item> + </section> + </section> + <section stringID="XST_DEVICE_UTILIZATION_SUMMARY"> + <item stringID="XST_SELECTED_DEVICE" value="4vfx60ff672-12"/> + <item AVAILABLE="25280" dataType="int" stringID="XST_NUMBER_OF_SLICES" value="0"/> + <item dataType="int" stringID="XST_NUMBER_OF_IOS" value="270"/> + <item AVAILABLE="352" dataType="int" stringID="XST_NUMBER_OF_BONDED_IOBS" value="0"/> + </section> + <section stringID="XST_PARTITION_RESOURCE_SUMMARY"> + <section stringID="XST_NO_PARTITIONS_WERE_FOUND_IN_THIS_DESIGN"/> + </section> + <section stringID="XST_ERRORS_STATISTICS"> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_ERRORS" value="0"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_WARNINGS" value="137"/> + <item dataType="int" filtered="0" stringID="XST_NUMBER_OF_INFOS" value="13"/> + </section> + </application> + +</document> diff --git a/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_xmdf.tcl b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_xmdf.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ecab791995b4cb9cf21caa7b2010b710b712e373 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/coregen/wordcounter_xmdf.tcl @@ -0,0 +1,68 @@ +# The package naming convention is <core_name>_xmdf +package provide wordcounter_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::wordcounter_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::wordcounter_xmdf::xmdfInit { instance } { +# Variable containg name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name wordcounter +} +# ::wordcounter_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::wordcounter_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be magically +# available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter.vhd +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter.vho +utilities_xmdf::xmdfSetData $instance FileSet $fcount type vhdl_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter_blk_mem_gen_v2_8_xst_1.ngc_xst.xrpt +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path wordcounter_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module wordcounter +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf new file mode 120000 index 0000000000000000000000000000000000000000..3629005078201b79547571520b77383a2bf55f2d --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf @@ -0,0 +1 @@ +IBLcableTester.ucf.cable.newHSIO \ No newline at end of file diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.newHSIO b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.newHSIO new file mode 100644 index 0000000000000000000000000000000000000000..0eb4ae2ebad1a2d78d0892c0fa8d7e2a4c3c689f --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.newHSIO @@ -0,0 +1,460 @@ +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : BnlAsic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +NET clk80 TNM_NET = FFS clk80; +NET clk40 TNM_NET = FFS clk40; +NET "U_IBLcableTesterCore/phaseclk" TNM_NET = "U_BnlAsicCore_phaseclk"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 156.25 Mhz HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 39.0625 Mhz HIGH 50%; +TIMESPEC TS_clk80 = PERIOD clk80 78.125 Mhz HIGH 50%; +TIMESPEC TS_clk40 = PERIOD clk40 39.0625 Mhz HIGH 50%; +TIMESPEC TS_phaseclk = PERIOD "U_BnlAsicCore_phaseclk" 78.125 Mhz HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_clk80_r = RISING clk80; +TIMEGRP TG_clk40_r = RISING clk40; + +# Inter Domain Constraints +TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +TIMESPEC TS_clk40_r_clk80_r = FROM TG_clk40_r TO TG_clk80_r 12.8ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; +timespec ts_02 = from ffs(*bz(0):*cz(0):*dz(0):*dz(1)) to ffs 640 MHz; +NET serialinb(*) maxskew = 250 ps ; +INST "U_IBLcableTesterCore/*U_pattern_mem/*receivedata/ff_*" IOB=FALSE; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +NET "iMainClkP" LOC = "H17"; +NET "iMainClkN" LOC = "J17"; +#fiber 1 +#NET "iMgtRxN" LOC = "N1"; +#NET "iMgtRxP" LOC = "M1"; +#NET "oMgtTxN" LOC = "T1"; +#NET "oMgtTxP" LOC = "R1"; +#fiber 2 +NET "iMgtRxN" LOC = "AA1"; +NET "iMgtRxP" LOC = "Y1"; +NET "oMgtTxN" LOC = "V1"; +NET "oMgtTxP" LOC = "U1"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +NET "oDebug(0)" LOC = "n10"; +NET "oDebug(1)" LOC = "n9"; +NET "oDebug(2)" LOC = "n8"; +NET "oDebug(3)" LOC = "n7"; +NET "oDebug(4)" LOC = "j6"; +NET "oDebug(5)" LOC = "k6"; +NET "oDebug(6)" LOC = "l6"; +NET "oDebug(7)" LOC = "l5"; +NET "oDebug(8)" LOC = "k4"; +NET "oDebug(9)" LOC = "k3"; +NET "oDebug(10)" LOC = "l4"; +NET "oDebug(11)" LOC = "l3"; +NET "oDebug(12)" LOC = "m6"; +NET "oDebug(13)" LOC = "m5"; +NET "oDebug(14)" LOC = "m3"; +NET "oDebug(15)" LOC = "n3"; +#NET "doricreset" LOC = "R26"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AK4"; +#NET "clkout40" LOC = "F5"; +#NET "clkout40" IOSTANDARD="LVCMOS25"; +#NET "clkout40" SLEW="FAST"; +#NET "oClock40" SLEW="FAST"; +#NET "oClock40" LOC = "L4"; +#NET "oClock40" IOSTANDARD="LVCMOS25"; +#NET "oClk160_p" LOC = "T5"; +#NET "oClk160_n" LOC = "T4"; +##NET "oClk40_p" LOC = "P7"; +##NET "oClk40_n" LOC = "P6"; +#NET "iClock160_p" LOC = "J6"; +#NET "iClock160_n" LOC = "K6"; +#NET "iClock160_p" IOSTANDARD="ULVDS_25"; +#NET "iClock160_n" IOSTANDARD="ULVDS_25"; +#NET "iClock160_p" CLOCK_DEDICATED_ROUTE = FALSE; + +# VDC inputs DTO +NET "serialin_p(0)" LOC = "J25"; +NET "serialin_p(1)" LOC = "E24"; +NET "serialin_p(2)" LOC = "G22"; +NET "serialin_p(3)" LOC = "H24"; +NET "serialin_p(4)" LOC = "AJ16"; +NET "serialin_p(5)" LOC = "AE13"; +NET "serialin_p(6)" LOC = "AF15"; + +# VDC inputs DTO2 +NET "serialin_p(7)" LOC = "AH15"; +NET "serialin_p(8)" LOC = "AC12"; +NET "serialin_p(9)" LOC = "AG13"; +NET "serialin_p(10)" LOC = "AD11"; +NET "serialin_p(11)" LOC = "AD10"; +NET "serialin_p(12)" LOC = "AE14"; +NET "serialin_p(13)" LOC = "AB11"; +NET "serialin_p(14)" LOC = "AD14"; +NET "serialin_p(15)" LOC = "AB13"; + +# CMD receive +NET "serialin_p(16)" LOC = "N30"; +NET "serialin_p(17)" LOC = "N29"; +NET "serialin_p(18)" LOC = "L29"; +NET "serialin_p(19)" LOC = "R29"; +NET "serialin_p(20)" LOC = "N27"; +NET "serialin_p(21)" LOC = "M32"; +NET "serialin_p(22)" LOC = "G32"; +NET "serialin_p(23)" LOC = "K29"; +# CLK receive +NET "serialin_p(24)" LOC = "P32"; +NET "serialin_p(25)" LOC = "P31"; +NET "serialin_p(26)" LOC = "R32"; +NET "serialin_p(27)" LOC = "R28"; +NET "serialin_p(28)" LOC = "K32"; +NET "serialin_p(29)" LOC = "L31"; +NET "serialin_p(30)" LOC = "E32"; +NET "serialin_p(31)" LOC = "J32"; + +# VDC inputs DTO +NET "serialin_n(0)" LOC = "H25"; +NET "serialin_n(1)" LOC = "F24"; +NET "serialin_n(2)" LOC = "H22"; +NET "serialin_n(3)" LOC = "J24"; +NET "serialin_n(4)" LOC = "AK16"; +NET "serialin_n(5)" LOC = "AF13"; +NET "serialin_n(6)" LOC = "AG15"; +NET "serialin_n(7)" LOC = "AJ15"; + + +# VDC inputs DTO2 +NET "serialin_n(8)" LOC = "AB12"; +NET "serialin_n(9)" LOC = "AH13"; +NET "serialin_n(10)" LOC = "AE11"; +NET "serialin_n(11)" LOC = "AD9"; +NET "serialin_n(12)" LOC = "AF14"; +NET "serialin_n(13)" LOC = "AA11"; +NET "serialin_n(14)" LOC = "AC13"; +NET "serialin_n(15)" LOC = "AA13"; + +# CMD receive +NET "serialin_n(16)" LOC = "M30"; +NET "serialin_n(17)" LOC = "N28"; +NET "serialin_n(18)" LOC = "L28"; +NET "serialin_n(19)" LOC = "P29"; +NET "serialin_n(20)" LOC = "M28"; +NET "serialin_n(21)" LOC = "M31"; +NET "serialin_n(22)" LOC = "G31"; +NET "serialin_n(23)" LOC = "J29"; + +# CLK receive +NET "serialin_n(24)" LOC = "N32"; +NET "serialin_n(25)" LOC = "P30"; +NET "serialin_n(26)" LOC = "R31"; +NET "serialin_n(27)" LOC = "R27"; +NET "serialin_n(28)" LOC = "K31"; +NET "serialin_n(29)" LOC = "L30"; +NET "serialin_n(30)" LOC = "F31"; +NET "serialin_n(31)" LOC = "H32"; + + +# OUTPUTS + +# Data outputs DTO +NET "serialout_p(0)" LOC = "AF9"; +NET "serialout_p(1)" LOC = "AG12"; +NET "serialout_p(2)" LOC = "AL10"; +NET "serialout_p(3)" LOC = "AF10"; +NET "serialout_p(4)" LOC = "AL9"; +NET "serialout_p(5)" LOC = "AH14"; +NET "serialout_p(6)" LOC = "AL11"; +NET "serialout_p(7)" LOC = "AH10"; +NET "serialout_p(8)" LOC = "AK13"; +NET "serialout_p(9)" LOC = "AJ12"; +NET "serialout_p(10)" LOC = "AK14"; +NET "serialout_p(11)" LOC = "AH8"; +NET "serialout_p(12)" LOC = "AM8"; +NET "serialout_p(13)" LOC = "AJ9"; +NET "serialout_p(14)" LOC = "AM13"; +NET "serialout_p(15)" LOC = "AK7"; + + + +# CMD output +NET "serialout_p(16)" LOC = "K26"; +NET "serialout_p(17)" LOC = "D21"; +NET "serialout_p(18)" LOC = "P22"; +NET "serialout_p(19)" LOC = "E19"; +NET "serialout_p(20)" LOC = "L21"; +NET "serialout_p(21)" LOC = "L26"; +NET "serialout_p(22)" LOC = "P24"; +NET "serialout_p(23)" LOC = "K24"; + +# CLK output +NET "serialout_p(24)" LOC = "D30"; +NET "serialout_p(25)" LOC = "D29"; +NET "serialout_p(26)" LOC = "M26"; +NET "serialout_p(27)" LOC = "D32"; +NET "serialout_p(28)" LOC = "E31"; +NET "serialout_p(29)" LOC = "H28"; +NET "serialout_p(30)" LOC = "G30"; +NET "serialout_p(31)" LOC = "H30"; + + +# Data outputs DTO +NET "serialout_n(0)" LOC = "AE9"; +NET "serialout_n(1)" LOC = "AH12"; +NET "serialout_n(2)" LOC = "AM10"; +NET "serialout_n(3)" LOC = "AG10"; +NET "serialout_n(4)" LOC = "AK9"; +NET "serialout_n(5)" LOC = "AJ14"; +NET "serialout_n(6)" LOC = "AM11"; +NET "serialout_n(7)" LOC = "AJ10"; +NET "serialout_n(8)" LOC = "AL13"; +NET "serialout_n(9)" LOC = "AK12"; +NET "serialout_n(10)" LOC = "AL14"; +NET "serialout_n(11)" LOC = "AH7"; +NET "serialout_n(12)" LOC = "AM7"; +NET "serialout_n(13)" LOC = "AH9"; +NET "serialout_n(14)" LOC = "AM12"; +NET "serialout_n(15)" LOC = "AJ7"; + + + +# CMD output +NET "serialout_n(16)" LOC = "J26"; +NET "serialout_n(17)" LOC = "E21"; +NET "serialout_n(18)" LOC = "N22"; +NET "serialout_n(19)" LOC = "F19"; +NET "serialout_n(20)" LOC = "M22"; +NET "serialout_n(21)" LOC = "L25"; +NET "serialout_n(22)" LOC = "N24"; +NET "serialout_n(23)" LOC = "L24"; + +# CLK output +NET "serialout_n(24)" LOC = "C30"; +NET "serialout_n(25)" LOC = "C29"; +NET "serialout_n(26)" LOC = "M25"; +NET "serialout_n(27)" LOC = "C32"; +NET "serialout_n(28)" LOC = "D31"; +NET "serialout_n(29)" LOC = "H27"; +NET "serialout_n(30)" LOC = "F30"; +NET "serialout_n(31)" LOC = "H29"; + +#-----------------------------------------------------------------------------; +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; +NET "oDebug(0)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(1)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(2)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(3)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(4)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(5)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(6)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(7)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(8)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(9)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(10)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(11)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(12)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(13)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(14)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(15)" IOSTANDARD = "LVCMOS25"; +NET "doricreset" IOSTANDARD = "LVCMOS25"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(17)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(21)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(24)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(25)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(26)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(27)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(28)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(29)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(30)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(31)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(17)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(21)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(23)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(24)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(25)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(26)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(27)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(28)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(29)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(30)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(31)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(20)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(24)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(25)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(26)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(27)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(28)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(29)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(30)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(31)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(20)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(24)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(25)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(26)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(27)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(28)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(29)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(30)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(31)" IOSTANDARD = "LVDS_25"; + +#NET "clk40" IOSTANDARD = "LVCMOS25"; +#NET "rclk" IOSTANDARD = "LVCMOS25"; +NET "transDis1" IOSTANDARD = "LVCMOS25"; +#NET "clk40" SLEW = "FAST"; +#NET "rclk" SLEW = "FAST"; + + +#----------------------------------------------------------------------------- +#-------------------------- Logic Location Constraints ----------------------- +#----------------------------------------------------------------------------- +#INST "U_BnlAsicCore/U_AsicControl/U_ClockGen" AREA_GROUP = "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" ; +#AREA_GROUP "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" RANGE = SLICE_X52Y93:SLICE_X66Y29 ; + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.oldHSIO b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.oldHSIO new file mode 100644 index 0000000000000000000000000000000000000000..5728a6faac9ac2dfa60c851632fdce3160a011b4 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.cable.oldHSIO @@ -0,0 +1,457 @@ +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : BnlAsic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +NET clk80 TNM_NET = FFS clk80; +NET clk40 TNM_NET = FFS clk40; +NET "U_IBLcableTesterCore/phaseclk" TNM_NET = "U_BnlAsicCore_phaseclk"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 156.25 Mhz HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 39.0625 Mhz HIGH 50%; +TIMESPEC TS_clk80 = PERIOD clk80 78.125 Mhz HIGH 50%; +TIMESPEC TS_clk40 = PERIOD clk40 39.0625 Mhz HIGH 50%; +TIMESPEC TS_phaseclk = PERIOD "U_BnlAsicCore_phaseclk" 78.125 Mhz HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_clk80_r = RISING clk80; +TIMEGRP TG_clk40_r = RISING clk40; + +# Inter Domain Constraints +TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +TIMESPEC TS_clk40_r_clk80_r = FROM TG_clk40_r TO TG_clk80_r 12.8ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +NET "iMainClkP" LOC = "H17"; +NET "iMainClkN" LOC = "J17"; +#fiber 1 +#NET "iMgtRxN" LOC = "N1"; +#NET "iMgtRxP" LOC = "M1"; +#NET "oMgtTxN" LOC = "T1"; +#NET "oMgtTxP" LOC = "R1"; +#fiber 2 +NET "iMgtRxN" LOC = "AA1"; +NET "iMgtRxP" LOC = "Y1"; +NET "oMgtTxN" LOC = "V1"; +NET "oMgtTxP" LOC = "U1"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +NET "oDebug(0)" LOC = "n10"; +NET "oDebug(1)" LOC = "n9"; +NET "oDebug(2)" LOC = "n8"; +NET "oDebug(3)" LOC = "n7"; +NET "oDebug(4)" LOC = "j6"; +NET "oDebug(5)" LOC = "k6"; +NET "oDebug(6)" LOC = "l6"; +NET "oDebug(7)" LOC = "l5"; +NET "oDebug(8)" LOC = "k4"; +NET "oDebug(9)" LOC = "k3"; +NET "oDebug(10)" LOC = "l4"; +NET "oDebug(11)" LOC = "l3"; +NET "oDebug(12)" LOC = "m6"; +NET "oDebug(13)" LOC = "m5"; +NET "oDebug(14)" LOC = "m3"; +NET "oDebug(15)" LOC = "n3"; +#NET "doricreset" LOC = "R26"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +NET "transDis1" LOC = "AE27"; +#NET "clkout40" LOC = "F5"; +#NET "clkout40" IOSTANDARD="LVCMOS25"; +#NET "clkout40" SLEW="FAST"; +#NET "oClock40" SLEW="FAST"; +#NET "oClock40" LOC = "L4"; +#NET "oClock40" IOSTANDARD="LVCMOS25"; +#NET "oClk160_p" LOC = "T5"; +#NET "oClk160_n" LOC = "T4"; +##NET "oClk40_p" LOC = "P7"; +##NET "oClk40_n" LOC = "P6"; +#NET "iClock160_p" LOC = "J6"; +#NET "iClock160_n" LOC = "K6"; +#NET "iClock160_p" IOSTANDARD="ULVDS_25"; +#NET "iClock160_n" IOSTANDARD="ULVDS_25"; +#NET "iClock160_p" CLOCK_DEDICATED_ROUTE = FALSE; + +# VDC inputs DTO +NET "serialin_p(0)" LOC = "J25"; +NET "serialin_p(1)" LOC = "E24"; +NET "serialin_p(2)" LOC = "G22"; +NET "serialin_p(3)" LOC = "H24"; +NET "serialin_p(4)" LOC = "AJ16"; +NET "serialin_p(5)" LOC = "AE13"; +NET "serialin_p(6)" LOC = "AF15"; + +# VDC inputs DTO2 +NET "serialin_p(7)" LOC = "AH15"; +NET "serialin_p(8)" LOC = "AC12"; +NET "serialin_p(9)" LOC = "AG13"; +NET "serialin_p(10)" LOC = "AD11"; +NET "serialin_p(11)" LOC = "AD10"; +NET "serialin_p(12)" LOC = "AE14"; +NET "serialin_p(13)" LOC = "AB11"; +NET "serialin_p(14)" LOC = "AD14"; +NET "serialin_p(15)" LOC = "AB13"; + +# CMD receive +NET "serialin_p(16)" LOC = "N30"; +NET "serialin_p(17)" LOC = "N29"; +NET "serialin_p(18)" LOC = "L29"; +NET "serialin_p(19)" LOC = "R29"; +NET "serialin_p(20)" LOC = "N27"; +NET "serialin_p(21)" LOC = "M32"; +NET "serialin_p(22)" LOC = "G32"; +NET "serialin_p(23)" LOC = "K29"; +# CLK receive +NET "serialin_p(24)" LOC = "P32"; +NET "serialin_p(25)" LOC = "P31"; +NET "serialin_p(26)" LOC = "R32"; +NET "serialin_p(27)" LOC = "R28"; +NET "serialin_p(28)" LOC = "K32"; +NET "serialin_p(29)" LOC = "L31"; +NET "serialin_p(30)" LOC = "E32"; +NET "serialin_p(31)" LOC = "J32"; + +# VDC inputs DTO +NET "serialin_n(0)" LOC = "H25"; +NET "serialin_n(1)" LOC = "F24"; +NET "serialin_n(2)" LOC = "H22"; +NET "serialin_n(3)" LOC = "J24"; +NET "serialin_n(4)" LOC = "AK16"; +NET "serialin_n(5)" LOC = "AF13"; +NET "serialin_n(6)" LOC = "AG15"; +NET "serialin_n(7)" LOC = "AJ15"; + + +# VDC inputs DTO2 +NET "serialin_n(8)" LOC = "AB12"; +NET "serialin_n(9)" LOC = "AH13"; +NET "serialin_n(10)" LOC = "AE11"; +NET "serialin_n(11)" LOC = "AD9"; +NET "serialin_n(12)" LOC = "AF14"; +NET "serialin_n(13)" LOC = "AA11"; +NET "serialin_n(14)" LOC = "AC13"; +NET "serialin_n(15)" LOC = "AA13"; + +# CMD receive +NET "serialin_n(16)" LOC = "M30"; +NET "serialin_n(17)" LOC = "N28"; +NET "serialin_n(18)" LOC = "L28"; +NET "serialin_n(19)" LOC = "P29"; +NET "serialin_n(20)" LOC = "M28"; +NET "serialin_n(21)" LOC = "M31"; +NET "serialin_n(22)" LOC = "G31"; +NET "serialin_n(23)" LOC = "J29"; + +# CLK receive +NET "serialin_n(24)" LOC = "N32"; +NET "serialin_n(25)" LOC = "P30"; +NET "serialin_n(26)" LOC = "R31"; +NET "serialin_n(27)" LOC = "R27"; +NET "serialin_n(28)" LOC = "K31"; +NET "serialin_n(29)" LOC = "L30"; +NET "serialin_n(30)" LOC = "F31"; +NET "serialin_n(31)" LOC = "H32"; + + +# OUTPUTS + +# Data outputs DTO +NET "serialout_p(0)" LOC = "AF9"; +NET "serialout_p(1)" LOC = "AG12"; +NET "serialout_p(2)" LOC = "AL10"; +NET "serialout_p(3)" LOC = "AF10"; +NET "serialout_p(4)" LOC = "AL9"; +NET "serialout_p(5)" LOC = "AH14"; +NET "serialout_p(6)" LOC = "AL11"; +NET "serialout_p(7)" LOC = "AH10"; +NET "serialout_p(8)" LOC = "AK13"; +NET "serialout_p(9)" LOC = "AJ12"; +NET "serialout_p(10)" LOC = "AK14"; +NET "serialout_p(11)" LOC = "AH8"; +NET "serialout_p(12)" LOC = "AM8"; +NET "serialout_p(13)" LOC = "AJ9"; +NET "serialout_p(14)" LOC = "AM13"; +NET "serialout_p(15)" LOC = "AK7"; + + + +# CMD output +NET "serialout_p(16)" LOC = "K26"; +NET "serialout_p(17)" LOC = "D21"; +NET "serialout_p(18)" LOC = "P22"; +NET "serialout_p(19)" LOC = "E19"; +NET "serialout_p(20)" LOC = "L21"; +NET "serialout_p(21)" LOC = "L26"; +NET "serialout_p(22)" LOC = "P24"; +NET "serialout_p(23)" LOC = "K24"; + +# CLK output +NET "serialout_p(24)" LOC = "D30"; +NET "serialout_p(25)" LOC = "D29"; +NET "serialout_p(26)" LOC = "M26"; +NET "serialout_p(27)" LOC = "D32"; +NET "serialout_p(28)" LOC = "E31"; +NET "serialout_p(29)" LOC = "H28"; +NET "serialout_p(30)" LOC = "G30"; +NET "serialout_p(31)" LOC = "H30"; + + +# Data outputs DTO +NET "serialout_n(0)" LOC = "AE9"; +NET "serialout_n(1)" LOC = "AH12"; +NET "serialout_n(2)" LOC = "AM10"; +NET "serialout_n(3)" LOC = "AG10"; +NET "serialout_n(4)" LOC = "AK9"; +NET "serialout_n(5)" LOC = "AJ14"; +NET "serialout_n(6)" LOC = "AM11"; +NET "serialout_n(7)" LOC = "AJ10"; +NET "serialout_n(8)" LOC = "AL13"; +NET "serialout_n(9)" LOC = "AK12"; +NET "serialout_n(10)" LOC = "AL14"; +NET "serialout_n(11)" LOC = "AH7"; +NET "serialout_n(12)" LOC = "AM7"; +NET "serialout_n(13)" LOC = "AH9"; +NET "serialout_n(14)" LOC = "AM12"; +NET "serialout_n(15)" LOC = "AJ7"; + + + +# CMD output +NET "serialout_n(16)" LOC = "J26"; +NET "serialout_n(17)" LOC = "E21"; +NET "serialout_n(18)" LOC = "N22"; +NET "serialout_n(19)" LOC = "F19"; +NET "serialout_n(20)" LOC = "M22"; +NET "serialout_n(21)" LOC = "L25"; +NET "serialout_n(22)" LOC = "N24"; +NET "serialout_n(23)" LOC = "L24"; + +# CLK output +NET "serialout_n(24)" LOC = "C30"; +NET "serialout_n(25)" LOC = "C29"; +NET "serialout_n(26)" LOC = "M25"; +NET "serialout_n(27)" LOC = "C32"; +NET "serialout_n(28)" LOC = "D31"; +NET "serialout_n(29)" LOC = "H27"; +NET "serialout_n(30)" LOC = "F30"; +NET "serialout_n(31)" LOC = "H29"; + +#-----------------------------------------------------------------------------; +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; +NET "oDebug(0)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(1)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(2)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(3)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(4)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(5)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(6)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(7)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(8)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(9)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(10)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(11)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(12)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(13)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(14)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(15)" IOSTANDARD = "LVCMOS25"; +NET "doricreset" IOSTANDARD = "LVCMOS25"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(17)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(21)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(24)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(25)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(26)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(27)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(28)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(29)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(30)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(31)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(17)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(21)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(23)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(24)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(25)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(26)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(27)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(28)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(29)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(30)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(31)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(20)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(24)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(25)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(26)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(27)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(28)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(29)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(30)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(31)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(20)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(24)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(25)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(26)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(27)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(28)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(29)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(30)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(31)" IOSTANDARD = "LVDS_25"; + +#NET "clk40" IOSTANDARD = "LVCMOS25"; +#NET "rclk" IOSTANDARD = "LVCMOS25"; +NET "transDis1" IOSTANDARD = "LVCMOS25"; +#NET "clk40" SLEW = "FAST"; +#NET "rclk" SLEW = "FAST"; + + +#----------------------------------------------------------------------------- +#-------------------------- Logic Location Constraints ----------------------- +#----------------------------------------------------------------------------- +#INST "U_BnlAsicCore/U_AsicControl/U_ClockGen" AREA_GROUP = "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" ; +#AREA_GROUP "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" RANGE = SLICE_X52Y93:SLICE_X66Y29 ; + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.iblbert b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.iblbert new file mode 100644 index 0000000000000000000000000000000000000000..9c8db3d42ceb63c44e212b1f72a9d5905a1bd3b9 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.ucf.iblbert @@ -0,0 +1,519 @@ +#----------------------------------------------------------------------------- +# Title : LCLS BNL ASIC Test FPGA, Constraints File +# Project : LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# File : BnlAsic.ucf +# Author : Ryan Herbst, rherbst@slac.stanford.edu +# Created : 07/21/2008 +#----------------------------------------------------------------------------- +# Description: +# This file contains all of the user constraints required to implement the +# LCLS BNL ASIC Test FPGA +#----------------------------------------------------------------------------- +# Copyright (c) 2008 by Ryan Herbst. All rights reserved. +#----------------------------------------------------------------------------- +# Modification history +# 07/21/2008: created. +#----------------------------------------------------------------------------- + + +#----------------------------------------------------------------------------- +#-------------------------- Timing Constraints ------------------------------- +#----------------------------------------------------------------------------- +# This section contains the timing constraints for the FPGA +#----------------------------------------------------------------------------- + +# Define system clocks +NET pgpClk TNM_NET = FFS pgpClk; +NET sysClk125 TNM_NET = FFS sysClk125; +NET sysClk250 TNM_NET = FFS sysClk250; +NET clk80 TNM_NET = FFS clk80; +NET clk40 TNM_NET = FFS clk40; +#NET "U_BnlAsicCore/fxclock" TNM_NET = "U_BnlAsicCore_fxclock"; +NET "U_IBLcableTesterCore/phaseclk" TNM_NET = "U_BnlAsicCore_phaseclk"; +# NET "U_BnlAsicCore/serclk" TNM_NET = "U_BnlAsicCore_serclk"; + +# Define system clocks +TIMESPEC TS_pgpClk = PERIOD pgpClk 156.25 Mhz HIGH 50%; +TIMESPEC TS_sysClk125 = PERIOD sysClk125 39.0625 Mhz HIGH 50%; +TIMESPEC TS_sysClk250 = PERIOD sysClk250 78.125 Mhz HIGH 50%; +TIMESPEC TS_clk80 = PERIOD clk80 78.125 Mhz HIGH 50%; +TIMESPEC TS_clk40 = PERIOD clk40 39.0625 Mhz HIGH 50%; +#TIMESPEC TS_fxclock = PERIOD "U_BnlAsicCore_fxclock" 78.125 Mhz HIGH 50%; +# TIMESPEC TS_serclk = PERIOD "U_BnlAsicCore_serclk" 200 Mhz HIGH 50%; +TIMESPEC TS_phaseclk = PERIOD "U_BnlAsicCore_phaseclk" 78.125 Mhz HIGH 50%; + +# Define time groups for inter-clock constraints +TIMEGRP TG_pgpClk_r = RISING pgpClk; +TIMEGRP TG_sysClk125_r = RISING sysClk125; +TIMEGRP TG_sysClk250_r = RISING sysClk250; +TIMEGRP TG_clk80_r = RISING clk80; +TIMEGRP TG_clk40_r = RISING clk40; + +# Inter Domain Constraints +TIMESPEC TS_pgpClk_r_sysClk125_r = FROM TG_pgpClk_r TO TG_sysClk125_r 6.4ns; +TIMESPEC TS_sysClk125_r_pgpClk_r = FROM TG_sysClk125_r TO TG_pgpClk_r 6.4ns; +TIMESPEC TS_sysClk125_r_sysClk250_r = FROM TG_sysClk125_r TO TG_sysClk250_r 12.8ns; +# TIMESPEC TS_clk80_r_clk160_r = FROM TG_clk80_r TO TG_clk160_r 8ns; +TIMESPEC TS_clk40_r_clk80_r = FROM TG_clk40_r TO TG_clk80_r 12.8ns; + +# Nets to ignore for timing +NET "iResetInL" TIG; + + +#----------------------------------------------------------------------------- +#-------------------------- Pin Location Constraints ------------------------- +#----------------------------------------------------------------------------- +# This section contains the pin location constraints for the design +#----------------------------------------------------------------------------- +# Old P5 = New P5 +# Old P4 = New P4 +# Old P9 = New P3 +# Old P3 = New P2 + + +NET "iPgpRefClkP" LOC = "J1"; +NET "iPgpRefClkM" LOC = "K1"; +NET "iMainClkP" LOC = "H17"; +NET "iMainClkN" LOC = "J17"; +#fiber 1 +#NET "iMgtRxN" LOC = "N1"; +#NET "iMgtRxP" LOC = "M1"; +#NET "oMgtTxN" LOC = "T1"; +#NET "oMgtTxP" LOC = "R1"; +#fiber 2 +NET "iMgtRxN" LOC = "AA1"; +NET "iMgtRxP" LOC = "Y1"; +NET "oMgtTxN" LOC = "V1"; +NET "oMgtTxP" LOC = "U1"; +NET "iResetInL" LOC = "AJ19"; +NET "oDispClk" LOC = "AG22"; +NET "oDispDat" LOC = "AJ22"; +NET "oDispLoadL(1)" LOC = "AK17"; +NET "oDispLoadL(0)" LOC = "Ak18"; +NET "oDispRstL" LOC = "AH22"; +NET "oDebug(0)" LOC = "n10"; +NET "oDebug(1)" LOC = "n9"; +NET "oDebug(2)" LOC = "n8"; +NET "oDebug(3)" LOC = "n7"; +NET "oDebug(4)" LOC = "j6"; +NET "oDebug(5)" LOC = "k6"; +NET "oDebug(6)" LOC = "l6"; +NET "oDebug(7)" LOC = "l5"; +NET "oDebug(8)" LOC = "k4"; +NET "oDebug(9)" LOC = "k3"; +NET "oDebug(10)" LOC = "l4"; +NET "oDebug(11)" LOC = "l3"; +NET "oDebug(12)" LOC = "m6"; +NET "oDebug(13)" LOC = "m5"; +NET "oDebug(14)" LOC = "m3"; +NET "oDebug(15)" LOC = "n3"; +NET "doricreset" LOC = "R26"; +#NET "rclk" LOC = "AM21"; +# fiber 1 +#NET "transDis1" LOC = "AH4"; +# fiber 2 +NET "transDis1" LOC = "AK4"; +#NET "clkout40" LOC = "F5"; +#NET "clkout40" IOSTANDARD="LVCMOS25"; +#NET "clkout40" SLEW="FAST"; +#NET "oClock40" SLEW="FAST"; +#NET "oClock40" LOC = "L4"; +#NET "oClock40" IOSTANDARD="LVCMOS25"; +#NET "oClk160_p" LOC = "T5"; +#NET "oClk160_n" LOC = "T4"; +##NET "oClk40_p" LOC = "P7"; +##NET "oClk40_n" LOC = "P6"; +#NET "iClock160_p" LOC = "J6"; +#NET "iClock160_n" LOC = "K6"; +#NET "iClock160_p" IOSTANDARD="ULVDS_25"; +#NET "iClock160_n" IOSTANDARD="ULVDS_25"; +#NET "iClock160_p" CLOCK_DEDICATED_ROUTE = FALSE; + +# VDC inputs DTO +NET "serialin_p(0)" LOC = "G22"; +NET "serialin_p(1)" LOC = "H24"; +NET "serialin_p(2)" LOC = "AJ16"; +NET "serialin_p(3)" LOC = "AE13"; +NET "serialin_p(4)" LOC = "AF15"; +NET "serialin_p(5)" LOC = "AH15"; +NET "serialin_p(6)" LOC = "AB13"; + +# VDC inputs DTO2 +NET "serialin_p(7)" LOC = "AD14"; +NET "serialin_p(8)" LOC = "AB11"; +NET "serialin_p(9)" LOC = "AE14"; +NET "serialin_p(10)" LOC = "AD10"; +NET "serialin_p(11)" LOC = "AD11"; +NET "serialin_p(12)" LOC = "AG13"; +NET "serialin_p(13)" LOC = "AC12"; + +#not used, cross-talk line +# NET "serialin_p(14)" LOC = "F29"; +# NET "serialin_p(15)" LOC = "H28"; + +# CMD receive +NET "serialin_p(16)" LOC = "G30"; +NET "serialin_p(17)" LOC = "D32"; +NET "serialin_p(18)" LOC = "D29"; +NET "serialin_p(19)" LOC = "K24"; +NET "serialin_p(20)" LOC = "L26"; +NET "serialin_p(21)" LOC = "E19"; +NET "serialin_p(22)" LOC = "D21"; + +# not used, cross-talk line +#NET "serialin_p(23)" LOC = "M32"; + +# VDC inputs DTO +NET "serialin_n(0)" LOC = "H22"; +NET "serialin_n(1)" LOC = "J24"; +NET "serialin_n(2)" LOC = "AK16"; +NET "serialin_n(3)" LOC = "AF13"; +NET "serialin_n(4)" LOC = "AG15"; +NET "serialin_n(5)" LOC = "AJ15"; +NET "serialin_n(6)" LOC = "AA13"; + + +# VDC inputs DTO2 +NET "serialin_n(7)" LOC = "AC13"; +NET "serialin_n(8)" LOC = "AA11"; +NET "serialin_n(9)" LOC = "AF14"; +NET "serialin_n(10)" LOC = "AD9"; +NET "serialin_n(11)" LOC = "AE11"; +NET "serialin_n(12)" LOC = "AH13"; +NET "serialin_n(13)" LOC = "AB12"; + + +# NET "serialin_n(14)" LOC = "E29"; +# NET "serialin_n(15)" LOC = "H27"; + +# CMD receive +NET "serialin_n(16)" LOC = "F30"; +NET "serialin_n(17)" LOC = "C32"; +NET "serialin_n(18)" LOC = "C29"; +NET "serialin_n(19)" LOC = "L24"; +NET "serialin_n(20)" LOC = "L25"; +NET "serialin_n(21)" LOC = "F19"; +NET "serialin_n(22)" LOC = "E21"; + +# not used, cross-talk line +# NET "serialin_n(23)" LOC = "M31"; + +# Data outputs DTO +NET "serialout_p(1)" LOC = "R29"; +NET "serialout_p(3)" LOC = "N29"; +NET "serialout_p(5)" LOC = "U28"; +NET "serialout_p(7)" LOC = "N27"; +NET "serialout_p(9)" LOC = "M32"; +NET "serialout_p(11)" LOC = "G32"; +NET "serialout_p(13)" LOC = "T31"; + + +# Data outputs DTO2 +NET "serialout_p(0)" LOC = "T29"; +NET "serialout_p(2)" LOC = "R32"; +NET "serialout_p(4)" LOC = "N30"; +NET "serialout_p(6)" LOC = "K32"; +NET "serialout_p(8)" LOC = "L31"; +NET "serialout_p(10)" LOC = "E32"; +NET "serialout_p(12)" LOC = "J32"; + +# Cross-talk 80 Mb/s +#NET "serialout_p(14)" LOC = "AH14"; +#NET "serialout_p(15)" LOC = "AF10"; +NET "serialoutxtf_p(0)" LOC = "AM13"; +NET "serialoutxtf_p(1)" LOC = "AK14"; +NET "serialoutxtf_p(2)" LOC = "AL11"; +NET "serialoutxtf_p(3)" LOC = "AL10"; +NET "serialoutxtf_p(4)" LOC = "AK7"; + +# output to DORIC +NET "serialout_p(16)" LOC = "AG12"; +NET "serialout_p(18)" LOC = "AF10"; +NET "serialout_p(17)" LOC = "AH14"; +NET "serialout_p(22)" LOC = "AH10"; +NET "serialout_p(21)" LOC = "AJ12"; +NET "serialout_p(20)" LOC = "AH8"; +NET "serialout_p(19)" LOC = "AF11"; + +#NET "serialout_p(23)" LOC = "AD10"; + +#cross-talk 40 Mb/s +NET "serialoutxts_p(0)" LOC = "AM8"; +NET "serialoutxts_p(1)" LOC = "AK13"; +NET "serialoutxts_p(2)" LOC = "AL9"; +NET "serialoutxts_p(3)" LOC = "AF9"; +NET "serialoutxts_p(4)" LOC = "AJ9"; + +# Data outputs DTO +NET "serialout_n(1)" LOC = "P29"; +NET "serialout_n(3)" LOC = "N28"; +NET "serialout_n(5)" LOC = "U27"; +NET "serialout_n(7)" LOC = "M28"; +NET "serialout_n(9)" LOC = "M31"; +NET "serialout_n(11)" LOC = "G31"; +NET "serialout_n(13)" LOC = "T30"; + +# Data outputs DTO2 +NET "serialout_n(0)" LOC = "T28"; +NET "serialout_n(2)" LOC = "R31"; +NET "serialout_n(4)" LOC = "M30"; +NET "serialout_n(6)" LOC = "K31"; +NET "serialout_n(8)" LOC = "L30"; +NET "serialout_n(10)" LOC = "F31"; +NET "serialout_n(12)" LOC = "H32"; + +# cross-talk 80 Mb/s +#NET "serialout_n(14)" LOC = "AJ14"; +#NET "serialout_n(15)" LOC = "AG10"; +NET "serialoutxtf_n(0)" LOC = "AM12"; +NET "serialoutxtf_n(1)" LOC = "AL14"; +NET "serialoutxtf_n(2)" LOC = "AM11"; +NET "serialoutxtf_n(3)" LOC = "AM10"; +NET "serialoutxtf_n(4)" LOC = "AJ7"; + +# output to DORIC +NET "serialout_n(16)" LOC = "AH12"; +NET "serialout_n(18)" LOC = "AG10"; +NET "serialout_n(17)" LOC = "AJ14"; +NET "serialout_n(22)" LOC = "AJ10"; +NET "serialout_n(21)" LOC = "AK12"; +NET "serialout_n(20)" LOC = "AH7"; +NET "serialout_n(19)" LOC = "AG11"; + +# cross-talk 40 Mb/s +#NET "serialout_n(23)" LOC = "AD9"; +NET "serialoutxts_n(0)" LOC = "AM7"; +NET "serialoutxts_n(1)" LOC = "AL13"; +NET "serialoutxts_n(2)" LOC = "AK9"; +NET "serialoutxts_n(3)" LOC = "AE9"; +NET "serialoutxts_n(4)" LOC = "AH9"; + +# Return clock +NET "retclock_p(16)" LOC = "H28"; +NET "retclock_p(17)" LOC = "M26"; +NET "retclock_p(18)" LOC = "D30"; +NET "retclock_p(19)" LOC = "P24"; +NET "retclock_p(20)" LOC = "L21"; +NET "retclock_p(21)" LOC = "P22"; +NET "retclock_p(22)" LOC = "K26"; + +#unused, cross-talk line +#NET "retclock_p(23)" LOC = "L31"; + +# Return clock +NET "retclock_n(16)" LOC = "H27"; +NET "retclock_n(17)" LOC = "M25"; +NET "retclock_n(18)" LOC = "C30"; +NET "retclock_n(19)" LOC = "N24"; +NET "retclock_n(20)" LOC = "M22"; +NET "retclock_n(21)" LOC = "N22"; +NET "retclock_n(22)" LOC = "J26"; + +#unused, cross-talk line +#NET "retclock_n(23)" LOC = "L30"; +#-----------------------------------------------------------------------------; +#-------------------------- IO Standard Constraints -------------------------- +#----------------------------------------------------------------------------- +# This section defines the IO types, IO delays and other IO parameters +#----------------------------------------------------------------------------- + +NET "iResetInL" IOSTANDARD = "LVCMOS33"; +NET "oDispClk" IOSTANDARD = "LVCMOS33"; +NET "oDispDat" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(1)" IOSTANDARD = "LVCMOS33"; +NET "oDispLoadL(0)" IOSTANDARD = "LVCMOS33"; +NET "oDispRstL" IOSTANDARD = "LVCMOS33"; +NET "oDebug(0)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(1)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(2)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(3)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(4)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(5)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(6)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(7)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(8)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(9)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(10)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(11)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(12)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(13)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(14)" IOSTANDARD = "LVCMOS25"; +NET "oDebug(15)" IOSTANDARD = "LVCMOS25"; +NET "doricreset" IOSTANDARD = "LVCMOS25"; + +NET "serialin_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(9)" IOSTANDARD = "LVDS_25"; + NET "serialin_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(13)" IOSTANDARD = "LVDS_25"; + NET "serialin_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(17)" IOSTANDARD = "LVDS_25"; + NET "serialin_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(21)" IOSTANDARD = "LVDS_25"; + NET "serialin_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(6)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(9)" IOSTANDARD = "LVDS_25"; + NET "serialin_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(13)" IOSTANDARD = "LVDS_25"; + NET "serialin_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(15)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(17)" IOSTANDARD = "LVDS_25"; + NET "serialin_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(20)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(21)" IOSTANDARD = "LVDS_25"; + NET "serialin_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialin_n(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(6)" IOSTANDARD = "LVDS_25"; +# NET "serialout_p(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(9)" IOSTANDARD = "LVDS_25"; +# NET "serialout_p(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(15)" IOSTANDARD = "LVDS_25"; +#NET "serialout_p(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(20)" IOSTANDARD = "LVDS_25"; +#NET "serialout_p(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_p(23)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(0)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(1)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(2)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(3)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(4)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(5)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(6)" IOSTANDARD = "LVDS_25"; +#NET "serialout_n(7)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(8)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(9)" IOSTANDARD = "LVDS_25"; +# NET "serialout_n(10)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(11)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(12)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(13)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(14)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(15)" IOSTANDARD = "LVDS_25"; +# NET "serialout_n(16)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(17)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(18)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(19)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(20)" IOSTANDARD = "LVDS_25"; +#NET "serialout_n(21)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(22)" IOSTANDARD = "LVDS_25"; +NET "serialout_n(23)" IOSTANDARD = "LVDS_25"; + +NET "retclock_p(16)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(17)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(18)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(19)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(20)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(21)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(22)" IOSTANDARD = "LVDS_25"; +NET "retclock_p(23)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(16)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(17)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(18)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(19)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(20)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(21)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(22)" IOSTANDARD = "LVDS_25"; +NET "retclock_n(23)" IOSTANDARD = "LVDS_25"; + +NET "serialout_p(0)" SLEW = "FAST"; +NET "serialout_p(1)" SLEW = "FAST"; +NET "serialout_p(2)" SLEW = "FAST"; +NET "serialout_p(3)" SLEW = "FAST"; +NET "serialout_p(4)" SLEW = "FAST"; +NET "serialout_p(5)" SLEW = "FAST"; +NET "serialout_p(6)" SLEW = "FAST"; +NET "serialout_p(7)" SLEW = "FAST"; +NET "serialout_p(8)" SLEW = "FAST"; +NET "serialout_p(9)" SLEW = "FAST"; +# NET "serialout_p(10)" SLEW = "FAST"; +NET "serialout_p(11)" SLEW = "FAST"; +NET "serialout_p(12)" SLEW = "FAST"; +NET "serialout_p(13)" SLEW = "FAST"; +# NET "serialout_p(14)" SLEW = "FAST"; +NET "serialout_p(15)" SLEW = "FAST"; +NET "serialout_p(16)" SLEW = "FAST"; +NET "serialout_p(17)" SLEW = "FAST"; +NET "serialout_p(18)" SLEW = "FAST"; +NET "serialout_p(19)" SLEW = "FAST"; +# NET "serialout_p(20)" SLEW = "FAST"; +NET "serialout_p(21)" SLEW = "FAST"; +NET "serialout_p(22)" SLEW = "FAST"; +NET "serialout_p(23)" SLEW = "FAST"; +NET "serialout_n(0)" SLEW = "FAST"; +NET "serialout_n(1)" SLEW = "FAST"; +NET "serialout_n(2)" SLEW = "FAST"; +NET "serialout_n(3)" SLEW = "FAST"; +NET "serialout_n(4)" SLEW = "FAST"; +NET "serialout_n(5)" SLEW = "FAST"; +NET "serialout_n(6)" SLEW = "FAST"; +NET "serialout_n(7)" SLEW = "FAST"; +NET "serialout_n(8)" SLEW = "FAST"; +NET "serialout_n(9)" SLEW = "FAST"; +# NET "serialout_n(10)" SLEW = "FAST"; +NET "serialout_n(11)" SLEW = "FAST"; +NET "serialout_n(12)" SLEW = "FAST"; +NET "serialout_n(13)" SLEW = "FAST"; +# NET "serialout_n(14)" SLEW = "FAST"; +NET "serialout_n(15)" SLEW = "FAST"; +NET "serialout_n(16)" SLEW = "FAST"; +NET "serialout_n(17)" SLEW = "FAST"; +NET "serialout_n(18)" SLEW = "FAST"; +NET "serialout_n(19)" SLEW = "FAST"; +# NET "serialout_n(20)" SLEW = "FAST"; +NET "serialout_n(21)" SLEW = "FAST"; +NET "serialout_n(22)" SLEW = "FAST"; +NET "serialout_n(23)" SLEW = "FAST"; +#NET "clk40" IOSTANDARD = "LVCMOS25"; +#NET "rclk" IOSTANDARD = "LVCMOS25"; +NET "transDis1" IOSTANDARD = "LVCMOS25"; +#NET "clk40" SLEW = "FAST"; +#NET "rclk" SLEW = "FAST"; + + +#----------------------------------------------------------------------------- +#-------------------------- Logic Location Constraints ----------------------- +#----------------------------------------------------------------------------- +#INST "U_BnlAsicCore/U_AsicControl/U_ClockGen" AREA_GROUP = "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" ; +#AREA_GROUP "AG_U_BnlAsicCore/U_AsicControl/U_ClockGen" RANGE = SLICE_X52Y93:SLICE_X66Y29 ; + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.vhd new file mode 100755 index 0000000000000000000000000000000000000000..054abd6a3f464e9192607d83b3d8f8a69d808beb --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTester.vhd @@ -0,0 +1,523 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : BnlAsic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity IBLcableTester is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + oClock40 : out std_logic; + iClock160_p : in std_logic; + iClock160_n : in std_logic; + oClk160_p : out std_logic; + oClk160_n : out std_logic; + oClk40_p : out std_logic; + oClk40_n : out std_logic; + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin_p : in std_logic_vector(31 downto 0); + serialin_n : in std_logic_vector(31 downto 0); + serialout_p : out std_logic_vector(31 downto 0); + serialout_n : out std_logic_vector(31 downto 0); + retclock_p : in std_logic_vector(23 downto 16); + retclock_n : in std_logic_vector(23 downto 16); + serialoutxtf_p : out std_logic_vector(4 downto 0); + serialoutxtf_n : out std_logic_vector(4 downto 0); + serialoutxts_p : out std_logic_vector(4 downto 0); + serialoutxts_n : out std_logic_vector(4 downto 0); + doricreset : out std_logic; + clkout40 : out std_logic; + + -- Reset button + iResetInL : in std_logic; + + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(15 downto 0); + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic + ); +end IBLcableTester; + + +-- Define architecture for top level module +architecture IBLcableTester of IBLcableTester is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of IBLcableTester : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of IBLcableTester : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of IBLcableTester : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := FALSE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + + -- PGP Clock Generator + component PgpClkGen + generic ( + RefClkEn1 : string := "ENABLE"; -- ENABLE or DISABLE + RefClkEn2 : string := "DISABLE"; -- ENABLE or DISABLE + DcmClkSrc : string := "RefClk1"; -- RefClk1 or RefClk2 + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Pad Inputs + pgpRefClkInP : in std_logic; + pgpRefClkInN : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Reference Clock To PGP MGT + -- Use one, See RefClkEn1 & RefClkEn2 Generics + pgpRefClk1 : out std_logic; + pgpRefClk2 : out std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpClk90 : out std_logic; + pgpReset : out std_logic; + + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + end component; + + + -- Core Logic + component IBLcableTesterCore + port ( + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + refClock : in std_logic; + pgpClk : in std_logic; + pgpClk90 : in std_logic; + pgpReset : in std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + serialin : in std_logic_vector(31 downto 0); + serialout : out std_logic_vector(31 downto 0); + retclock : in std_logic_vector(23 downto 16); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + doricreset : out std_logic; + resetOut : out std_logic; + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic_vector(1 downto 0); + dispRstL : out std_logic; + debug : out std_logic_vector(15 downto 0) + ); + end component; + component clock160 + port ( + CLKIN_N_IN : in std_logic; + CLKIN_P_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLKIN_IBUFGDS_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; +--component ila + --PORT ( + --CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + --CLK : IN STD_LOGIC; + --DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; + --component icon + --PORT ( + --CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- + --end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal pgpClk90 : std_logic; + signal clk160 : std_logic; + signal clk80 : std_logic; + signal clk40 : std_logic; + signal pgpReset : std_logic; + signal resetOut : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(15 downto 0); + signal sysClk125i : std_logic; + signal doricresetb : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal holdrst : std_logic; + signal halfclock : std_logic; + signal clockfast : std_logic; + signal quarterclock : std_logic; + signal serialoutb : std_logic_vector(31 downto 0); + signal serialinb : std_logic_vector(31 downto 0); + signal retclockb : std_logic_vector(23 downto 16); + signal retclockd : std_logic_vector(23 downto 16); + signal retclocki : std_logic_vector(23 downto 16); + signal ccontrol: std_logic_vector(35 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(0 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of IBUF : component is TRUE; + attribute syn_noprune of IBUF : component is TRUE; + attribute syn_black_box of OBUF : component is TRUE; + attribute syn_noprune of OBUF : component is TRUE; + attribute syn_black_box of IBUFDS : component is TRUE; + attribute syn_noprune of IBUFDS : component is TRUE; + attribute syn_black_box of OBUFDS : component is TRUE; + attribute syn_noprune of OBUFDS : component is TRUE; + attribute syn_black_box of BUFGMUX : component is TRUE; + attribute syn_noprune of BUFGMUX : component is TRUE; +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125 + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK250: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_clkout40 : OBUF port map ( I => clk40 , O => clkout40 ); + + + -- Debug + U_Debug0 : OBUF port map ( I => debug(0) , O => oDebug(0) ); + U_Debug1 : OBUF port map ( I => debug(1) , O => oDebug(1) ); + U_Debug2 : OBUF port map ( I => debug(2) , O => oDebug(2) ); + U_Debug3 : OBUF port map ( I => debug(3) , O => oDebug(3) ); + U_Debug4 : OBUF port map ( I => debug(4) , O => oDebug(4) ); + U_Debug5 : OBUF port map ( I => debug(5) , O => oDebug(5) ); + U_Debug6 : OBUF port map ( I => debug(6) , O => oDebug(6) ); + U_Debug7 : OBUF port map ( I => debug(7) , O => oDebug(7) ); + U_Debug8 : OBUF port map ( I => debug(8) , O => oDebug(8) ); + U_Debug9 : OBUF port map ( I => debug(9) , O => oDebug(9) ); + U_Debug10 : OBUF port map ( I => debug(10) , O => oDebug(10) ); + U_Debug11 : OBUF port map ( I => debug(11) , O => oDebug(11) ); + U_Debug12 : OBUF port map ( I => debug(12) , O => oDebug(12) ); + U_Debug13 : OBUF port map ( I => debug(13) , O => oDebug(13) ); + U_Debug14 : OBUF port map ( I => debug(14) , O => oDebug(14) ); + U_Debug15 : OBUF port map ( I => debug(15) , O => oDebug(15) ); + +-- U_clock40out : OBUF port map ( I => quarterclock , O => oClock40 ); +-- U_serialout1 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => mainClk , O => serialout_p(1) , OB => serialout_n(1) ); +-- U_serialout2 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => clkin , O => serialout_p(2) , OB => serialout_n(2) ); +-- U_clockout40 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +---- SLEW=>"FAST") +-- port map ( I => quarterclock , O => oClk40_p , OB => oClk40_n ); +-- U_clockout160 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => pgpClk , O => oClk160_p , OB => oClk160_n ); +-- U_clockin160 : IBUFDS generic map ( DIFF_TERM=>TRUE, +-- IOSTANDARD=>"ULVDS_25") +-- port map ( I => iClock160_p , IB=>iClock160_n , O => clk160 ); + + SERIAL_IO_DATA: + for I in 0 to 31 generate + U_serialout : OBUFDS generic map ( + IOSTANDARD=>"LVDS_25", + SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + +-- SERIAL_IO_DATA_in: +-- for I in 0 to 15 generate + U_serialin : IBUFDS generic map ( DIFF_TERM=>TRUE, + IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + end generate SERIAL_IO_DATA; +-- end generate SERIAL_IO_DATA_in; + +-- SERIAL_IO_CMD: +-- for I in 16 to 23 generate +-- delayline : IDELAY +-- generic map ( +-- IOBDELAY_TYPE => "FIXED", -- Set to DEFAULT for -- Zero Hold Time Mode +-- IOBDELAY_VALUE => 10 -- (0 to 63) +-- ) +-- port map ( +-- O => retclockd(I), +-- I => retclockb(I), +-- C => '0', +-- CE => '0', +-- INC => '0', +-- RST => '0' +-- ); +-- --retclockd(I)<= not retclocki(I); +-- U_serialout : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); +-- +-- U_serialin : IBUFDS generic map ( DIFF_TERM=>TRUE, +-- IOSTANDARD=>"LVDS_25") +-- port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); +-- U_retclock : IBUFDS generic map ( DIFF_TERM=>TRUE, +-- IOSTANDARD=>"LVDS_25") +-- port map ( I => retclock_p(I) , IB=>retclock_n(I) , O => retclockb(I) ); +-- end generate SERIAL_IO_CMD; + +-- CROSSTALK: +-- for I in 0 to 4 generate +-- U_xtalkf : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +---- SLEW=>"FAST") +-- port map ( I => serialoutb(15) , O => serialoutxtf_p(I) , OB => serialoutxtf_n(I) ); +-- +-- U_xtalks : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => serialoutb(23) , O => serialoutxts_p(I) , OB => serialoutxts_n(I) ); +-- +-- end generate CROSSTALK; +-- +-- U_doric : OBUF port map ( I => doricresetb , O => doricreset ); + U_link : OBUF port map ( I => '0' , O => transDis1 ); + + + -- FPGA Core + U_IBLcableTesterCore: IBLcableTesterCore port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpClk90 => pgpClk90, + pgpReset => pgpReset, mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb, + serialout => serialoutb, retclock => retclockb, + clock160 => pgpClk, + clock80 => sysClk250, clock40 => sysClk125, + doricreset => doricresetb, resetOut => resetOut, + dispClk => dispClk, dispDat => dispDat, + dispLoadL => dispLoadL, dispRstL => dispRstL, + debug => debug + ); + --sysClk125i <= not sysClk125; + sysClk125i<=debug(0); +-- U_clock160: clock160 port map( +-- CLKIN_N_IN => iMainClkN, +-- CLKIN_P_IN => iMainClkP, +-- RST_IN => sysRst125, +-- CLKFX_OUT => open, +-- CLKIN_IBUFGDS_OUT => clkin, +-- CLK0_OUT => clk0, +-- LOCKED_OUT => open); + process(pgpClk) + begin + if(pgpClk'event and pgpClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + process(pgpClk) + begin + if(pgpClk'event and pgpClk='1') then + clk80<= not clk80; + end if; + end process; + process(clk80) + begin + if(clk80'event and clk80='1') then + clk40<= not clk40; + end if; + end process; + --cdata(7 downto 0)<=serialinb(7 downto 0); + --cdata(31 downto 8) <=(others=>'0'); + --ctrig(0)<='0'; + --chipscope : ila + --port map ( + --CONTROL => ccontrol, + --CLK => mainClk, + --DATA => cdata, + --TRIG0 => ctrig); + --chipscopeicon : icon + --port map ( + --CONTROL0 => ccontrol); + +end IBLcableTester; diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCore.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCore.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0e14f9f3809d2e9929a6387ff61c10cb36ec4dd8 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCore.vhd @@ -0,0 +1,670 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA Core +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : IBLcableTesterCore.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity IBLcableTesterCore is + port ( + + -- Master system clock, 250Mhz, 125Mhz + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + + -- PGP Clocks + refClock : in std_logic; + pgpClk : in std_logic; + pgpClk90 : in std_logic; + pgpReset : in std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(31 downto 0); + serialout : out std_logic_vector(31 downto 0); + retclock : in std_logic_vector(23 downto 16); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + doricreset : out std_logic; +-- serialclkout : out std_logic; + + -- Reset out to PGP Clock generation + resetOut : out std_logic; + + -- LED Display + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic_vector(1 downto 0); + dispRstL : out std_logic; + + + -- Debug + debug : out std_logic_vector(15 downto 0) + ); +end IBLcableTesterCore; + + +-- Define architecture +architecture IBLcableTesterCore of IBLcableTesterCore is + + -- LED Display Controller + component DisplayControl + port ( + sysClk : in std_logic; + sysRst : in std_logic; + dispStrobe : in std_logic; + dispUpdate : in std_logic; + dispRotate : in std_logic_vector(1 downto 0); + dispDigitA : in std_logic_vector(7 downto 0); + dispDigitB : in std_logic_vector(7 downto 0); + dispDigitC : in std_logic_vector(7 downto 0); + dispDigitD : in std_logic_vector(7 downto 0); + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic; + dispRstL : out std_logic + ); + end component; + component pattern_mem is + generic(DELAY: integer); + port( + clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + deserclk90: in std_logic; + rst: in std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic + ); + end component; + component pattern_cmd is + port( + clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + retclk: in std_logic; + rst: in std_logic; + doricreset: out std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic + ); + end component; + component clock200 + port( CLKIN_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + component phaseshift + port ( CLKIN_IN : in std_logic; + DADDR_IN : in std_logic_vector (6 downto 0); + DCLK_IN : in std_logic; + DEN_IN : in std_logic; + DI_IN : in std_logic_vector (15 downto 0); + DWE_IN : in std_logic; + RST_IN : in std_logic; + CLK0_OUT : out std_logic; + CLK90_OUT : out std_logic; + CLKFX_OUT : out std_logic; + CLK2X_OUT : out std_logic; + DRDY_OUT : out std_logic; + LOCKED_OUT : out std_logic); + --PSDONE_OUT : out std_logic); + end component; + + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + -- PGP Front End Wrapper + + component PgpFrontEnd + generic ( + MgtMode : string := "A"; + RefClkSel : string := "REFCLK1" + ); + port ( + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + mgtRxRecClk : out std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + pgpDispA : out std_logic_vector(7 downto 0); + pgpDispB : out std_logic_vector(7 downto 0); + resetOut : out std_logic; + locClk : in std_logic; + locReset : in std_logic; + cmdEn : out std_logic; + cmdOpCode : out std_logic_vector(7 downto 0); + cmdCtxOut : out std_logic_vector(23 downto 0); + regReq : out std_logic; + regOp : out std_logic; + regAck : in std_logic; + regFail : in std_logic; + regAddr : out std_logic_vector(23 downto 0); + regDataOut : out std_logic_vector(31 downto 0); + regDataIn : in std_logic_vector(31 downto 0); + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + valid : out std_logic; + eof :out std_logic; + sof :out std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); + end component; + + + -- Local Signals + signal cmdEn : std_logic; + signal cmdOpCode : std_logic_vector(7 downto 0); + signal cmdCtxOut : std_logic_vector(23 downto 0); + signal readDataValid : std_logic; + signal readDataSOF : std_logic; + signal readDataEOF : std_logic; + signal readDataEOFE : std_logic; + signal readData : std_logic_vector(15 downto 0); + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal regReq : std_logic; + signal regOp : std_logic; + signal regAck : std_logic; + signal regFail : std_logic; + signal regAddr : std_logic_vector(23 downto 0); + signal regDataOut : std_logic_vector(31 downto 0); + signal regDataIn : std_logic_vector(31 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal ack : std_logic_vector(31 downto 0); + signal err : std_logic_vector(31 downto 0); + signal eof : std_logic; + signal sof : std_logic; + signal vvalid : std_logic; + signal regAck1 : std_logic; + signal regAck2 : std_logic; + signal regAck3 : std_logic; + signal regAck4 : std_logic; + signal regFail1 : std_logic; + signal regFail2 : std_logic; + signal regFail3 : std_logic; + signal regFail4 : std_logic; + type readback is array(31 downto 0) of std_logic_vector(31 downto 0); + signal thedata : readback; + signal req : std_logic_vector(31 downto 0); + signal counter1 : std_logic_vector(7 downto 0); + signal counter2 : std_logic_vector(7 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + signal daddr : std_logic_vector (6 downto 0); + signal denfx : std_logic; + signal denphase : std_logic; + signal phaseclk : std_logic; + signal sysClk90 : std_logic; + signal fxclock : std_logic; + signal serclk : std_logic; + signal drdy : std_logic; + signal drdy2 : std_logic; + signal lockedfx : std_logic; + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal lockedphase : std_logic; + signal lockednophase : std_logic; + signal reqclkfx : std_logic; + signal reqclkphase : std_logic; + signal oldreqclkfx : std_logic; + signal oldreqclkphase : std_logic; + signal clkenafx : std_logic; + signal clkenaphase : std_logic; + signal psdone : std_logic; + signal holdrst : std_logic; + signal phaserst : std_logic; + signal clockrst : std_logic; + signal clockrst2 : std_logic; + signal idctrlrst : std_logic; + signal clkdata : std_logic_vector(15 downto 0); + signal holdctr : std_logic_vector(24 downto 0); + signal clockidctrl : std_logic; + signal dreset : std_logic_vector(23 downto 16); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + type DELAR is array (0 to 31) of integer; + constant setting: DELAR := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + attribute syn_noprune : boolean; + attribute syn_noprune of U_idelayctrl: label is true; + +begin + + -- Display Controller A + U_DispCntrlA: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + + -- Output LED Data + dispDat <= dispDatA or dispDatB; + dispDigitA <= pgpDispA; + dispDigitB <= pgpDispB; + dispDigitD <= regDataIn(7 downto 0); + dispDigitC <= "0000"&lockedid&lockednophase &lockedphase & lockedfx; + dispDigitE <= "0000" & counter1(7 downto 4); + dispDigitF <= "0000" & counter1(3 downto 0); + dispDigitG <= "0000" & counter2(7 downto 4); + dispDigitH <="0000" & counter2(3 downto 0); + + + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + if req(0)='1' then + counter1<=unsigned(counter1)+1; + end if; + + if req(1)='1' then + counter2<=unsigned(counter2)+1; + end if; + + end if; + end process; + + + -- PGP Front End + U_PgpFrontEnd: PgpFrontEnd port map ( + pgpRefClk1 => refClock, pgpRefClk2 => '0', + mgtRxRecClk => open, pgpClk => pgpClk, + pgpReset => pgpReset, pgpDispA => pgpDispA, + pgpDispB => pgpDispB, resetOut => resetOut, + locClk => sysClk125, locReset => sysRst125, + cmdEn => cmdEn, cmdOpCode => cmdOpCode, + cmdCtxOut => cmdCtxOut, regReq => regReq, + regOp => regOp, regAck => regAck, + regFail => regFail, regAddr => regAddr, + regDataOut => regDataOut, regDataIn => regDataIn, + frameTxEnable => readDataValid, frameTxSOF => readDataSOF, + frameTxEOF => readDataEOF, frameTxEOFE => readDataEOFE, + frameTxData => readData, valid => vvalid, + eof => eof, sof => sof, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, mgtCombusIn => (others=>'0'), + mgtCombusOut => open + ); + + clkData<=(others=>'0'); + readDataValid<='0'; + vvalid<='0'; + readDataSOF<='0'; + readDataEOF<='0'; + readDataEOFE<='0'; + readData<=(others=>'0'); + regAck1<= (ack(0) or ack(1) or ack(2) or ack(3) or ack(4) or ack(5) or ack(6) or ack(7)); + regAck2<= (ack(8) or ack(9) or ack(10) or ack(11) or ack(12) or ack(13) or ack(14) or ack(15)); + regAck3<= (ack(16) or ack(17) or ack(18) or ack(19) or ack(20) or ack(21) or ack(22) or ack(23)); + regAck4<= (ack(24) or ack(25) or ack(26) or ack(27) or ack(28) or ack(29) or ack(30) or ack(31)); + regAck<= (regAck1 or regAck2 or regAck3 or regAck4 or drdy or drdy2); + regFail1<= (err(0) or err(1) or err(2) or err(3) or err(4) or err(5) or err(6) or err(7)); + regFail2<= (err(8) or err(9) or err(10) or err(11) or err(12) or err(13) or err(14) or err(15)); + regFail3<= (err(16) or err(17) or err(18) or err(19) or err(20) or err(21) or err(22) or err(23)); + regFail4<= (err(24) or err(25) or err(26) or err(27) or err(28) or err(29) or err(30) or err(31)); + regFail<= (regFail1 or regFail2 or regFail3 or regFail4); + req(0)<='1' when regReq='1' and (regAddr(9 downto 4) = "000000" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(1)<='1' when regReq='1' and (regAddr(9 downto 4) = "000001" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(2)<='1' when regReq='1' and (regAddr(9 downto 4) = "000010" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(3)<='1' when regReq='1' and (regAddr(9 downto 4) = "000011" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(4)<='1' when regReq='1' and (regAddr(9 downto 4) = "000100" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(5)<='1' when regReq='1' and (regAddr(9 downto 4) = "000101" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(6)<='1' when regReq='1' and (regAddr(9 downto 4) = "000110" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(7)<='1' when regReq='1' and (regAddr(9 downto 4) = "000111" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(8)<='1' when regReq='1' and (regAddr(9 downto 4) = "001000" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(9)<='1' when regReq='1' and (regAddr(9 downto 4) = "001001" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(10)<='1' when regReq='1' and (regAddr(9 downto 4) = "001010" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(11)<='1' when regReq='1' and (regAddr(9 downto 4) = "001011" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(12)<='1' when regReq='1' and (regAddr(9 downto 4) = "001100" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(13)<='1' when regReq='1' and (regAddr(9 downto 4) = "001101" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(14)<='1' when regReq='1' and (regAddr(9 downto 4) = "001110" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(15)<='1' when regReq='1' and (regAddr(9 downto 4) = "001111" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111110") else '0'; + req(16)<='1' when regReq='1' and (regAddr(9 downto 4) = "010000" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(17)<='1' when regReq='1' and (regAddr(9 downto 4) = "010001" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(18)<='1' when regReq='1' and (regAddr(9 downto 4) = "010010" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(19)<='1' when regReq='1' and (regAddr(9 downto 4) = "010011" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(20)<='1' when regReq='1' and (regAddr(9 downto 4) = "010100" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(21)<='1' when regReq='1' and (regAddr(9 downto 4) = "010101" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(22)<='1' when regReq='1' and (regAddr(9 downto 4) = "010110" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(23)<='1' when regReq='1' and (regAddr(9 downto 4) = "010111" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(24)<='1' when regReq='1' and (regAddr(9 downto 4) = "011000" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(25)<='1' when regReq='1' and (regAddr(9 downto 4) = "011001" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(26)<='1' when regReq='1' and (regAddr(9 downto 4) = "011010" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(27)<='1' when regReq='1' and (regAddr(9 downto 4) = "011011" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(28)<='1' when regReq='1' and (regAddr(9 downto 4) = "011100" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(29)<='1' when regReq='1' and (regAddr(9 downto 4) = "011101" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(30)<='1' when regReq='1' and (regAddr(9 downto 4) = "011110" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + req(31)<='1' when regReq='1' and (regAddr(9 downto 4) = "011111" or regAddr(9 downto 4) = "111111" or regAddr(9 downto 4) = "111101") else '0'; + reqclkphase <='1' when regReq='1' and (regAddr(9 downto 4) = "111000" or regAddr(9 downto 4) = "111001" or regAddr(9 downto 4) = "111010") else '0'; + reqclkfx<='1'when regreq='1' and (regAddr(9 downto 4) = "111011" or regAddr(9 downto 4) = "111100") else '0'; + with regAddr(9 downto 4) select + regDataIn <= thedata(0) when "000000", + thedata(1) when "000001", + thedata(2) when "000010", + thedata(3) when "000011", + thedata(4) when "000100", + thedata(5) when "000101", + thedata(6) when "000110", + thedata(7) when "000111", + thedata(8) when "001000", + thedata(9) when "001001", + thedata(10) when "001010", + thedata(11) when "001011", + thedata(12) when "001100", + thedata(13) when "001101", + thedata(14) when "001110", + thedata(15) when "001111", + thedata(16) when "010000", + thedata(17) when "010001", + thedata(18) when "010010", + thedata(19) when "010011", + thedata(20) when "010100", + thedata(21) when "010101", + thedata(22) when "010110", + thedata(23) when "010111", + thedata(24) when "011000", + thedata(25) when "011001", + thedata(26) when "011010", + thedata(27) when "011011", + thedata(28) when "011100", + thedata(29) when "011101", + thedata(30) when "011110", + thedata(31) when "011111", + x"0000" & clkdata when "111010", + x"ffffffff" when others; + + PATTERN_GEN_DATA: + for I in 0 to 15 generate + + U_pattern_mem: pattern_mem + generic map( + DELAY=>setting(I)) + port map ( + clk => sysClk125, + serclk => pgpClk, --was serclk + deserclk90 => pgpClk90, + deserclk => phaseclk, + rst => sysRst125, + pgpEnable => req(I), + pgpRW => regOp, + pgpAck => ack(I), + pgpErr => err(I), + dataFromPgp => regDataOut, + addrPgp => regAddr(3 downto 0), + dataToPgp => thedata(I), + dataFromFe => serialin(I), + dataToFe => serialout(I)); +end generate PATTERN_GEN_DATA; + PATTERN_GEN_DATA_2: + for I in 16 to 31 generate + + U_pattern_mem: pattern_mem + generic map( + DELAY=>setting(I)) + port map ( + clk => sysClk125, + serclk => sysclk125, --was serclk + deserclk90 => sysclk90, + deserclk => sysclk125, + rst => sysRst125, + pgpEnable => req(I), + pgpRW => regOp, + pgpAck => ack(I), + pgpErr => err(I), + dataFromPgp => regDataOut, + addrPgp => regAddr(3 downto 0), + dataToPgp => thedata(I), + dataFromFe => serialin(I), + dataToFe => serialout(I)); +end generate PATTERN_GEN_DATA_2; + PATTERN_GEN_CMD: + for I in 16 to 15 generate + + U_pattern_cmd: pattern_cmd port map ( + clk => sysClk125, + serclk => clock80, + deserclk => clock40, + retclk => retclock(I), + rst => sysRst125, + doricreset => dreset(I), + pgpEnable => req(I), + pgpRW => regOp, + pgpAck => ack(I), + pgpErr => err(I), + dataFromPgp => regDataOut, + addrPgp => regAddr(3 downto 0), + dataToPgp => thedata(I), + dataFromFe => serialin(I), + dataToFe => serialout(I)); +end generate PATTERN_GEN_CMD; + doricreset<=dreset(20); + + clockrst<=holdrst; + clockrst2<=phaserst; + U_idelctrlclk: clock200 port map( + CLKIN_IN => clock160, + RST_IN => clockrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + U_clockmult: phaseshift port map( + CLKIN_IN => sysClk125, -- was clock160 + DADDR_IN => daddr, + DCLK_IN => sysClk125, + DEN_IN => denfx, + DI_IN => regDataOut(15 downto 0), + --DO_OUT => clkdata, + DWE_IN => regOp, + RST_IN => clockrst, + CLK0_OUT => open, + CLK90_OUT => sysClk90, + CLKFX_OUT => fxclock, + CLK2X_OUT => open, + DRDY_OUT => drdy, + LOCKED_OUT=> lockedfx); + --PSDONE_OUT=> open); + U_phaseshift: phaseshift port map( + CLKIN_IN => pgpClk, -- was fxclock + DADDR_IN => daddr, + DCLK_IN => sysClk125, + DEN_IN => denphase, + DI_IN => regDataOut(15 downto 0), + --DO_OUT => (others=>'0'), + DWE_IN => regOp, + RST_IN => clockrst2, + CLK0_OUT => phaseclk, -- was open + CLKFX_OUT => open, + CLK2X_OUT => open, -- was phaseclk + DRDY_OUT => drdy2, + LOCKED_OUT=> lockedphase); + --PSDONE_OUT=> psdone); + U_noshift: phaseshift port map( + CLKIN_IN => fxclock, + DADDR_IN => (others=>'0'), + DCLK_IN => sysClk125, + DEN_IN => '0', + DI_IN => (others=>'0'), + --DO_OUT => (others=>'0'), + DWE_IN => '0', + RST_IN => clockrst2, + CLK0_OUT => open, + CLKFX_OUT => open, + CLK2X_OUT => serclk, + DRDY_OUT => open, + LOCKED_OUT=> lockednophase); + --PSDONE_OUT=> open); + + + with regAddr(9 downto 4) select + daddr<="1010101" when "111000", + "0010001" when "111001", + "0000000" when "111010", + "1010000" when "111011", + "1010010" when "111100", + "0000000" when others; + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + clkenafx<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (reqclkfx='1' and oldreqclkfx='0') then + clkenafx<='1'; + holdctr<=x"ffffff"&'1'; + holdrst<='1'; + else + clkenafx<='0'; + if (holdctr=x"000000"&'0') then + phaserst<='0'; + else + if (holdctr(24)='0') then + holdrst<='0'; + phaserst<='1'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end if; + if (reqclkphase='1' and oldreqclkphase='0') then + clkenaphase<='1'; + else + clkenaphase<='0'; + end if; + denfx<=clkenafx; + denphase<=clkenaphase; + oldreqclkfx<=reqclkfx; + oldreqclkphase<=reqclkphase; + end if; + end process; + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end IBLcableTesterCore; + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCoreOld.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCoreOld.vhd new file mode 100644 index 0000000000000000000000000000000000000000..277fb2788431b5b99c2ef73572061a512fa6c95b --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterCoreOld.vhd @@ -0,0 +1,622 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA Core +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : IBLcableTesterCore.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Core logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +use work.all; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity IBLcableTesterCore is + port ( + + -- Master system clock, 250Mhz, 125Mhz + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + + -- PGP Clocks + refClock : in std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + + -- MGT Serial Pins + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin : in std_logic_vector(23 downto 0); + serialout : out std_logic_vector(23 downto 0); + retclock : in std_logic_vector(23 downto 16); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + doricreset : out std_logic; +-- serialclkout : out std_logic; + + -- Reset out to PGP Clock generation + resetOut : out std_logic; + + -- LED Display + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic_vector(1 downto 0); + dispRstL : out std_logic; + + + -- Debug + debug : out std_logic_vector(15 downto 0) + ); +end IBLcableTesterCore; + + +-- Define architecture +architecture IBLcableTesterCore of IBLcableTesterCore is + + -- LED Display Controller + component DisplayControl + port ( + sysClk : in std_logic; + sysRst : in std_logic; + dispStrobe : in std_logic; + dispUpdate : in std_logic; + dispRotate : in std_logic_vector(1 downto 0); + dispDigitA : in std_logic_vector(7 downto 0); + dispDigitB : in std_logic_vector(7 downto 0); + dispDigitC : in std_logic_vector(7 downto 0); + dispDigitD : in std_logic_vector(7 downto 0); + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic; + dispRstL : out std_logic + ); + end component; + component pattern_mem is + generic(DELAY: integer); + port( + clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + rst: in std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic + ); + end component; + component pattern_cmd is + port( + clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + retclk: in std_logic; + rst: in std_logic; + doricreset: out std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic + ); + end component; + component clock200 + port( CLKIN_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; + component IDELAYCTRL + port ( RDY : out std_logic; + REFCLK : in std_logic; + RST : in std_logic + ); + end component; + component phaseshift + port ( CLKIN_IN : in std_logic; + DADDR_IN : in std_logic_vector (6 downto 0); + DCLK_IN : in std_logic; + DEN_IN : in std_logic; + DI_IN : in std_logic_vector (15 downto 0); + DWE_IN : in std_logic; + RST_IN : in std_logic; + CLK0_OUT : out std_logic; + CLKFX_OUT : out std_logic; + CLK2X_OUT : out std_logic; + DRDY_OUT : out std_logic; + LOCKED_OUT : out std_logic); + --PSDONE_OUT : out std_logic); + end component; + + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + -- PGP Front End Wrapper + + component PgpFrontEnd + generic ( + MgtMode : string := "A"; + RefClkSel : string := "REFCLK1" + ); + port ( + pgpRefClk1 : in std_logic; + pgpRefClk2 : in std_logic; + mgtRxRecClk : out std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + pgpDispA : out std_logic_vector(7 downto 0); + pgpDispB : out std_logic_vector(7 downto 0); + resetOut : out std_logic; + locClk : in std_logic; + locReset : in std_logic; + cmdEn : out std_logic; + cmdOpCode : out std_logic_vector(7 downto 0); + cmdCtxOut : out std_logic_vector(23 downto 0); + regReq : out std_logic; + regOp : out std_logic; + regAck : in std_logic; + regFail : in std_logic; + regAddr : out std_logic_vector(23 downto 0); + regDataOut : out std_logic_vector(31 downto 0); + regDataIn : in std_logic_vector(31 downto 0); + frameTxEnable : in std_logic; + frameTxSOF : in std_logic; + frameTxEOF : in std_logic; + frameTxEOFE : in std_logic; + frameTxData : in std_logic_vector(15 downto 0); + valid : out std_logic; + eof :out std_logic; + sof :out std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + mgtCombusIn : in std_logic_vector(15 downto 0); + mgtCombusOut : out std_logic_vector(15 downto 0) + ); + end component; + + + -- Local Signals + signal cmdEn : std_logic; + signal cmdOpCode : std_logic_vector(7 downto 0); + signal cmdCtxOut : std_logic_vector(23 downto 0); + signal readDataValid : std_logic; + signal readDataSOF : std_logic; + signal readDataEOF : std_logic; + signal readDataEOFE : std_logic; + signal readData : std_logic_vector(15 downto 0); + signal dispDatA : std_logic; + signal dispDatB : std_logic; + signal pgpDispA : std_logic_vector(7 downto 0); + signal pgpDispB : std_logic_vector(7 downto 0); + signal regReq : std_logic; + signal regOp : std_logic; + signal regAck : std_logic; + signal regFail : std_logic; + signal regAddr : std_logic_vector(23 downto 0); + signal regDataOut : std_logic_vector(31 downto 0); + signal regDataIn : std_logic_vector(31 downto 0); + signal dispDigitA : std_logic_vector(7 downto 0); + signal dispDigitB : std_logic_vector(7 downto 0); + signal dispDigitC : std_logic_vector(7 downto 0); + signal dispDigitD : std_logic_vector(7 downto 0); + signal dispDigitE : std_logic_vector(7 downto 0); + signal dispDigitF : std_logic_vector(7 downto 0); + signal dispDigitG : std_logic_vector(7 downto 0); + signal dispDigitH : std_logic_vector(7 downto 0); + signal dispStrobe : std_logic; + signal dispUpdateA : std_logic; + signal dispUpdateB : std_logic; + signal sysClkCnt : std_logic_vector(15 downto 0); + signal ack : std_logic_vector(23 downto 0); + signal err : std_logic_vector(23 downto 0); + signal eof : std_logic; + signal sof : std_logic; + signal vvalid : std_logic; + signal regAck1 : std_logic; + signal regAck2 : std_logic; + signal regAck3 : std_logic; + signal regFail1 : std_logic; + signal regFail2 : std_logic; + signal regFail3 : std_logic; + type readback is array(23 downto 0) of std_logic_vector(31 downto 0); + signal thedata : readback; + signal req : std_logic_vector(23 downto 0); + signal counter1 : std_logic_vector(7 downto 0); + signal counter2 : std_logic_vector(7 downto 0); + signal idcounter : std_logic_vector(2 downto 0); + signal daddr : std_logic_vector (6 downto 0); + signal denfx : std_logic; + signal denphase : std_logic; + signal phaseclk : std_logic; + signal fxclock : std_logic; + signal serclk : std_logic; + signal drdy : std_logic; + signal drdy2 : std_logic; + signal lockedfx : std_logic; + signal lockedid : std_logic; + signal oldlockedid : std_logic; + signal lockedphase : std_logic; + signal lockednophase : std_logic; + signal reqclkfx : std_logic; + signal reqclkphase : std_logic; + signal oldreqclkfx : std_logic; + signal oldreqclkphase : std_logic; + signal clkenafx : std_logic; + signal clkenaphase : std_logic; + signal psdone : std_logic; + signal holdrst : std_logic; + signal phaserst : std_logic; + signal clockrst : std_logic; + signal clockrst2 : std_logic; + signal idctrlrst : std_logic; + signal clkdata : std_logic_vector(15 downto 0); + signal holdctr : std_logic_vector(24 downto 0); + signal clockidctrl : std_logic; + signal dreset : std_logic_vector(23 downto 16); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + type DELAR is array (0 to 15) of integer; + constant setting: DELAR := (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + attribute syn_noprune : boolean; + attribute syn_noprune of U_idelayctrl: label is true; + +begin + + -- Display Controller A + U_DispCntrlA: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateA, + dispRotate => "01", dispDigitA => dispDigitA, + dispDigitB => dispDigitB, dispDigitC => dispDigitC, + dispDigitD => dispDigitD, dispClk => dispClk, + dispDat => dispDatA, dispLoadL => dispLoadL(0), + dispRstL => dispRstL + ); + + -- Display Controller B + U_DispCntrlB: DisplayControl port map ( + sysClk => sysClk125, sysRst => sysRst125, + dispStrobe => dispStrobe, dispUpdate => dispUpdateB, + dispRotate => "01", dispDigitA => dispDigitE, + dispDigitB => dispDigitF, dispDigitC => dispDigitG, + dispDigitD => dispDigitH, dispClk => open, + dispDat => dispDatB, dispLoadL => dispLoadL(1), + dispRstL => open + ); + + -- Output LED Data + dispDat <= dispDatA or dispDatB; + dispDigitA <= pgpDispA; + dispDigitB <= pgpDispB; + dispDigitD <= regDataIn(7 downto 0); + dispDigitC <= "0000"&lockedid&lockednophase &lockedphase & lockedfx; + dispDigitE <= "0000" & counter1(7 downto 4); + dispDigitF <= "0000" & counter1(3 downto 0); + dispDigitG <= "0000" & counter2(7 downto 4); + dispDigitH <="0000" & counter2(3 downto 0); + + + -- Generate display strobe (200ns) and update control + process ( sysClk125, sysRst125 ) begin + if sysRst125 = '1' then + sysClkCnt <= (others=>'0') after tpd; + dispStrobe <= '0' after tpd; + dispUpdateA <= '0' after tpd; + dispUpdateB <= '0' after tpd; + elsif rising_edge(sysClk125) then + + -- Display strobe, 320ns + dispStrobe <= sysClkCnt(4) after tpd; + + -- Update Display 0 + if sysClkCnt(15 downto 0) = x"8000" then + dispUpdateA <= '1' after tpd; + else + dispUpdateA <= '0' after tpd; + end if; + + -- Update Display B + if sysClkCnt(15 downto 0) = x"0000" then + dispUpdateB <= '1' after tpd; + else + dispUpdateB <= '0' after tpd; + end if; + + -- Update counter + sysClkCnt <= sysClkCnt + 1 after tpd; + + if req(0)='1' then + counter1<=unsigned(counter1)+1; + end if; + + if req(1)='1' then + counter2<=unsigned(counter2)+1; + end if; + + end if; + end process; + + + -- PGP Front End + U_PgpFrontEnd: PgpFrontEnd port map ( + pgpRefClk1 => refClock, pgpRefClk2 => '0', + mgtRxRecClk => open, pgpClk => pgpClk, + pgpReset => pgpReset, pgpDispA => pgpDispA, + pgpDispB => pgpDispB, resetOut => resetOut, + locClk => sysClk125, locReset => sysRst125, + cmdEn => cmdEn, cmdOpCode => cmdOpCode, + cmdCtxOut => cmdCtxOut, regReq => regReq, + regOp => regOp, regAck => regAck, + regFail => regFail, regAddr => regAddr, + regDataOut => regDataOut, regDataIn => regDataIn, + frameTxEnable => readDataValid, frameTxSOF => readDataSOF, + frameTxEOF => readDataEOF, frameTxEOFE => readDataEOFE, + frameTxData => readData, valid => vvalid, + eof => eof, sof => sof, + mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, mgtCombusIn => (others=>'0'), + mgtCombusOut => open + ); + + clkData<=(others=>'0'); + readDataValid<='0'; + vvalid<='0'; + readDataSOF<='0'; + readDataEOF<='0'; + readDataEOFE<='0'; + readData<=(others=>'0'); + regAck1<= (ack(0) or ack(1) or ack(2) or ack(3) or ack(4) or ack(5) or ack(6) or ack(7)); + regAck2<= (ack(8) or ack(9) or ack(10) or ack(11) or ack(12) or ack(13) or ack(14) or ack(15)); + regAck3<= (ack(16) or ack(17) or ack(18) or ack(19) or ack(20) or ack(21) or ack(22) or ack(23)); + regAck<= (regAck1 or regAck2 or regAck3 or drdy or drdy2); + regFail1<= (err(0) or err(1) or err(2) or err(3) or err(4) or err(5) or err(6) or err(7)); + regFail2<= (err(8) or err(9) or err(10) or err(11) or err(12) or err(13) or err(14) or err(15)); + regFail3<= (err(16) or err(17) or err(18) or err(19) or err(20) or err(21) or err(22) or err(23)); + regFail<= (regFail1 or regFail2 or regFail3); + req(0)<='1' when regReq='1' and (regAddr(8 downto 4) = "00000" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(1)<='1' when regReq='1' and (regAddr(8 downto 4) = "00001" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(2)<='1' when regReq='1' and (regAddr(8 downto 4) = "00010" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(3)<='1' when regReq='1' and (regAddr(8 downto 4) = "00011" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(4)<='1' when regReq='1' and (regAddr(8 downto 4) = "00100" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(5)<='1' when regReq='1' and (regAddr(8 downto 4) = "00101" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(6)<='1' when regReq='1' and (regAddr(8 downto 4) = "00110" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(7)<='1' when regReq='1' and (regAddr(8 downto 4) = "00111" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(8)<='1' when regReq='1' and (regAddr(8 downto 4) = "01000" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(9)<='1' when regReq='1' and (regAddr(8 downto 4) = "01001" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(10)<='1' when regReq='1' and (regAddr(8 downto 4) = "01010" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(11)<='1' when regReq='1' and (regAddr(8 downto 4) = "01011" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(12)<='1' when regReq='1' and (regAddr(8 downto 4) = "01100" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(13)<='1' when regReq='1' and (regAddr(8 downto 4) = "01101" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(14)<='1' when regReq='1' and (regAddr(8 downto 4) = "01110" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(15)<='1' when regReq='1' and (regAddr(8 downto 4) = "01111" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11110") else '0'; + req(16)<='1' when regReq='1' and (regAddr(8 downto 4) = "10000" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(17)<='1' when regReq='1' and (regAddr(8 downto 4) = "10001" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(18)<='1' when regReq='1' and (regAddr(8 downto 4) = "10010" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(19)<='1' when regReq='1' and (regAddr(8 downto 4) = "10011" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(20)<='1' when regReq='1' and (regAddr(8 downto 4) = "10100" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(21)<='1' when regReq='1' and (regAddr(8 downto 4) = "10101" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(22)<='1' when regReq='1' and (regAddr(8 downto 4) = "10110" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + req(23)<='1' when regReq='1' and (regAddr(8 downto 4) = "10111" or regAddr(8 downto 4) = "11111" or regAddr(8 downto 4) = "11101") else '0'; + reqclkphase <='1' when regReq='1' and (regAddr(8 downto 4) = "11000" or regAddr(8 downto 4) = "11001" or regAddr(8 downto 4) = "11010") else '0'; + reqclkfx<='1'when regreq='1' and (regAddr(8 downto 4) = "11011" or regAddr(8 downto 4) = "11100") else '0'; + with regAddr(8 downto 4) select + regDataIn <= thedata(0) when "00000", + thedata(1) when "00001", + thedata(2) when "00010", + thedata(3) when "00011", + thedata(4) when "00100", + thedata(5) when "00101", + thedata(6) when "00110", + thedata(7) when "00111", + thedata(8) when "01000", + thedata(9) when "01001", + thedata(10) when "01010", + thedata(11) when "01011", + thedata(12) when "01100", + thedata(13) when "01101", + thedata(14) when "01110", + thedata(15) when "01111", + thedata(16) when "10000", + thedata(17) when "10001", + thedata(18) when "10010", + thedata(19) when "10011", + thedata(20) when "10100", + thedata(21) when "10101", + thedata(22) when "10110", + thedata(23) when "10111", + x"0000" & clkdata when "11010", + x"ffffffff" when others; + + PATTERN_GEN_DATA: + for I in 0 to 15 generate + + U_pattern_mem: pattern_mem + generic map( + DELAY=>setting(I)) + port map ( + clk => sysClk125, + serclk => pgpClk, --was serclk + deserclk => phaseclk, + rst => sysRst125, + pgpEnable => req(I), + pgpRW => regOp, + pgpAck => ack(I), + pgpErr => err(I), + dataFromPgp => regDataOut, + addrPgp => regAddr(3 downto 0), + dataToPgp => thedata(I), + dataFromFe => serialin(I), + dataToFe => serialout(I)); +end generate PATTERN_GEN_DATA; + PATTERN_GEN_CMD: + for I in 16 to 23 generate + + U_pattern_cmd: pattern_cmd port map ( + clk => sysClk125, + serclk => clock80, + deserclk => clock40, + retclk => retclock(I), + rst => sysRst125, + doricreset => dreset(I), + pgpEnable => req(I), + pgpRW => regOp, + pgpAck => ack(I), + pgpErr => err(I), + dataFromPgp => regDataOut, + addrPgp => regAddr(3 downto 0), + dataToPgp => thedata(I), + dataFromFe => serialin(I), + dataToFe => serialout(I)); +end generate PATTERN_GEN_CMD; + doricreset<=dreset(20); + + clockrst<=holdrst; + clockrst2<=phaserst; + U_idelctrlclk: clock200 port map( + CLKIN_IN => clock160, + RST_IN => clockrst, + CLKFX_OUT => clockidctrl, + CLK0_OUT => open, + LOCKED_OUT => lockedid); + U_idelayctrl: IDELAYCTRL port map( + RDY => open, + REFCLK => clockidctrl, + RST => idctrlrst); + + U_clockmult: phaseshift port map( + CLKIN_IN => clock80, -- was clock160 + DADDR_IN => daddr, + DCLK_IN => sysClk125, + DEN_IN => denfx, + DI_IN => regDataOut(15 downto 0), + --DO_OUT => clkdata, + DWE_IN => regOp, + RST_IN => clockrst, + CLK0_OUT => open, + CLKFX_OUT => fxclock, + CLK2X_OUT => open, + DRDY_OUT => drdy, + LOCKED_OUT=> lockedfx); + --PSDONE_OUT=> open); + U_phaseshift: phaseshift port map( + CLKIN_IN => pgpClk, -- was fxclock + DADDR_IN => daddr, + DCLK_IN => sysClk125, + DEN_IN => denphase, + DI_IN => regDataOut(15 downto 0), + --DO_OUT => (others=>'0'), + DWE_IN => regOp, + RST_IN => clockrst2, + CLK0_OUT => phaseclk, -- was open + CLKFX_OUT => open, + CLK2X_OUT => open, -- was phaseclk + DRDY_OUT => drdy2, + LOCKED_OUT=> lockedphase); + --PSDONE_OUT=> psdone); + U_noshift: phaseshift port map( + CLKIN_IN => fxclock, + DADDR_IN => (others=>'0'), + DCLK_IN => sysClk125, + DEN_IN => '0', + DI_IN => (others=>'0'), + --DO_OUT => (others=>'0'), + DWE_IN => '0', + RST_IN => clockrst2, + CLK0_OUT => open, + CLKFX_OUT => open, + CLK2X_OUT => serclk, + DRDY_OUT => open, + LOCKED_OUT=> lockednophase); + --PSDONE_OUT=> open); + + + with regAddr(8 downto 4) select + daddr<="1010101" when "11000", + "0010001" when "11001", + "0000000" when "11010", + "1010000" when "11011", + "1010010" when "11100", + "0000000" when others; + process(sysRst125, sysClk125) -- clock interface + begin + if (sysRst125='1') then + holdctr<=(others=>'1'); + holdrst<='1'; + clkenafx<='1'; + elsif(sysClk125'event and sysClk125='1') then + if (reqclkfx='1' and oldreqclkfx='0') then + clkenafx<='1'; + holdctr<=x"ffffff"&'1'; + holdrst<='1'; + else + clkenafx<='0'; + if (holdctr=x"000000"&'0') then + phaserst<='0'; + else + if (holdctr(24)='0') then + holdrst<='0'; + phaserst<='1'; + end if; + holdctr<=unsigned(holdctr)-1; + end if; + end if; + if (reqclkphase='1' and oldreqclkphase='0') then + clkenaphase<='1'; + else + clkenaphase<='0'; + end if; + denfx<=clkenafx; + denphase<=clkenaphase; + oldreqclkfx<=reqclkfx; + oldreqclkphase<=reqclkphase; + end if; + end process; + process(sysClk125, sysRst125) -- reset logic for IDELAYCTRL + begin + if(sysRst125='1') then + idctrlrst<='0'; + idcounter<="000"; + oldlockedid<='0'; + elsif(sysClk125'event and sysClk125='1') then + if(lockedid='1' and oldlockedid='0')then + idcounter<="111"; + idctrlrst<='1'; + elsif(unsigned(idcounter)>0)then + idcounter<=unsigned(idcounter)-1; + else + idctrlrst<='0'; + end if; + oldlockedid<=lockedid; + end if; + end process; + +end IBLcableTesterCore; + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterOld.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterOld.vhd new file mode 100755 index 0000000000000000000000000000000000000000..6ed702983dc508fa14150e905bec3311055c729b --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/IBLcableTesterOld.vhd @@ -0,0 +1,518 @@ +------------------------------------------------------------------------------- +-- Title : BNL ASIC Test FGPA, Top Level +-- Project : LCLS Detector, BNL ASIC +------------------------------------------------------------------------------- +-- File : BnlAsic.vhd +-- Author : Ryan Herbst, rherbst@slac.stanford.edu +-- Created : 07/21/2008 +------------------------------------------------------------------------------- +-- Description: +-- Top level logic for BNL ASIC test FPGA. +------------------------------------------------------------------------------- +-- Copyright (c) 2008 by Ryan Herbst. All rights reserved. +------------------------------------------------------------------------------- +-- Modification history: +-- 07/21/2008: created. +------------------------------------------------------------------------------- + +LIBRARY ieee; +Library Unisim; +USE ieee. std_logic_1164.ALL; +use ieee. std_logic_arith.all; +use ieee. std_logic_unsigned.all; +USE work.ALL; + +entity IBLcableTester is + port ( + + -- PGP Crystal Clock Input, 156.25Mhz + iPgpRefClkP : in std_logic; + iPgpRefClkM : in std_logic; + + -- System clock 125 MHz clock input + iMainClkP : in std_logic; + iMainClkN : in std_logic; + + oClock40 : out std_logic; + iClock160_p : in std_logic; + iClock160_n : in std_logic; + oClk160_p : out std_logic; + oClk160_n : out std_logic; + oClk40_p : out std_logic; + oClk40_n : out std_logic; + -- PGP Rx/Tx Lines + iMgtRxN : in std_logic; + iMgtRxP : in std_logic; + oMgtTxN : out std_logic; + oMgtTxP : out std_logic; + + -- ATLAS Pixel module pins + serialin_p : in std_logic_vector(23 downto 0); + serialin_n : in std_logic_vector(23 downto 0); + serialout_p : out std_logic_vector(23 downto 0); + serialout_n : out std_logic_vector(23 downto 0); + retclock_p : in std_logic_vector(23 downto 16); + retclock_n : in std_logic_vector(23 downto 16); + serialoutxtf_p : out std_logic_vector(4 downto 0); + serialoutxtf_n : out std_logic_vector(4 downto 0); + serialoutxts_p : out std_logic_vector(4 downto 0); + serialoutxts_n : out std_logic_vector(4 downto 0); + doricreset : out std_logic; + clkout40 : out std_logic; + + -- Reset button + iResetInL : in std_logic; + + -- LED Display + oDispClk : out std_logic; + oDispDat : out std_logic; + oDispLoadL : out std_logic_vector(1 downto 0); + oDispRstL : out std_logic; + + -- Debug + oDebug : out std_logic_vector(15 downto 0); + + -- Misc Signals + oPdBuff0 : out std_logic; + oPdBuff1 : out std_logic; + oPdBuff3 : out std_logic; + oPdBuff4 : out std_logic; + oLemoA : out std_logic; + iLemoB : in std_logic; + + -- Transmitter enable + transDis1 : out std_logic + ); +end IBLcableTester; + + +-- Define architecture for top level module +architecture IBLcableTester of IBLcableTester is + + -- Synthesis control attributes + attribute syn_useioff : boolean; + attribute syn_useioff of IBLcableTester : architecture is true; + attribute xc_fast_auto : boolean; + attribute xc_fast_auto of IBLcableTester : architecture is false; + attribute syn_noclockbuf : boolean; + attribute syn_noclockbuf of IBLcableTester : architecture is true; + + -- IO Pad components + component IBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUF port ( O : out std_logic; I : in std_logic ); end component; + component OBUFDS + generic( IOSTANDARD: STRING:= "LVDS_25"; + SLEW: STRING:="FAST"); + port ( O : out std_logic; OB : out std_logic; I : in std_logic ); + end component; + + -- Input LVDS with termination + component IBUFDS + generic ( DIFF_TERM : boolean := FALSE; + IOSTANDARD: STRING := "LVDS_25"); + port ( O : out std_logic; I : in std_logic; IB : in std_logic ); + end component; + + -- Xilinx global clock buffer component + component BUFGMUX + port ( + O : out std_logic; + I0 : in std_logic; + I1 : in std_logic; + S : in std_logic + ); + end component; + + + -- PGP Clock Generator + component PgpClkGen + generic ( + RefClkEn1 : string := "ENABLE"; -- ENABLE or DISABLE + RefClkEn2 : string := "DISABLE"; -- ENABLE or DISABLE + DcmClkSrc : string := "RefClk1"; -- RefClk1 or RefClk2 + UserFxDiv : integer := 5; -- DCM FX Output Divide + UserFxMult : integer := 4 -- DCM FX Output Divide, 4/5 * 156.25 = 125Mhz + ); + port ( + + -- Reference Clock Pad Inputs + pgpRefClkInP : in std_logic; + pgpRefClkInN : in std_logic; + + -- Power On Reset Input + ponResetL : in std_logic; + + -- Locally Generated Reset + locReset : in std_logic; + + -- Reference Clock To PGP MGT + -- Use one, See RefClkEn1 & RefClkEn2 Generics + pgpRefClk1 : out std_logic; + pgpRefClk2 : out std_logic; + + -- Global Clock & Reset For PGP Logic, 156.25Mhz + pgpClk : out std_logic; + pgpReset : out std_logic; + + -- Global Clock & Reset For User Logic, 125Mhz + userClk : out std_logic; + userReset : out std_logic; + + -- Inputs clocks for reset generation connect + -- to pgpClk and userClk + pgpClkIn : in std_logic; + userClkIn : in std_logic + ); + end component; + + + -- Core Logic + component IBLcableTesterCore + port ( + sysClk250 : in std_logic; + sysClk125 : in std_logic; + sysRst125 : in std_logic; + sysRst250 : in std_logic; + refClock : in std_logic; + pgpClk : in std_logic; + pgpReset : in std_logic; + mgtRxN : in std_logic; + mgtRxP : in std_logic; + mgtTxN : out std_logic; + mgtTxP : out std_logic; + serialin : in std_logic_vector(23 downto 0); + serialout : out std_logic_vector(23 downto 0); + retclock : in std_logic_vector(23 downto 16); + clock160 : in std_logic; + clock80 : in std_logic; + clock40 : in std_logic; + doricreset : out std_logic; + resetOut : out std_logic; + dispClk : out std_logic; + dispDat : out std_logic; + dispLoadL : out std_logic_vector(1 downto 0); + dispRstL : out std_logic; + debug : out std_logic_vector(15 downto 0) + ); + end component; + component clock160 + port ( + CLKIN_N_IN : in std_logic; + CLKIN_P_IN : in std_logic; + RST_IN : in std_logic; + CLKFX_OUT : out std_logic; + CLKIN_IBUFGDS_OUT : out std_logic; + CLK0_OUT : out std_logic; + LOCKED_OUT : out std_logic); + end component; +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; +--component ila + --PORT ( + --CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + --CLK : IN STD_LOGIC; + --DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; + --component icon + --PORT ( + --CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- + --end component; + + + -- Local signals + signal resetInL : std_logic; + signal tmpClk250 : std_logic; + signal sysClk125 : std_logic; + signal sysRst125 : std_logic; + signal sysRst250 : std_logic; + signal sysClk250 : std_logic; + signal refClock : std_logic; + signal pgpClk : std_logic; + signal clk160 : std_logic; + signal clk80 : std_logic; + signal clk40 : std_logic; + signal pgpReset : std_logic; + signal resetOut : std_logic; + signal mgtRxN : std_logic; + signal mgtRxP : std_logic; + signal mgtTxN : std_logic; + signal mgtTxP : std_logic; + signal dispClk : std_logic; + signal dispDat : std_logic; + signal dispLoadL : std_logic_vector(1 downto 0); + signal dispRstL : std_logic; + signal debug : std_logic_vector(15 downto 0); + signal sysClk125i : std_logic; + signal doricresetb : std_logic; + signal mainClk : std_logic; + signal clk0 : std_logic; + signal clkin : std_logic; + signal holdrst : std_logic; + signal halfclock : std_logic; + signal clockfast : std_logic; + signal quarterclock : std_logic; + signal serialoutb : std_logic_vector(23 downto 0); + signal serialinb : std_logic_vector(23 downto 0); + signal retclockb : std_logic_vector(23 downto 16); + signal retclockd : std_logic_vector(23 downto 16); + signal retclocki : std_logic_vector(23 downto 16); + signal ccontrol: std_logic_vector(35 downto 0); + signal cdata: std_logic_vector(31 downto 0); + signal ctrig: std_logic_vector(0 downto 0); + + -- Register delay for simulation + constant tpd:time := 0.5 ns; + + -- Black Box Attributes +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + attribute syn_black_box : boolean; + attribute syn_noprune : boolean; + attribute syn_black_box of IBUF : component is TRUE; + attribute syn_noprune of IBUF : component is TRUE; + attribute syn_black_box of OBUF : component is TRUE; + attribute syn_noprune of OBUF : component is TRUE; + attribute syn_black_box of IBUFDS : component is TRUE; + attribute syn_noprune of IBUFDS : component is TRUE; + attribute syn_black_box of OBUFDS : component is TRUE; + attribute syn_noprune of OBUFDS : component is TRUE; + attribute syn_black_box of BUFGMUX : component is TRUE; + attribute syn_noprune of BUFGMUX : component is TRUE; +begin + + -- Reset input + U_ResetIn: IBUF port map ( I => iResetInL, O => resetInL ); + + -- PGP Clock Generator + U_PgpClkGen: PgpClkGen generic map ( + RefClkEn1 => "ENABLE", + RefClkEn2 => "DISABLE", + DcmClkSrc => "RefClk1", + UserFxDiv => 4, + UserFxMult => 2 + ) port map ( + pgpRefClkInP => iPgpRefClkP, + pgpRefClkInN => iPgpRefClkM, + ponResetL => resetInL, + locReset => resetOut, + pgpRefClk1 => refClock, + pgpRefClk2 => open, + pgpClk => pgpClk, + pgpReset => pgpReset, + pgpClkIn => pgpClk, + userClk => sysClk125, + userReset => sysRst125, + userClkIn => sysClk125 + ); + + -- Generate Divided Clock, sample reset + process ( pgpClk ) begin + if rising_edge(pgpClk) then + tmpClk250 <= not tmpClk250 after tpd; + sysRst250 <= sysRst125 after tpd; + end if; + end process; + + -- Global Buffer For 125Mhz Clock + U_CLK250: BUFGMUX port map ( + O => sysClk250, + I0 => tmpClk250, + I1 => '0', + S => '0' + ); + + -- No Pads for MGT Lines + mgtRxN <= iMgtRxN; + mgtRxP <= iMgtRxP; + oMgtTxN <= mgtTxN; + oMgtTxP <= mgtTxP; + + -- LED Display + U_DispClk : OBUF port map ( I => dispClk , O => oDispClk ); + U_DispDat : OBUF port map ( I => dispDat , O => oDispDat ); + U_DispLoadL1 : OBUF port map ( I => dispLoadL(1) , O => oDispLoadL(1) ); + U_DispLoadL0 : OBUF port map ( I => dispLoadL(0) , O => oDispLoadL(0) ); + U_DispRstL : OBUF port map ( I => dispRstL , O => oDispRstL ); + U_clkout40 : OBUF port map ( I => clk40 , O => clkout40 ); + + + -- Debug + U_Debug0 : OBUF port map ( I => debug(0) , O => oDebug(0) ); + U_Debug1 : OBUF port map ( I => debug(1) , O => oDebug(1) ); + U_Debug2 : OBUF port map ( I => debug(2) , O => oDebug(2) ); + U_Debug3 : OBUF port map ( I => debug(3) , O => oDebug(3) ); + U_Debug4 : OBUF port map ( I => debug(4) , O => oDebug(4) ); + U_Debug5 : OBUF port map ( I => debug(5) , O => oDebug(5) ); + U_Debug6 : OBUF port map ( I => debug(6) , O => oDebug(6) ); + U_Debug7 : OBUF port map ( I => debug(7) , O => oDebug(7) ); + U_Debug8 : OBUF port map ( I => debug(8) , O => oDebug(8) ); + U_Debug9 : OBUF port map ( I => debug(9) , O => oDebug(9) ); + U_Debug10 : OBUF port map ( I => debug(10) , O => oDebug(10) ); + U_Debug11 : OBUF port map ( I => debug(11) , O => oDebug(11) ); + U_Debug12 : OBUF port map ( I => debug(12) , O => oDebug(12) ); + U_Debug13 : OBUF port map ( I => debug(13) , O => oDebug(13) ); + U_Debug14 : OBUF port map ( I => debug(14) , O => oDebug(14) ); + U_Debug15 : OBUF port map ( I => debug(15) , O => oDebug(15) ); + +-- U_clock40out : OBUF port map ( I => quarterclock , O => oClock40 ); +-- U_serialout1 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => mainClk , O => serialout_p(1) , OB => serialout_n(1) ); +-- U_serialout2 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => clkin , O => serialout_p(2) , OB => serialout_n(2) ); +-- U_clockout40 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +---- SLEW=>"FAST") +-- port map ( I => quarterclock , O => oClk40_p , OB => oClk40_n ); +-- U_clockout160 : OBUFDS generic map ( +-- IOSTANDARD=>"LVDS_25", +-- SLEW=>"FAST") +-- port map ( I => pgpClk , O => oClk160_p , OB => oClk160_n ); +-- U_clockin160 : IBUFDS generic map ( DIFF_TERM=>TRUE, +-- IOSTANDARD=>"ULVDS_25") +-- port map ( I => iClock160_p , IB=>iClock160_n , O => clk160 ); + + SERIAL_IO_DATA: + for I in 0 to 15 generate + U_serialout : OBUFDS generic map ( + IOSTANDARD=>"LVDS_25", + SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + +-- SERIAL_IO_DATA_in: +-- for I in 0 to 15 generate + U_serialin : IBUFDS generic map ( DIFF_TERM=>TRUE, + IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + end generate SERIAL_IO_DATA; +-- end generate SERIAL_IO_DATA_in; + + SERIAL_IO_CMD: + for I in 16 to 23 generate +-- delayline : IDELAY +-- generic map ( +-- IOBDELAY_TYPE => "FIXED", -- Set to DEFAULT for -- Zero Hold Time Mode +-- IOBDELAY_VALUE => 10 -- (0 to 63) +-- ) +-- port map ( +-- O => retclockd(I), +-- I => retclockb(I), +-- C => '0', +-- CE => '0', +-- INC => '0', +-- RST => '0' +-- ); +-- --retclockd(I)<= not retclocki(I); + U_serialout : OBUFDS generic map ( + IOSTANDARD=>"LVDS_25", + SLEW=>"FAST") + port map ( I => serialoutb(I) , O => serialout_p(I) , OB => serialout_n(I) ); + + U_serialin : IBUFDS generic map ( DIFF_TERM=>TRUE, + IOSTANDARD=>"LVDS_25") + port map ( I => serialin_p(I) , IB=>serialin_n(I) , O => serialinb(I) ); + U_retclock : IBUFDS generic map ( DIFF_TERM=>TRUE, + IOSTANDARD=>"LVDS_25") + port map ( I => retclock_p(I) , IB=>retclock_n(I) , O => retclockb(I) ); + end generate SERIAL_IO_CMD; + + CROSSTALK: + for I in 0 to 4 generate + U_xtalkf : OBUFDS generic map ( + IOSTANDARD=>"LVDS_25", + SLEW=>"FAST") + port map ( I => serialoutb(15) , O => serialoutxtf_p(I) , OB => serialoutxtf_n(I) ); + + U_xtalks : OBUFDS generic map ( + IOSTANDARD=>"LVDS_25", + SLEW=>"FAST") + port map ( I => serialoutb(23) , O => serialoutxts_p(I) , OB => serialoutxts_n(I) ); + + end generate CROSSTALK; + + U_doric : OBUF port map ( I => doricresetb , O => doricreset ); + U_link : OBUF port map ( I => '0' , O => transDis1 ); + + + -- FPGA Core + U_IBLcableTesterCore: IBLcableTesterCore port map ( + sysClk250 => sysClk250, sysRst250 => sysRst250, + sysClk125 => sysClk125, sysRst125 => sysRst125, + refClock => refClock, pgpClk => pgpClk, + pgpReset => pgpReset, mgtRxN => mgtRxN, + mgtRxP => mgtRxP, mgtTxN => mgtTxN, + mgtTxP => mgtTxP, serialin => serialinb, + serialout => serialoutb, retclock => retclockb, + clock160 => pgpClk, + clock80 => sysClk250, clock40 => sysClk125, + doricreset => doricresetb, resetOut => resetOut, + dispClk => dispClk, dispDat => dispDat, + dispLoadL => dispLoadL, dispRstL => dispRstL, + debug => debug + ); + --sysClk125i <= not sysClk125; + sysClk125i<=debug(0); +-- U_clock160: clock160 port map( +-- CLKIN_N_IN => iMainClkN, +-- CLKIN_P_IN => iMainClkP, +-- RST_IN => sysRst125, +-- CLKFX_OUT => open, +-- CLKIN_IBUFGDS_OUT => clkin, +-- CLK0_OUT => clk0, +-- LOCKED_OUT => open); + process(pgpClk) + begin + if(pgpClk'event and pgpClk='1') then + halfclock<= not halfclock; + end if; + end process; + process(halfclock) + begin + if(halfclock'event and halfclock='1') then + quarterclock<= not quarterclock; + end if; + end process; + process(pgpClk) + begin + if(pgpClk'event and pgpClk='1') then + clk80<= not clk80; + end if; + end process; + process(clk80) + begin + if(clk80'event and clk80='1') then + clk40<= not clk40; + end if; + end process; + --cdata(7 downto 0)<=serialinb(7 downto 0); + --cdata(31 downto 8) <=(others=>'0'); + --ctrig(0)<='0'; + --chipscope : ila + --port map ( + --CONTROL => ccontrol, + --CLK => mainClk, + --DATA => cdata, + --TRIG0 => ctrig); + --chipscopeicon : icon + --port map ( + --CONTROL0 => ccontrol); + +end IBLcableTester; diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/deser.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/deser.vhd new file mode 100644 index 0000000000000000000000000000000000000000..110b8e6df51ad2185256498b83147a696217dd4a --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/deser.vhd @@ -0,0 +1,70 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity deser is + +port( clk: in std_logic; + rst: in std_logic; + go: in std_logic; + d_in: in std_logic; + d_out: out std_logic_vector(31 downto 0); + ld: out std_logic +); +end deser; + +-------------------------------------------------------------- + +architecture DESER of deser is + +signal reg : std_logic_vector(31 downto 0); +signal going: std_logic; +signal counter: std_logic_vector(4 downto 0); + +begin + + + process(rst, clk) + + begin + if(rst='1') then + reg<=x"00000000"; + d_out<=x"00000000"; + going<='0'; + ld<='0'; + elsif (clk'event and clk='1') then + if (going='0') then + if(go='1' and d_in='1')then + going<='1'; + else + counter<="11110"; + end if; + else + if (counter="11111") then + ld<='1'; + d_out<=reg; + if(go='0')then + going<='0'; + end if; + elsif(counter="11110")then + ld<='0'; + end if; + counter<=unsigned(counter)-1; + end if; + reg(31 downto 1)<=reg(30 downto 0); + reg(0)<=d_in; + end if; + + end process; + +end DESER; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/deser16.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/deser16.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8d13af35a1752205e20c671916cebcc8aa193498 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/deser16.vhd @@ -0,0 +1,67 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity deser16 is + +port( clk: in std_logic; + rst: in std_logic; + go: in std_logic; + d_in: in std_logic; + d_out: out std_logic_vector(15 downto 0); + ld: out std_logic +); +end deser16; + +-------------------------------------------------------------- + +architecture DESER16 of deser16 is + +signal reg : std_logic_vector(15 downto 0); +signal counter: std_logic_vector(3 downto 0); +signal going: std_logic; + +begin + + + process(rst, clk) + + begin + if(rst='1') then + reg<=x"0000"; + d_out<=x"0000"; + going<='0'; + ld<='0'; + elsif (clk'event and clk='1') then + if(going='0' and go='1' and d_in='1')then + going<='1'; + counter<="1110"; + else + if (going='1' and counter="1111") then + ld<='1'; + d_out<=reg; + if(go='0')then + going<='0'; + end if; + elsif(counter="1110")then + ld<='0'; + end if; + counter<=unsigned(counter)-1; + end if; + reg(15 downto 1)<=reg(14 downto 0); + reg(0)<=d_in; + end if; + + end process; + +end DESER16; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_cmd.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_cmd.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a02a9a8e9471acad60953b891f68ce0345920d94 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_cmd.vhd @@ -0,0 +1,575 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 08/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity pattern_cmd is + +port( clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + retclk: in std_logic; + rst: in std_logic; + doricreset: out std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic +); +end pattern_cmd; + +-------------------------------------------------------------- + +architecture PATTERN_CMD of pattern_cmd is + +signal nloaded : std_logic_vector(9 downto 0); +signal pointer : std_logic_vector(9 downto 0); +signal header : std_logic_vector(9 downto 0); +signal nwords: std_logic_vector(63 downto 0); +signal nerr: std_logic_vector(63 downto 0); +signal current: std_logic_vector(31 downto 0); +signal doutb: std_logic_vector(31 downto 0); +signal douta: std_logic_vector(31 downto 0); +signal dout2: std_logic_vector(35 downto 0); +signal din: std_logic_vector(35 downto 0); +signal dataout: std_logic_vector(31 downto 0); +signal serdata: std_logic_vector(31 downto 0); +signal deserdata: std_logic_vector(15 downto 0); +signal xorword: std_logic_vector(15 downto 0); +signal xorbit: std_logic; +signal going: std_logic; +signal oldgoing: std_logic; +signal isgoing: std_logic; +signal ld: std_logic; +signal dld: std_logic; +signal oldld: std_logic; +signal olddld: std_logic; +signal ena: std_logic; +signal memena: std_logic; +signal resena: std_logic; +signal memacc: std_logic; +signal resacc: std_logic; +signal enaold: std_logic; +signal pgpEnaOld: std_logic; +signal full: std_logic; +signal empty: std_logic; +signal dataFE: std_logic; +signal docount: std_logic; +signal rescount: std_logic; +signal rescountena: std_logic; +signal injacc: std_logic; +signal oldinjacc: std_logic; +signal injena: std_logic; +signal desergo: std_logic; +signal wrfifo: std_logic; +signal intclk: std_logic; +signal thedeserclk: std_logic; +signal ccontrol: std_logic_vector(35 downto 0); +signal cdata: std_logic_vector(31 downto 0); +signal ctrig: std_logic_vector(0 downto 0); +signal overflownerr: std_logic; +signal overflownwords: std_logic; +signal carrynerr: std_logic; +signal carrynwords: std_logic; +signal nerrce: std_logic; +signal oldoverflownerr: std_logic; +signal retclkd: std_logic; + +function vectorize(s: std_logic) return std_logic_vector is +variable v: std_logic_vector(0 downto 0); +begin +v(0) := s; +return v; +end; + +function vectorize(v: std_logic_vector) return std_logic_vector is +begin +return v; +end; +component ser + port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + --isgoing: in std_logic; + inj: in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic + ); +end component; +component deser16 + port( clk: in std_logic; + rst: in std_logic; + go: in std_logic; + d_in: in std_logic; + d_out: out std_logic_vector(15 downto 0); + ld: out std_logic + ); + end component; +component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; + +component iblfifo + port ( + din: IN std_logic_VECTOR(35 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(35 downto 0); + empty: OUT std_logic; + full: OUT std_logic); +end component; +component counter30 + port ( + clk: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(29 downto 0)); +end component; +component BUFGMUX + port ( + O: out std_logic; + I0: in std_logic; + I1: in std_logic; + S: in std_logic + ); +end component; + +-- component ila +-- PORT ( +-- CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); +-- CLK : IN STD_LOGIC; +-- DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); +-- TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; +-- component icon +-- PORT ( +-- CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- +-- end component; +-- +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; +begin + + -- serdesrst<=rst or softreset; + pgpAck<=enaold; + memena<= ena and memacc; + resena<= ena and resacc; + rescountena<= ena and rescount; + din<="0000" & serdata; + --dataToFE<=dataFE; +-- with pgpRW select + -- maddr <= nloaded when '1', + -- "0000000" & addrPgp when '0'; + with memacc select + dataTopgp <= dataout when '0', + douta when '1', + (others=>'0') when others; +-- BUFGMUX_inst : BUFGMUX +-- port map ( +-- O => thedeserclk, -- Clock MUX output +-- I0 => retclk, -- Clock0 input +-- I1 => deserclk, -- Clock1 input +-- S => intclk -- Clock select input +-- ); + + with intclk select + thedeserclk<= retclk when '0', + not deserclk when '1', + '0' when others; + process(rst, clk) -- user interface + + begin + if(rst='1') then + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + ena<='1'; + enaold<='0'; + pgpEnaOld<='0'; + memacc<='0'; + pgpErr<='0'; + resacc<='1'; + oldgoing<='0'; + intclk<='0'; + elsif (clk'event and clk='1') then + if(pgpEnable='1' and pgpEnaOld='0') then + ena<='1'; + case pgpRW is + when '1' => -- WRITE + case going is + when '0' => -- not running + case addrPgp is + when "0000" => -- start + if(nloaded/="1111111111") then + going<='1'; + end if; + memacc<='0'; + pgpErr<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + when "0001" => -- stop + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + when "0010" => -- reset + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + memacc<='0'; + pgpErr<='0'; + resacc<='1'; + rescount<='1'; + injacc<='0'; + when "0011" => -- headersize + if unsigned(dataFromPgp(9 downto 0))>=unsigned(nloaded)+1 then + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + else + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + header<=dataFromPgp(9 downto 0); + end if; + when "0100" => -- write memory + if nloaded = "1111111110" then + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + else + memacc<='1'; + resacc<='0'; + pgpErr<='0'; + nloaded<=unsigned(nloaded)+1; + rescount<='0'; + injacc<='0'; + end if; + when "0101" => -- reset counters + rescount<='1'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + when "0111" => -- Use internal receive clock + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + intclk<='1'; + when "1000" => -- use receive clock from DORIC + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + intclk<='0'; + when others => -- error + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + end case; + when '1' => -- running + case addrPgp is + when "0001" => -- stop + pgpErr<='0'; + memacc<='0'; + resacc<='1'; + rescount<='0'; + injacc<='0'; + going<='0'; + when "0101" => -- reset counters + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + when "0110" => -- inject error + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='1'; + when others => + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + end case; + when others => + end case; + when '0' => -- READ (both running and stopped) + resacc<='0'; + injacc<='0'; + rescount<='0'; + case addrPgp is + when "0000" => -- number of words MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(63 downto 32); + when "0001" => -- number of words LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(31 downto 0); + when "0010" => -- number of errors MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(63 downto 32); + when "0011" => -- number of errors LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(31 downto 0); + when "0100" => -- number of loaded words + memacc<='0'; + pgpErr<='0'; + dataout<="0000000000000000000000" & unsigned(nloaded)+1; + when "0101" => -- last loaded word + if (nloaded="1111111111") then + pgpErr<='1'; + memacc<='0'; + dataout<=x"ffffffff"; + else + pgpErr<='0'; + memacc<='1'; + end if; + when "0110" => -- empty and full flags + memacc<='0'; + pgpErr<='0'; + dataout<=x"0000000" &'0'& going & full & empty; + when others => + memacc<='0'; + pgpErr<='1'; + dataout<=x"ffffffff"; + end case; + when others=> + end case; + else + ena<='0'; + end if; + pgpEnaOld<=pgpEnable; + enaold<=ena; + oldgoing<=going; + + end if; + + end process; + + process(serclk,rst) -- serializer + begin + if (rst='1') then + oldld<='0'; + pointer<="0000000000"; + desergo<='0'; + wrfifo<='0'; + doricreset<='1'; + elsif (serclk'event and serclk='1') then + if (going='1') then + if (ld='0' and oldld='1') then + if pointer=nloaded then + pointer<=header; + else + pointer<=unsigned(pointer)+1; + end if; + if(desergo='1') then + wrfifo<='1'; + end if; + elsif (ld='1' and oldld='0') then + if(pointer>=header) then + desergo<='1'; + doricreset<='1'; + else + doricreset<='0'; + end if; + else + wrfifo<='0'; + end if; + elsif (going='0' and oldgoing='1') then + pointer<="0000000000" ; + desergo<='0'; + wrfifo<='0'; + end if; + if (injacc='1' and oldinjacc='0') then + injena<='1'; + else + injena<='0'; + end if; + oldinjacc<=injacc; + oldld<=ld; + end if; + end process; + + process(thedeserclk,rst) -- deserializer + begin + if (rst='1') then + olddld<='0'; + xorbit<='0'; + nerrce<='0'; + oldoverflownerr<='0'; + xorword<=x"0000"; + elsif (thedeserclk'event and thedeserclk='1') then + if (olddld='1') then + for I in 15 downto 0 loop + xorword(I) <= deserdata(I) xor dout2(I*2) xor dout2(I*2+1); + end loop; + else + xorword(15 downto 1) <= xorword(14 downto 0); + xorword(0)<='0'; + end if; + xorbit<=xorword(15); + nerrce<=xorbit; + if(overflownerr='1' and oldoverflownerr='0')then + carrynerr<='1'; + else + carrynerr<='0'; + end if; + carrynwords<=overflownwords and dld; + olddld<=dld; + oldoverflownerr<=overflownerr; + end if; + end process; + +the_mem : pattern_blk_mem + port map ( + clka => clk, + dina => dataFromPgp, + addra => nloaded, + ena => memena, + wea => vectorize(pgpRW), + douta => douta, + clkb => serclk, + dinb => (others=>'0'), + addrb => pointer, + enb => ld, + web => vectorize('0'), + doutb => serdata); +serializer : ser + port map ( + clk => serclk, + ld => ld, + go => going, + --isgoing => isgoing, + inj => injena, + rst => resena, + d_in => serdata, + d_out => dataToFE ); + + +valstore : iblfifo -- stores the values to be checked + port map ( + din => din, + rd_clk => thedeserclk, + rd_en => dld, + rst => resena, + wr_clk => serclk, + wr_en => wrfifo, + dout => dout2, + empty => empty, + full => full); +deserializer: deser16 + port map ( + clk => thedeserclk, + rst => resena, + go => desergo, + d_in => dataFromFE, + d_out => deserdata, + ld => dld); +nerrlow : counter30 + port map ( + clk => thedeserclk, + ce => nerrce, + aclr => rescountena, + q_thresh0 => overflownerr, + q => nerr(29 downto 0)); +nerrhigh : counter30 + port map ( + clk => thedeserclk, + ce => carrynerr, + aclr => rescountena, + q_thresh0 => open, + q => nerr(59 downto 30)); + +nerr(63 downto 60)<="0000"; + +nwordslow : counter30 + port map ( + clk => thedeserclk, + ce => olddld, + aclr => rescountena, + q_thresh0 => overflownwords, + q => nwords(29 downto 0)); +nwordshigh : counter30 + port map ( + clk => thedeserclk, + ce => carrynwords, + aclr => rescountena, + q_thresh0 => open, + q => nwords(59 downto 30)); + +nwords(63 downto 60)<="0000"; +-- cdata(0)<=dld; +-- cdata(1)<=olddld; +-- cdata(2)<=docount; +-- cdata(3)<=dataFromFE; +-- cdata(7 downto 4)<=dout2(31 downto 28); +-- cdata(23 downto 8)<=deserdata; +-- cdata(31 downto 24)<=dout2(7 downto 0); +-- ctrig(0)<=desergo; +-- chipscope : ila +-- port map ( +-- CONTROL => ccontrol, +-- CLK => deserclk, +-- DATA => cdata, +-- TRIG0 => ctrig); +-- chipscopeicon : icon +-- port map ( +-- CONTROL0 => ccontrol); + + +end PATTERN_CMD; +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_mem.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_mem.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0ed40e5b836743bde4d3f34c576a98a47ce266f6 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_mem.vhd @@ -0,0 +1,745 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 08/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity pattern_mem is +generic( DELAY: integer:=0); +port( clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + deserclk90: in std_logic; + rst: in std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic +); +end pattern_mem; + +-------------------------------------------------------------- + +architecture PATTERN_MEM of pattern_mem is + +signal nloaded : std_logic_vector(9 downto 0); +signal pointer : std_logic_vector(9 downto 0); +signal header : std_logic_vector(9 downto 0); +signal nwords: std_logic_vector(63 downto 0); +signal nerr: std_logic_vector(63 downto 0); +signal current: std_logic_vector(31 downto 0); +signal doutb: std_logic_vector(31 downto 0); +signal douta: std_logic_vector(31 downto 0); +signal dout2: std_logic_vector(35 downto 0); +signal din: std_logic_vector(35 downto 0); +signal dataout: std_logic_vector(31 downto 0); +signal serdata: std_logic_vector(31 downto 0); +signal deserdata: std_logic_vector(31 downto 0); +signal xorword: std_logic_vector(31 downto 0); +signal xorword2: std_logic_vector(31 downto 0); +signal xorbit: std_logic; +signal going: std_logic; +signal oldgoing: std_logic; +signal ld: std_logic; +signal dld: std_logic; +signal oldld: std_logic; +signal olddld: std_logic; +signal ena: std_logic; +signal memena: std_logic; +signal resena: std_logic; +signal delena: std_logic; +signal delrstena: std_logic; +signal delayreset: std_logic; +signal delacc: std_logic; +signal delrstacc: std_logic; +signal memacc: std_logic; +signal resacc: std_logic; +signal enaold: std_logic; +signal pgpEnaOld: std_logic; +signal full: std_logic; +signal empty: std_logic; +signal dataFE: std_logic; +signal dataFEsync: std_logic; +signal dataFromFEd: std_logic; +signal rescount: std_logic; +signal rescountena: std_logic; +signal injacc: std_logic; +signal oldinjacc: std_logic; +signal injena: std_logic; +signal loopback: std_logic; +signal ccontrol: std_logic_vector(35 downto 0); +signal cdata: std_logic_vector(31 downto 0); +signal ctrig: std_logic_vector(0 downto 0); +signal overflownerr: std_logic; +signal overflownwords: std_logic; +signal carrynerr: std_logic; +signal carrynwords: std_logic; +signal nerrce: std_logic; +signal oldoverflownerr: std_logic; +signal dataToFEs: std_logic; +signal phaseConfig: std_logic; +signal oldPhaseConfig: std_logic; +signal doPhaseConfig: std_logic; + + +function vectorize(s: std_logic) return std_logic_vector is +variable v: std_logic_vector(0 downto 0); +begin +v(0) := s; +return v; +end; + +function vectorize(v: std_logic_vector) return std_logic_vector is +begin +return v; +end; +component ser + port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + inj: in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic + ); +end component; +component deser + port( clk: in std_logic; + rst: in std_logic; + go: in std_logic; + d_in: in std_logic; + d_out: out std_logic_vector(31 downto 0); + ld: out std_logic + ); + end component; + component syncdatac port ( + clk : in std_logic ; -- clock input + clk90 : in std_logic ; -- clock 90 input + rdatain : in std_logic; -- data input + rst : in std_logic ; -- reset input + useaout : out std_logic ; -- useA output for cascade + usebout : out std_logic ; -- useB output for cascade + usecout : out std_logic ; -- useC output for cascade + usedout : out std_logic ; -- useD output for cascade + sdataout : out std_logic; -- data out + phaseConfig : in std_logic); -- FS: Setting phase configuration flag + end component; +component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; +COMPONENT pattern_blk_mem_62 + PORT ( + clka : IN STD_LOGIC; + ena : IN STD_LOGIC; + wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0); + dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + clkb : IN STD_LOGIC; + enb : IN STD_LOGIC; + addrb : IN STD_LOGIC_VECTOR(9 DOWNTO 0); + doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) + ); +END COMPONENT; +component iblfifo + port ( + din: IN std_logic_VECTOR(35 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(35 downto 0); + empty: OUT std_logic; + full: OUT std_logic); +end component; +component counter30 + port ( + clk: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(29 downto 0)); +end component; +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + +--component ila + --PORT ( + --CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + --CLK : IN STD_LOGIC; + --DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; + --component icon + --PORT ( + --CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- + --end component; + +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + +begin + + dataToFE<=dataToFEs; + -- serdesrst<=rst or softreset; + pgpAck<=enaold; + memena<= ena and memacc; + resena<= ena and resacc; + delena<= ena and delacc; + delrstena<= ena and delrstacc; + rescountena<= ena and rescount; + din<="0000" & serdata; + with loopback select + dataFE <= dataFromFEd when '0', + dataToFEs when '1', + '0' when others; +-- with pgpRW select + -- maddr <= nloaded when '1', + -- "0000000" & addrPgp when '0'; + with memacc select + dataTopgp <= dataout when '0', + douta when '1', + (others=>'0') when others; + + process(rst, clk) -- user interface + + begin + if(rst='1') then + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + ena<='1'; + enaold<='0'; + pgpEnaOld<='0'; + memacc<='0'; + rescount<='0'; + pgpErr<='0'; + resacc<='1'; + delrstacc<='0'; + delacc<='0'; + oldgoing<='0'; + loopback<='0'; + phaseConfig <='0'; + elsif (clk'event and clk='1') then + if(pgpEnable='1' and pgpEnaOld='0') then + ena<='1'; + case pgpRW is + when '1' => -- WRITE + case going is + when '0' => -- not running + case addrPgp is + when "0000" => -- start + if(nloaded/="1111111111") then + going<='1'; + end if; + memacc<='0'; + pgpErr<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0001" => -- stop + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0010" => -- reset + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + memacc<='0'; + pgpErr<='0'; + resacc<='1'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0011" => -- headersize + if unsigned(dataFromPgp(9 downto 0))>=unsigned(nloaded)+1 then + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + delacc<='0'; + rescount<='0'; + delrstacc<='0'; + phaseConfig<='0'; + else + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + header<=dataFromPgp(9 downto 0); + end if; + when "0100" => -- write memory + if nloaded = "1111111110" then + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + else + memacc<='1'; + resacc<='0'; + pgpErr<='0'; + nloaded<=unsigned(nloaded)+1; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + end if; + when "0101" => -- reset counters + rescount<='1'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + delacc<='0'; + injacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0111" => -- loopback on + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + delacc<='0'; + loopback<='1'; + delrstacc<='0'; + phaseConfig<='0'; + when "1000" => -- loopback off + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + delacc<='0'; + loopback<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "1001" => -- increment delay for incoming serial data + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + rescount<='0'; + injacc<='0'; + delacc<='1'; + delrstacc<='0'; + phaseConfig<='0'; + when "1010" => -- reset delay + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='1'; + phaseConfig<='0'; + when others => -- error + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + end case; + when '1' => -- running + case addrPgp is + when "0001" => -- stop + pgpErr<='0'; + memacc<='0'; + resacc<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + going<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0101" => -- reset counters + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "0110" => -- inject error + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='1'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + when "1001" => -- increment delay for incoming serial data + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='1'; + delrstacc<='0'; + phaseConfig<='0'; + when "1010" => -- reset delay for incoming serial data + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='1'; + phaseConfig<='0'; + when "1011" => -- calibrate phase + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='1'; + when others => + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + end case; + when others => + end case; + when '0' => -- READ (both running and stopped) + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='0'; + phaseConfig<='0'; + case addrPgp is + when "0000" => -- number of words MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(63 downto 32); + when "0001" => -- number of words LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(31 downto 0); + when "0010" => -- number of errors MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(63 downto 32); + when "0011" => -- number of errors LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(31 downto 0); + when "0100" => -- number of loaded words + memacc<='0'; + pgpErr<='0'; + dataout<="0000000000000000000000" & unsigned(nloaded)+1; + when "0101" => -- last loaded word + if (nloaded="1111111111") then + pgpErr<='1'; + memacc<='0'; + dataout<=x"ffffffff"; + else + pgpErr<='0'; + memacc<='1'; + end if; + when "0110" => -- empty and full flags + memacc<='0'; + pgpErr<='0'; + dataout<=x"0000000" &'0'& going & full & empty; + when others => + memacc<='0'; + pgpErr<='1'; + dataout<=x"ffffffff"; + end case; + when others => + end case; + else + ena<='0'; + end if; + pgpEnaOld<=pgpEnable; + enaold<=ena; + oldgoing<=going; + delayreset<=delrstena or rst; + end if; + + end process; + + process(serclk,rst) -- serializer + begin + if (rst='1') then + oldld<='0'; + pointer<="0000000000"; + elsif (serclk'event and serclk='1') then + if (going='1') then + if (ld='0' and oldld='1') then + if pointer=nloaded then + pointer<=header; + else + pointer<=unsigned(pointer)+1; + end if; + end if; + elsif (going='0' and oldgoing='1') then + pointer<="0000000000" ; + end if; + if (injacc='1' and oldinjacc='0') then + injena<='1'; + else + injena<='0'; + end if; + oldinjacc<=injacc; + oldld<=ld; + end if; + end process; + + process(deserclk,rst) -- deserializer + begin + if (rst='1') then + oldphaseConfig <= '0'; + doPhaseConfig <='0'; + olddld<='0'; + nerrce<='0'; + oldoverflownerr<='0'; + xorword<=x"00000000"; + xorword2<=x"00000000"; + xorbit<='0'; + elsif (deserclk'event and deserclk='1') then + if (olddld='1') then + xorword2<=dout2(31 downto 0); + xorword<= deserdata ; +-- xorword<=x"12345678"; + else + xorword(31 downto 1) <= xorword(30 downto 0); + xorword(0)<='0'; + xorword2(31 downto 1) <= xorword2(30 downto 0); + xorword2(0)<='0'; + end if; + xorbit<=xorword(31) xor xorword2(31); + nerrce<=xorbit; + if(overflownerr='1' and oldoverflownerr='0')then + carrynerr<='1'; + else + carrynerr<='0'; + end if; + if(phaseConfig='1' and oldphaseConfig='0')then + doPhaseConfig<='1'; + else + doPhaseConfig<='0'; + end if; + carrynwords<=overflownwords and dld; + olddld<=dld; + oldoverflownerr<=overflownerr; + oldphaseConfig<=phaseConfig; + end if; + end process; + +the_mem : pattern_blk_mem + port map ( + clka => clk, + dina => dataFromPgp, + addra => nloaded, + ena => memena, + wea => vectorize(pgpRW), + douta => douta, + clkb => serclk, + dinb => (others=>'0'), + addrb => pointer, + enb => ld, + web => vectorize('0'), + doutb => serdata); +-- the_mem : pattern_blk_mem_62 +-- PORT MAP ( +-- clka => clk, +-- ena => memena, +-- wea => vectorize(pgpRW), +-- addra => nloaded, +-- dina => dataFromPgp, +-- clkb => serclk, +-- enb => ld, +-- addrb => pointer, +-- doutb => serdata +-- ); +serializer : ser + port map ( + clk => serclk, + ld => ld, + go => going, + inj => injena, + rst => resena, + d_in => serdata, + d_out => dataToFEs ); + +valstore : iblfifo -- stores the values to be checked + port map ( + din => din, + rd_clk => deserclk, + rd_en => dld, + rst => resena, + wr_clk => serclk, + wr_en => oldld, + dout => dout2, + empty => empty, + full => full); + receivedata: syncdatac + port map( + phaseConfig => doPhaseConfig, + clk => deserclk, + clk90 => deserclk90, + rdatain => dataFE, + --rdatain => IOMXOUT(1), + rst => rst, + useaout => open, + usebout => open, + usecout => open, + usedout => open, + sdataout => dataFEsync); +deserializer: deser + port map ( + clk => deserclk, + rst => resena, + go => going, + d_in => dataFEsync, + d_out => deserdata, + ld => dld); +nerrlow : counter30 + port map ( + clk => deserclk, + ce => nerrce, + aclr => rescountena, + q_thresh0 => overflownerr, + q => nerr(29 downto 0)); +nerrhigh : counter30 + port map ( + clk => deserclk, + ce => carrynerr, + aclr => rescountena, + q_thresh0 => open, + q => nerr(59 downto 30)); + +nerr(63 downto 60)<="0000"; + +nwordslow : counter30 + port map ( + clk => deserclk, + ce => olddld, + aclr => rescountena, + q_thresh0 => overflownwords, + q => nwords(29 downto 0)); +nwordshigh : counter30 + port map ( + clk => deserclk, + ce => carrynwords, + aclr => rescountena, + q_thresh0 => open, + q => nwords(59 downto 30)); + +nwords(63 downto 60)<="0000"; + +delayline : IDELAY + generic map ( + IOBDELAY_TYPE => "VARIABLE", -- Set to DEFAULT for -- Zero Hold Time Mode + IOBDELAY_VALUE => 0 -- (0 to 63) + ) + port map ( + O => dataFromFEd, + I => dataFromFE, + C => clk, + CE => delena, + INC => '1', + RST => delayreset + ); + + + +-- cdata(0)<=dld; +-- cdata(1)<=olddld; +-- cdata(2)<=overflownerr; +-- cdata(3)<=carrynerr; +-- cdata(4)<=nerrce; +-- cdata(5)<=nerr(30); +-- cdata(6)<=nerr(31); +-- cdata(7)<=nerr(0); +-- cdata(8)<=nerr(1); +-- cdata(3)<=olddld; +-- cdata(4)<=docount; +-- cdata(5)<=datafe; +-- cdata(6)<=xorword(31); +-- cdata(7)<=xorword2(31); +-- cdata(8)<=loopback; +-- cdata(9)<=dataFromFE; +-- cdata(31 downto 9) <=(others=>'0'); +-- ctrig(0)<=overflownerr; +-- chipscope : ila +-- port map ( +-- CONTROL => ccontrol, +-- CLK => deserclk, +-- DATA => cdata, +-- TRIG0 => ctrig); +-- chipscopeicon : icon +-- port map ( +-- CONTROL0 => ccontrol); + +end PATTERN_MEM; +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_memOld.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_memOld.vhd new file mode 100644 index 0000000000000000000000000000000000000000..856a4d99a482eefb7e49f303874dff6e761e4186 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/pattern_memOld.vhd @@ -0,0 +1,677 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 08/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity pattern_mem is +generic( DELAY: integer:=0); +port( clk: in std_logic; + serclk: in std_logic; + deserclk: in std_logic; + rst: in std_logic; + pgpEnable: in std_logic; + pgpRW: in std_logic; + pgpAck: out std_logic; + pgpErr: out std_logic; + dataFromPgp:in std_logic_vector(31 downto 0); + addrPgp: in std_logic_vector(3 downto 0); + dataToPgp: out std_logic_vector(31 downto 0); + dataFromFE: in std_logic; + dataToFE: out std_logic +); +end pattern_mem; + +-------------------------------------------------------------- + +architecture PATTERN_MEM of pattern_mem is + +signal nloaded : std_logic_vector(9 downto 0); +signal pointer : std_logic_vector(9 downto 0); +signal header : std_logic_vector(9 downto 0); +signal nwords: std_logic_vector(63 downto 0); +signal nerr: std_logic_vector(63 downto 0); +signal current: std_logic_vector(31 downto 0); +signal doutb: std_logic_vector(31 downto 0); +signal douta: std_logic_vector(31 downto 0); +signal dout2: std_logic_vector(35 downto 0); +signal din: std_logic_vector(35 downto 0); +signal dataout: std_logic_vector(31 downto 0); +signal serdata: std_logic_vector(31 downto 0); +signal deserdata: std_logic_vector(31 downto 0); +signal xorword: std_logic_vector(31 downto 0); +signal xorword2: std_logic_vector(31 downto 0); +signal xorbit: std_logic; +signal going: std_logic; +signal oldgoing: std_logic; +signal ld: std_logic; +signal dld: std_logic; +signal oldld: std_logic; +signal olddld: std_logic; +signal ena: std_logic; +signal memena: std_logic; +signal resena: std_logic; +signal delena: std_logic; +signal delrstena: std_logic; +signal delayreset: std_logic; +signal delacc: std_logic; +signal delrstacc: std_logic; +signal memacc: std_logic; +signal resacc: std_logic; +signal enaold: std_logic; +signal pgpEnaOld: std_logic; +signal full: std_logic; +signal empty: std_logic; +signal dataFE: std_logic; +signal dataFromFEd: std_logic; +signal rescount: std_logic; +signal rescountena: std_logic; +signal injacc: std_logic; +signal oldinjacc: std_logic; +signal injena: std_logic; +signal loopback: std_logic; +signal ccontrol: std_logic_vector(35 downto 0); +signal cdata: std_logic_vector(31 downto 0); +signal ctrig: std_logic_vector(0 downto 0); +signal overflownerr: std_logic; +signal overflownwords: std_logic; +signal carrynerr: std_logic; +signal carrynwords: std_logic; +signal nerrce: std_logic; +signal oldoverflownerr: std_logic; +signal dataToFEs: std_logic; + + +function vectorize(s: std_logic) return std_logic_vector is +variable v: std_logic_vector(0 downto 0); +begin +v(0) := s; +return v; +end; + +function vectorize(v: std_logic_vector) return std_logic_vector is +begin +return v; +end; +component ser + port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + inj: in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic + ); +end component; +component deser + port( clk: in std_logic; + rst: in std_logic; + go: in std_logic; + d_in: in std_logic; + d_out: out std_logic_vector(31 downto 0); + ld: out std_logic + ); + end component; +component pattern_blk_mem + port ( + clka: IN std_logic; + dina: IN std_logic_VECTOR(31 downto 0); + addra: IN std_logic_VECTOR(9 downto 0); + ena: IN std_logic; + wea: IN std_logic_VECTOR(0 downto 0); + douta: OUT std_logic_VECTOR(31 downto 0); + clkb: IN std_logic; + dinb: IN std_logic_VECTOR(31 downto 0); + addrb: IN std_logic_VECTOR(9 downto 0); + enb: IN std_logic; + web: IN std_logic_VECTOR(0 downto 0); + doutb: OUT std_logic_VECTOR(31 downto 0)); +end component; +COMPONENT pattern_blk_mem_62 + PORT ( + clka : IN STD_LOGIC; + ena : IN STD_LOGIC; + wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0); + dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + clkb : IN STD_LOGIC; + enb : IN STD_LOGIC; + addrb : IN STD_LOGIC_VECTOR(9 DOWNTO 0); + doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) + ); +END COMPONENT; +component iblfifo + port ( + din: IN std_logic_VECTOR(35 downto 0); + rd_clk: IN std_logic; + rd_en: IN std_logic; + rst: IN std_logic; + wr_clk: IN std_logic; + wr_en: IN std_logic; + dout: OUT std_logic_VECTOR(35 downto 0); + empty: OUT std_logic; + full: OUT std_logic); +end component; +component counter30 + port ( + clk: IN std_logic; + ce: IN std_logic; + aclr: IN std_logic; + q_thresh0: OUT std_logic; + q: OUT std_logic_VECTOR(29 downto 0)); +end component; +component IDELAY + generic (IOBDELAY_TYPE : string := "DEFAULT"; --(DEFAULT, FIXED, VARIABLE) + IOBDELAY_VALUE : integer := 0 --(0 to 63) + ); + port ( + O : out STD_LOGIC; + I : in STD_LOGIC; + C : in STD_LOGIC; + CE : in STD_LOGIC; + INC : in STD_LOGIC; + RST : in STD_LOGIC + ); +end component; + +--component ila + --PORT ( + --CONTROL : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0); + --CLK : IN STD_LOGIC; + --DATA : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --TRIG0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)); +-- +--end component; + --component icon + --PORT ( + --CONTROL0 : INOUT STD_LOGIC_VECTOR(35 DOWNTO 0)); +-- + --end component; + +-- attribute syn_noprune : boolean; +-- attribute syn_noprune of chipscope : label is true; +-- attribute syn_noprune of chipscopeicon : label is true; + +begin + + dataToFE<=dataToFEs; + -- serdesrst<=rst or softreset; + pgpAck<=enaold; + memena<= ena and memacc; + resena<= ena and resacc; + delena<= ena and delacc; + delrstena<= ena and delrstacc; + rescountena<= ena and rescount; + din<="0000" & serdata; + with loopback select + dataFE <= dataFromFEd when '0', + dataToFEs when '1', + '0' when others; +-- with pgpRW select + -- maddr <= nloaded when '1', + -- "0000000" & addrPgp when '0'; + with memacc select + dataTopgp <= dataout when '0', + douta when '1', + (others=>'0') when others; + + process(rst, clk) -- user interface + + begin + if(rst='1') then + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + ena<='1'; + enaold<='0'; + pgpEnaOld<='0'; + memacc<='0'; + rescount<='0'; + pgpErr<='0'; + resacc<='1'; + delrstacc<='0'; + delacc<='0'; + oldgoing<='0'; + loopback<='0'; + elsif (clk'event and clk='1') then + if(pgpEnable='1' and pgpEnaOld='0') then + ena<='1'; + case pgpRW is + when '1' => -- WRITE + case going is + when '0' => -- not running + case addrPgp is + when "0000" => -- start + if(nloaded/="1111111111") then + going<='1'; + end if; + memacc<='0'; + pgpErr<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + when "0001" => -- stop + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + when "0010" => -- reset + nloaded<="1111111111"; + header<="0000000000"; + current<=x"00000000"; + going<='0'; + memacc<='0'; + pgpErr<='0'; + resacc<='1'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + when "0011" => -- headersize + if unsigned(dataFromPgp(9 downto 0))>=unsigned(nloaded)+1 then + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + delacc<='0'; + rescount<='0'; + delrstacc<='0'; + else + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + header<=dataFromPgp(9 downto 0); + end if; + when "0100" => -- write memory + if nloaded = "1111111110" then + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + else + memacc<='1'; + resacc<='0'; + pgpErr<='0'; + nloaded<=unsigned(nloaded)+1; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + end if; + when "0101" => -- reset counters + rescount<='1'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + delacc<='0'; + injacc<='0'; + delrstacc<='0'; + when "0111" => -- loopback on + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + delacc<='0'; + loopback<='1'; + delrstacc<='0'; + when "1000" => -- loopback off + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='0'; + delacc<='0'; + loopback<='0'; + delrstacc<='0'; + when "1001" => -- increment delay for incoming serial data + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + rescount<='0'; + injacc<='0'; + delacc<='1'; + delrstacc<='0'; + when "1010" => -- reset delay + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='1'; + when others => -- error + memacc<='0'; + resacc<='0'; + pgpErr<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + end case; + when '1' => -- running + case addrPgp is + when "0001" => -- stop + pgpErr<='0'; + memacc<='0'; + resacc<='1'; + rescount<='0'; + injacc<='0'; + delacc<='0'; + going<='0'; + delrstacc<='0'; + when "0101" => -- reset counters + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + rescount<='1'; + injacc<='0'; + delacc<='0'; + delrstacc<='0'; + when "0110" => -- inject error + rescount<='0'; + memacc<='0'; + resacc<='0'; + pgpErr<='0'; + injacc<='1'; + delacc<='0'; + delrstacc<='0'; + when "1001" => -- increment delay for incoming serial data + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='1'; + delrstacc<='0'; + when "1010" => -- reset delay for incoming serial data + pgpErr<='0'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='1'; + when others => + pgpErr<='1'; + memacc<='0'; + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='0'; + end case; + when others => + end case; + when '0' => -- READ (both running and stopped) + resacc<='0'; + injacc<='0'; + rescount<='0'; + delacc<='0'; + delrstacc<='0'; + case addrPgp is + when "0000" => -- number of words MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(63 downto 32); + when "0001" => -- number of words LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nwords(31 downto 0); + when "0010" => -- number of errors MSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(63 downto 32); + when "0011" => -- number of errors LSB + memacc<='0'; + pgpErr<='0'; + dataout<=nerr(31 downto 0); + when "0100" => -- number of loaded words + memacc<='0'; + pgpErr<='0'; + dataout<="0000000000000000000000" & unsigned(nloaded)+1; + when "0101" => -- last loaded word + if (nloaded="1111111111") then + pgpErr<='1'; + memacc<='0'; + dataout<=x"ffffffff"; + else + pgpErr<='0'; + memacc<='1'; + end if; + when "0110" => -- empty and full flags + memacc<='0'; + pgpErr<='0'; + dataout<=x"0000000" &'0'& going & full & empty; + when others => + memacc<='0'; + pgpErr<='1'; + dataout<=x"ffffffff"; + end case; + when others => + end case; + else + ena<='0'; + end if; + pgpEnaOld<=pgpEnable; + enaold<=ena; + oldgoing<=going; + delayreset<=delrstena or rst; + end if; + + end process; + + process(serclk,rst) -- serializer + begin + if (rst='1') then + oldld<='0'; + pointer<="0000000000"; + elsif (serclk'event and serclk='1') then + if (going='1') then + if (ld='0' and oldld='1') then + if pointer=nloaded then + pointer<=header; + else + pointer<=unsigned(pointer)+1; + end if; + end if; + elsif (going='0' and oldgoing='1') then + pointer<="0000000000" ; + end if; + if (injacc='1' and oldinjacc='0') then + injena<='1'; + else + injena<='0'; + end if; + oldinjacc<=injacc; + oldld<=ld; + end if; + end process; + + process(deserclk,rst) -- deserializer + begin + if (rst='1') then + olddld<='0'; + nerrce<='0'; + oldoverflownerr<='0'; + xorword<=x"00000000"; + xorword2<=x"00000000"; + xorbit<='0'; + elsif (deserclk'event and deserclk='1') then + if (olddld='1') then + xorword2<=dout2(31 downto 0); + xorword<= deserdata ; +-- xorword<=x"12345678"; + else + xorword(31 downto 1) <= xorword(30 downto 0); + xorword(0)<='0'; + xorword2(31 downto 1) <= xorword2(30 downto 0); + xorword2(0)<='0'; + end if; + xorbit<=xorword(31) xor xorword2(31); + nerrce<=xorbit; + if(overflownerr='1' and oldoverflownerr='0')then + carrynerr<='1'; + else + carrynerr<='0'; + end if; + carrynwords<=overflownwords and dld; + olddld<=dld; + oldoverflownerr<=overflownerr; + end if; + end process; + +the_mem : pattern_blk_mem + port map ( + clka => clk, + dina => dataFromPgp, + addra => nloaded, + ena => memena, + wea => vectorize(pgpRW), + douta => douta, + clkb => serclk, + dinb => (others=>'0'), + addrb => pointer, + enb => ld, + web => vectorize('0'), + doutb => serdata); +-- the_mem : pattern_blk_mem_62 +-- PORT MAP ( +-- clka => clk, +-- ena => memena, +-- wea => vectorize(pgpRW), +-- addra => nloaded, +-- dina => dataFromPgp, +-- clkb => serclk, +-- enb => ld, +-- addrb => pointer, +-- doutb => serdata +-- ); +serializer : ser + port map ( + clk => serclk, + ld => ld, + go => going, + inj => injena, + rst => resena, + d_in => serdata, + d_out => dataToFEs ); + +valstore : iblfifo -- stores the values to be checked + port map ( + din => din, + rd_clk => deserclk, + rd_en => dld, + rst => resena, + wr_clk => serclk, + wr_en => oldld, + dout => dout2, + empty => empty, + full => full); +deserializer: deser + port map ( + clk => deserclk, + rst => resena, + go => going, + d_in => dataFE, + d_out => deserdata, + ld => dld); +nerrlow : counter30 + port map ( + clk => deserclk, + ce => nerrce, + aclr => rescountena, + q_thresh0 => overflownerr, + q => nerr(29 downto 0)); +nerrhigh : counter30 + port map ( + clk => deserclk, + ce => carrynerr, + aclr => rescountena, + q_thresh0 => open, + q => nerr(59 downto 30)); + +nerr(63 downto 60)<="0000"; + +nwordslow : counter30 + port map ( + clk => deserclk, + ce => olddld, + aclr => rescountena, + q_thresh0 => overflownwords, + q => nwords(29 downto 0)); +nwordshigh : counter30 + port map ( + clk => deserclk, + ce => carrynwords, + aclr => rescountena, + q_thresh0 => open, + q => nwords(59 downto 30)); + +nwords(63 downto 60)<="0000"; + +delayline : IDELAY + generic map ( + IOBDELAY_TYPE => "VARIABLE", -- Set to DEFAULT for -- Zero Hold Time Mode + IOBDELAY_VALUE => 0 -- (0 to 63) + ) + port map ( + O => dataFromFEd, + I => dataFromFE, + C => clk, + CE => delena, + INC => '1', + RST => delayreset + ); + + + +-- cdata(0)<=dld; +-- cdata(1)<=olddld; +-- cdata(2)<=overflownerr; +-- cdata(3)<=carrynerr; +-- cdata(4)<=nerrce; +-- cdata(5)<=nerr(30); +-- cdata(6)<=nerr(31); +-- cdata(7)<=nerr(0); +-- cdata(8)<=nerr(1); +-- cdata(3)<=olddld; +-- cdata(4)<=docount; +-- cdata(5)<=datafe; +-- cdata(6)<=xorword(31); +-- cdata(7)<=xorword2(31); +-- cdata(8)<=loopback; +-- cdata(9)<=dataFromFE; +-- cdata(31 downto 9) <=(others=>'0'); +-- ctrig(0)<=overflownerr; +-- chipscope : ila +-- port map ( +-- CONTROL => ccontrol, +-- CLK => deserclk, +-- DATA => cdata, +-- TRIG0 => ctrig); +-- chipscopeicon : icon +-- port map ( +-- CONTROL0 => ccontrol); + +end PATTERN_MEM; +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/phaseshift.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/phaseshift.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e1c3e1624d24b51845a7ce23df9feaad4195e90f --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/phaseshift.vhd @@ -0,0 +1,104 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved. +-------------------------------------------------------------------------------- +-- ____ ____ +-- / /\/ / +-- /___/ \ / Vendor: Xilinx +-- \ \ \/ Version : 10.1.03 +-- \ \ Application : xaw2vhdl +-- / / Filename : phaseshift.vhd +-- /___/ /\ Timestamp : 08/24/2009 10:21:32 +-- \ \ / \ +-- \___\/\___\ +-- +--Command: xaw2vhdl-st /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores//phaseshift.xaw /a/sulky20/g.ee.u07/kocian/minilat/xilinx/IBL/xil_cores//phaseshift +--Design Name: phaseshift +--Device: xc4vfx60-10ff1152 +-- +-- Module phaseshift +-- Generated by Xilinx Architecture Wizard +-- Written for synthesis tool: Synplify + +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; +library UNISIM; +use UNISIM.Vcomponents.ALL; + +entity phaseshift is + port ( CLKIN_IN : in std_logic; + DADDR_IN : in std_logic_vector (6 downto 0); + DCLK_IN : in std_logic; + DEN_IN : in std_logic; + DI_IN : in std_logic_vector (15 downto 0); + DWE_IN : in std_logic; + RST_IN : in std_logic; + CLK0_OUT : out std_logic; + CLKFX_OUT : out std_logic; + CLK2X_OUT : out std_logic; + DRDY_OUT : out std_logic; + LOCKED_OUT : out std_logic); +end phaseshift; + +architecture BEHAVIORAL of phaseshift is + signal CLKFB_IN : std_logic; + signal CLK0_BUF : std_logic; + signal CLKFX_BUF : std_logic; + signal CLK2X_BUF : std_logic; +begin + CLK0_OUT <= CLKFB_IN; + CLK0_BUFG_INST : BUFG + port map (I=>CLK0_BUF, + O=>CLKFB_IN); + CLKFX_BUFG_INST : BUFG + port map (I=>CLKFX_BUF, + O=>CLKFX_OUT); + CLK2X_BUFG_INST : BUFG + port map (I=>CLK2X_BUF, + O=>CLK2X_OUT); + + DCM_ADV_INST : DCM_ADV + generic map( CLK_FEEDBACK => "1X", + CLKDV_DIVIDE => 2.0, + CLKFX_DIVIDE => 2, + CLKFX_MULTIPLY => 2, + CLKIN_DIVIDE_BY_2 => FALSE, + CLKIN_PERIOD => 12.8, + CLKOUT_PHASE_SHIFT => "DIRECT", + DCM_AUTOCALIBRATION => TRUE, + DCM_PERFORMANCE_MODE => "MAX_SPEED", + DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", + DFS_FREQUENCY_MODE => "LOW", + DLL_FREQUENCY_MODE => "LOW", + DUTY_CYCLE_CORRECTION => TRUE, + FACTORY_JF => x"F0F0", + PHASE_SHIFT => 0, + STARTUP_WAIT => FALSE) + port map (CLKFB=>CLKFB_IN, + CLKIN=>CLKIN_IN, + DADDR(6 downto 0)=>DADDR_IN(6 downto 0), + DCLK=>DCLK_IN, + DEN=>DEN_IN, + DI(15 downto 0)=>DI_IN(15 downto 0), + DWE=>DWE_IN, + PSCLK=>'0', + PSEN=>'0', + PSINCDEC=>'0', + RST=>RST_IN, + CLKDV=>open, + CLKFX=>CLKFX_BUF, + CLKFX180=>open, + CLK0=>CLK0_BUF, + CLK2X=>CLK2X_BUF, + CLK2X180=>open, + CLK90=>open, + CLK180=>open, + CLK270=>open, + DO=>open, + DRDY=>DRDY_OUT, + LOCKED=>LOCKED_OUT, + PSDONE=>open); + +end BEHAVIORAL; + + diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/ser.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/ser.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8904613c085ba0ef20599d91ec9eca4f0b6739a1 --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/ser.vhd @@ -0,0 +1,74 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity ser is + +port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + inj : in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic +); +end ser; + +-------------------------------------------------------------- + +architecture SER of ser is + +signal reg : std_logic_vector(31 downto 0); +signal going: std_logic; +signal counter: std_logic_vector(4 downto 0); + +begin + + + process(rst, clk) + + begin + if(rst='1') then + reg<=x"00000000"; + d_out<='0'; + going<='0'; + ld<='0'; + elsif (clk'event and clk='1') then + if (going='0')then + if(go='1')then + going<='1'; + else + counter<="00010"; + end if; + elsif (go='0' and counter="00010") then + going<='0'; -- Empty flag is asserted instantly so go for + else + if (counter="00000") then + reg<=d_in; + else + reg(31 downto 1)<=reg(30 downto 0); + reg(0)<='0'; + end if; + if(counter="00010") then -- it takes 2 cycles to + ld<='1'; -- get data from the FIFO; + elsif(counter="00001") then + ld<='0'; -- Request is only 1 cycle long. + end if; + counter<=unsigned(counter)-1; + end if; + d_out<=reg(31) xor inj; + end if; + + end process; + +end SER; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/projects/IBLcableTester/hdl/serbiphase.vhd b/rce/fw-hsio/projects/IBLcableTester/hdl/serbiphase.vhd new file mode 100644 index 0000000000000000000000000000000000000000..de05b9c978a9dc8f303b7511542d643a4ed98d8a --- /dev/null +++ b/rce/fw-hsio/projects/IBLcableTester/hdl/serbiphase.vhd @@ -0,0 +1,86 @@ +-------------------------------------------------------------- +-- Serializer for High Speed I/O board (ATLAS Pixel teststand) +-- Martin Kocian 01/2009 +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use work.all; + +-------------------------------------------------------------- + +entity serbiphase is + +port( clk: in std_logic; + ld: out std_logic; + go: in std_logic; + isgoing: out std_logic; -- debugging + inj : in std_logic; + rst: in std_logic; + d_in: in std_logic_vector(31 downto 0); + d_out: out std_logic +); +end serbiphase; + +-------------------------------------------------------------- + +architecture SERBIPHASE of serbiphase is + +signal reg : std_logic_vector(31 downto 0); +signal gogo: std_logic; +signal clk40: std_logic; + +signal ldout : std_logic; + +begin + + ld<=ldout ; + isgoing<=gogo; -- debugging + + process(clk) + begin + if (clk'event and clk='1') then + clk40<=not clk40; + end if; + end process; + + process(rst, clk40) + + variable counter: std_logic_vector(3 downto 0); + variable going: std_logic; + begin + if(rst='1') then + reg<=x"00000000"; + d_out<='0'; + going:='0'; + ldout<='0'; + elsif (clk40'event and clk40='1') then + gogo<=going; + if (going='0' and go='1')then + going:='1'; + counter:="0010"; + elsif (go='0' and counter="0010") then + going:='0'; -- Empty flag is asserted instantly so go for + end if; -- another 32 bits to process the last word. + if (counter="0000" and going='1') then + reg<=d_in; + counter:="1111"; + else + reg(31 downto 2)<=reg(29 downto 0); + reg(1 downto 0)<="00"; + if(counter="0010" and going='1') then -- it takes 2 cycles to + ldout<='1'; -- get data from the FIFO; + elsif(counter="0001" and going='1') then + ldout<='0'; -- Request is only 1 cycle long. + end if; + counter:=unsigned(counter)-1; + end if; + d_out<=reg(31) xor reg(30) xor inj; + end if; + + end process; + +end SERBIPHASE; + +-------------------------------------------------------------- diff --git a/rce/fw-hsio/system.mk b/rce/fw-hsio/system.mk new file mode 100644 index 0000000000000000000000000000000000000000..bf476d3eed6f14ccdf4e33affb735d70e24e634e --- /dev/null +++ b/rce/fw-hsio/system.mk @@ -0,0 +1,262 @@ + +# Top level directory +export PROJ_DIR = $(abspath $(PWD)) +export TOP_DIR = $(abspath $(PROJ_DIR)/../..) + +# Project Build Directory +export OUT_DIR = $(TOP_DIR)/build/$(PROJECT) + +# Location of synthesis options files +CONFIG_DIR = $(PROJ_DIR)/config + +# Images Directory +IMAGES_DIR = $(PROJ_DIR)/images + +# Project RTL Location +PRJ_RTL = $(PROJ_DIR)/hdl + +# UCF File (always in PRJ_RTL/PROJECT.ucf) +UCF_FILE = $(PRJ_RTL)/$(PROJECT).ucf + +# Get Project Version +PRJ_VERSION = $(shell grep MAKE_VERSION $(PROJ_DIR)/Version.vhd | cut -d ' ' -f 8 | cut -d'"' -f2) + +define ACTION_HEADER +@echo +@echo "=============================================================================" +@echo $(1) +@echo " Project = $(PROJECT)" +@echo " Out Dir = $(OUT_DIR)" +@echo " Version = $(PRJ_VERSION)" +@echo -e " Changed = $(foreach ARG,$?,$(ARG)\n )" +@echo "=============================================================================" +@echo +endef + +.PHONY : all +all: prom trce + +.PHONY : test +test: + @echo PROJECT: $(PROJECT) + @echo PROJ_DIR: $(PROJ_DIR) + @echo PRJ_VERSION $(PRJ_VERSION) + @echo TOP_DIR: $(TOP_DIR) + @echo OUT_DIR: $(OUT_DIR) + @echo CONFIG_DIR: $(CONFIG_DIR) + @echo XST_OPTIONS_FILE $(XST_OPTIONS_FILE) + @echo RAW_SOURCES_FILE $(RAW_SOURCES_FILE) + @echo OUT_SOURCES_FILE $(OUT_SOURCES_FILE) + @echo RTL_FILES: + @echo -e "$(foreach ARG,$(RTL_FILES), $(ARG)\n)" + +#### Build Location ######################################## +.PHONY : dir +dir: + +#### Check Source Files ################################### +#%.vhd : +# @test -d $*.vhd || echo "$*.vhd does not exist"; false; +# +#%.v : +# @test -d $*.v || echo "$*.v does not exist"; false; +# + +#### Coregen ############################################### +xco_to_build = $(addprefix $(TOP_DIR)/build/coregen/, $(patsubst %.xco, %, $(notdir $(1))))/$(notdir $(patsubst %.xco, $(2), $(1))) + +XCO_FILES = $(foreach dir, $(CORE_DIRS), $(wildcard $(dir)/*.xco)) +XCO_NGC_FILES = $(foreach xcof, $(XCO_FILES), $(call xco_to_build, $(xcof), %.ngc)) +XCO_CGP_FILES = $(foreach xcof, $(XCO_FILES), $(call xco_to_build, $(xcof), %.xco)) +XCO_FILES_BUILD = $(foreach xcof, $(XCO_FILES), $(call xco_to_build, $(xcof), %.xco)) + +.SECONDARY: $(XCO_NGC_FILES) $(XCO_FILES_BUILD) $(XCO_CGP_FILES) +$(XCO_FILES_BUILD): $(XCO_FILES) + @test -d $(TOP_DIR)/build/ || { \ + echo ""; \ + echo "Build directory missing!"; \ + echo "You must create a build directory at the top level."; \ + echo ""; \ + echo "This directory can either be a normal directory:"; \ + echo " mkdir $(TOP_DIR)/build"; \ + echo ""; \ + echo "Or by creating a symbolic link to a directory on another disk:"; \ + echo " ln -s /tmp/build $(TOP_DIR)/build"; \ + echo ""; false; } + test -d $(dir $@) || mkdir -p $(dir $@) + cp $(foreach dir, $(CORE_DIRS), $(wildcard $(dir)/$(notdir $@))) $@ + +%.cgp: %.xco + ( \ + echo 'SET addpads = False'; \ + echo 'SET asysymbol = False'; \ + echo 'SET busformat = BusFormatAngleBracketNotRipped'; \ + echo 'SET createndf = False'; \ + echo 'SET designentry = VHDL'; \ + echo 'SET device = xc4vfx60'; \ + echo 'SET devicefamily = virtex4'; \ + echo 'SET flowvendor = Other'; \ + echo 'SET formalverification = False'; \ + echo 'SET foundationsym = False'; \ + echo 'SET implementationfiletype = Ngc'; \ + echo 'SET package = ff1152'; \ + echo 'SET removerpms = False'; \ + echo 'SET simulationfiles = Behavioral'; \ + echo 'SET speedgrade = -11'; \ + echo 'SET verilogsim = False'; \ + echo 'SET vhdlsim = True'; \ + ) > $@ + +%.ngc: %.xco %.cgp + $(call ACTION_HEADER,"Regenerating $(notdir $<)") + cd $(dir $<) && \ + coregen \ + -b $(notdir $<) \ + -p $(patsubst %.xco, %.cgp, $(notdir $<)) + +ip_cores: $(XCO_NGC_FILES) + +#### Synthesis ############################################# +XST_OPTIONS_FILE = $(CONFIG_DIR)/xst_options.txt +RAW_SOURCES_FILE = $(CONFIG_DIR)/sources.txt +OUT_SOURCES_FILE = $(OUT_DIR)/sources.txt + +RTL_FILES = $(abspath $(subst _PROJ_DIR_,$(PROJ_DIR),$(shell grep -o _PROJ_DIR_\.\*.[vhd,v] $(RAW_SOURCES_FILE)))) + +$(OUT_DIR)/$(PROJECT).ngc: $(RTL_FILES) $(XST_OPTIONS_FILE) $(RAW_SOURCES_FILE) $(XCO_NGC_FILES) + $(call ACTION_HEADER,"Synthesize") + @test -d $(TOP_DIR)/build/ || { \ + echo ""; \ + echo "Build directory missing!"; \ + echo "You must create a build directory at the top level."; \ + echo ""; \ + echo "This directory can either be a normal directory:"; \ + echo " mkdir $(TOP_DIR)/build"; \ + echo ""; \ + echo "Or by creating a symbolic link to a directory on another disk:"; \ + echo " ln -s /tmp/build $(TOP_DIR)/build"; \ + echo ""; false; } + @test -d $(OUT_DIR) || mkdir $(OUT_DIR) + @test -d $(OUT_DIR)/tmp || mkdir $(OUT_DIR)/tmp + @test -d $(OUT_DIR)/xst/ || mkdir $(OUT_DIR)/xst/ + @test -d $(OUT_DIR)/xst/tmp || mkdir $(OUT_DIR)/xst/tmp + @rm -f $(OUT_SOURCES_FILE) + @sed 's|_PROJ_DIR_|$(PROJ_DIR)|' $(RAW_SOURCES_FILE) > $(OUT_SOURCES_FILE) + @cd $(OUT_DIR); xst -ifn $(XST_OPTIONS_FILE) -ofn $*.srp + + +#### Translate ############################################# +TRANSLATE_OPTIONS_FILE = $(CONFIG_DIR)/ngdbuild_options.txt +####TRANSLATE_INPUT = .ngc #Override with .ngo to use ChipScope core inserter output +TRANSLATE_INPUT = .ngc #Override with .ngo to use ChipScope core inserter output +ifneq ($(BOOT_ELF),) + dep_bmm := $(PROJ_DIR)/boot/$(PROJECT).bmm + opt_bmm := -bm $(PROJ_DIR)/boot/$(PROJECT).bmm +endif +%.ngd: %$(TRANSLATE_INPUT) $(UCF_FILE) $(TRANSLATE_OPTIONS_FILE) $(dep_bmm) $(XCO_NGC_FILES) + $(call ACTION_HEADER,"Translate") + @cd $(OUT_DIR); ngdbuild \ + -sd $(OUT_DIR) \ + -f $(TRANSLATE_OPTIONS_FILE) \ + $(opt_bmm) \ + -dd $(OUT_DIR)/bld \ + -uc $(UCF_FILE) \ + $(foreach ARG,$(CORE_DIRS),-sd $(abspath $(PROJ_DIR)/$(ARG))) \ + $(foreach ARG,$(XCO_FILES_BUILD),-sd $(abspath $(dir $(ARG)))) \ + $*$(TRANSLATE_INPUT) \ + $*.ngd + + + +#### Map ################################################### +MAP_OPTIONS_FILE = $(CONFIG_DIR)/map_options.txt +%_map.ncd %.pcf: %.ngd $(MAP_OPTIONS_FILE) + $(call ACTION_HEADER,"Map") + @cd $(OUT_DIR); map \ + -w \ + -f $(MAP_OPTIONS_FILE) \ + -o $*_map.ncd \ + $*.ngd $*.pcf + +#### PAR ################################################### +PAR_OPTIONS_FILE = $(CONFIG_DIR)/par_options.txt +%.ncd: %_map.ncd %.pcf $(PAR_OPTIONS_FILE) + $(call ACTION_HEADER,"Place and Route") + @cd $(OUT_DIR); par \ + -w \ + -f $(PAR_OPTIONS_FILE) \ + $*_map.ncd \ + $*.ncd $*.pcf + +#### Trace ################################################# +TRCE_OPTIONS_FILE = $(CONFIG_DIR)/trce_options.txt +%.twr: %.ncd %.pcf $(TRCE_OPTIONS_FILE) + $(call ACTION_HEADER,"Trace") + @cd $(OUT_DIR); trce \ + -f $(TRCE_OPTIONS_FILE) \ + -o $*.twr \ + $*.ncd $*.pcf + +#### Bit ################################################### +BIT_OPTIONS_FILE = $(CONFIG_DIR)/bitgen_options.txt +ifneq ($(BOOT_ELF),) + dep_elf := $(PROJ_DIR)/boot/$(BOOT_ELF) + opt_elf := -bd $(PROJ_DIR)/boot/$(BOOT_ELF) +endif +%.bit: %.ncd $(BIT_OPTIONS_FILE) $(PROJ_DIR)/Makefile $(dep_elf) + $(call ACTION_HEADER,"Bitgen") + @cd $(OUT_DIR); bitgen \ + $(opt_elf) \ + -f $(BIT_OPTIONS_FILE) $(opt_elf) \ + $*.ncd + +$(IMAGES_DIR)/$(PROJECT)_$(PRJ_VERSION).bit : $(OUT_DIR)/$(PROJECT).bit + @cp $< $@ + @echo "" + @echo "Bit file copied to $@" + @echo "Don't forget to 'svn commit' when the image is stable!" + + +#### PROM ################################################## +PROM_OPTIONS_FILE = $(CONFIG_DIR)/promgen_options.txt +%.mcs: %.bit $(PROM_OPTIONS_FILE) + $(call ACTION_HEADER,"PROM Generate") + @cd $(OUT_DIR); promgen \ + -f $(PROM_OPTIONS_FILE) \ + -u 0 $*.bit + +$(IMAGES_DIR)/$(PROJECT)_$(PRJ_VERSION).mcs : $(OUT_DIR)/$(PROJECT).mcs + @cp $< $@ + @echo "" + @echo "Prom file copied to $@" + @echo "Don't forget to 'svn commit' when the image is stable!" + +#### Makefile Targets ###################################### +.PHONY : syn +syn : $(OUT_DIR)/$(PROJECT).ngc + + +.PHONY : translate +translate : $(OUT_DIR)/$(PROJECT).ngd + +.PHONY : map +map : $(OUT_DIR)/$(PROJECT)_map.ncd + +.PHONY : par +par : $(OUT_DIR)/$(PROJECT).ncd + +.PHONY : trce +trce : $(OUT_DIR)/$(PROJECT).twr + +.PHONY : bit +bit : $(IMAGES_DIR)/$(PROJECT)_$(PRJ_VERSION).bit + +.PHONY : prom +prom : bit $(IMAGES_DIR)/$(PROJECT)_$(PRJ_VERSION).mcs + +#### Clean ################################################# +.PHONY : clean +clean: + rm -rf $(OUT_DIR) + + diff --git a/rce/make/hw/Makefile.package.template b/rce/make/hw/Makefile.package.template new file mode 100644 index 0000000000000000000000000000000000000000..a05ce51bbe68f6e5df486ff8658be084256eaab7 --- /dev/null +++ b/rce/make/hw/Makefile.package.template @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/hw/package.mk +endif diff --git a/rce/make/hw/constituents.mk.template b/rce/make/hw/constituents.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..d7cba60244e29e00d5f86a7d02575abbf1e93b60 --- /dev/null +++ b/rce/make/hw/constituents.mk.template @@ -0,0 +1,29 @@ +# Site location with binary cores +# bcores := /afs/slac/g/npa/package/xilinx/bcores/rs_v6 + +# File which specifies synplify options +# synoptions := hdl/syntemplate_options + +# Specify design name, constraints, sdc, bmm and elf files +# designs := lcls +# ucf_lcls := hdl/lcls.ucf +# sdc_lcls := hdl/lcls.sdc +# bmm_lcls := hdl/lcls.bmm +# elf_lcls := $(bcores)/cem.elf + +# Specify list of source files +# topsynpl_lcls := hdl/lcls.src + + +# Simulation code source directory +# scores := $(RELEASE_DIR)/rcehw/lcls + +# Simulation settings +# simoptions := sim/synopsys.setup + +# Simulation designs +# simulations := temac_sim + +# Simulation source files (top level and wrappers) +# topwrapp_temac_sim := sim/temac_sim.src +# wrappers_temac_sim := sim/temac_export.src sim/temac_import.src diff --git a/rce/make/hw/flags.mk b/rce/make/hw/flags.mk new file mode 100644 index 0000000000000000000000000000000000000000..14fa790da7f9594191516cdf1c4995ac5b494777 --- /dev/null +++ b/rce/make/hw/flags.mk @@ -0,0 +1,44 @@ +# Architecture flags +# ------------------ +arch_tgts := xc4vfx12 xc4vfx20 xc4vfx60 +arch_opts := + +define arch_opt_template +arch_tgts += $$(addsuffix -$(1),$$(arch_tgts)) +endef +$(foreach opt,$(arch_opts),$(eval $(call arch_opt_template,$(opt)))) + +ifneq ($(findstring xc4vfx12,$(tgt_arch)),) +PLATFORM := xc4vfx12-ff668-10 +endif + +ifneq ($(findstring xc4vfx20,$(tgt_arch)),) +PLATFORM := xc4vfx20-ff672-10 +endif + +ifneq ($(findstring xc4vfx60,$(tgt_arch)),) +PLATFORM := xc4vfx60-ff1152-11 +endif + +BITGENOPTS := -g DebugBitstream:No -g Binary:no -g CRC:Enable \ +-g ConfigRate:26 -g CclkPin:PullUp -g M0Pin:PullUp -g M1Pin:PullUp \ +-g M2Pin:PullUp -g ProgPin:PullUp -g DonePin:PullUp -g InitPin:Pullup \ +-g CsPin:Pullup -g DinPin:Pullup -g BusyPin:Pullup -g RdWrPin:Pullup \ +-g TckPin:PullUp -g TdiPin:PullUp -g TdoPin:PullUp -g TmsPin:PullUp \ +-g UnusedPin:PullDown -g UserID:0xDEADBEEF -g DCIUpdateMode:AsRequired \ +-g StartUpClk:CClk -g DONE_cycle:4 -g GTS_cycle:5 -g GWE_cycle:6 \ +-g LCK_cycle:NoWait -g Match_cycle:Auto -g Security:None -g Persist:No \ +-g DonePipe:No -g DriveDone:No -g Encrypt:No + +TIME := /usr/bin/time -f "(time %E: usr %U sys %S CPU %P i/o %I/%O)" +ACEGEN := $(TIME) xmd -tcl genace.tcl -jprog +BITGEN := $(TIME) bitgen -intstyle silent -d -w $(BITGENOPTS) +TWRGEN := $(TIME) trce -intstyle silent -v 50 -l 500 -u 100 +PARGEN := $(TIME) par -intstyle silent -w -ol high -xe n -t 4 +MAPGEN := $(TIME) map -intstyle silent -cm speed -ol high -p $(PLATFORM) -pr b -c 100 +NGDGEN := $(TIME) ngdbuild -intstyle silent -dd ngo -p $(PLATFORM) +XSTGEN := $(TIME) xst -intstyle silent +OPTGEN := $(RELEASE_DIR)/make/hw/optgen.py +PRJGEN := $(RELEASE_DIR)/make/hw/prjgen.py +TCLGEN := $(RELEASE_DIR)/make/hw/tclgen.py +SYNPLF := $(TIME) synplify_premier_dp -batch diff --git a/rce/make/hw/flags.mk.template b/rce/make/hw/flags.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..5ac3c6501e488b76a56880f6dcb84c89202ee65a --- /dev/null +++ b/rce/make/hw/flags.mk.template @@ -0,0 +1 @@ +include $(RELEASE_DIR)/make/hw/flags.mk diff --git a/rce/make/hw/optgen.py b/rce/make/hw/optgen.py new file mode 100755 index 0000000000000000000000000000000000000000..55ab2257a19acb43c82e3aca5d935964feb808fd --- /dev/null +++ b/rce/make/hw/optgen.py @@ -0,0 +1,23 @@ +#!/usr/bin/python + +import sys + +if __name__ == '__main__': + template = sys.argv[1] + projname = sys.argv[2] + useiobuf = sys.argv[3] + platform = sys.argv[4] + options = sys.argv[5] + + ftemplate = open(template, 'r') + foptions = open(options, 'w') + + lines = ftemplate.readlines() + for line in lines: + line = line.replace('PROJNAME', projname) + line = line.replace('USEIOBUF', useiobuf) + line = line.replace('PLATFORM', platform) + foptions.write(line) + + ftemplate.close() + foptions.close() diff --git a/rce/make/hw/package.mk b/rce/make/hw/package.mk new file mode 100644 index 0000000000000000000000000000000000000000..ea4347515b293aa511cb3216cc7702f7bd448b84 --- /dev/null +++ b/rce/make/hw/package.mk @@ -0,0 +1,296 @@ +# Package level makefile +# ---------------------- +Makefile:; + +# Symbols +# ------- +SHELL := /bin/sh +RM := rm -f +MV := mv -f + +pwd := $(shell pwd) +cwd := $(call reverse,$(subst /, ,$(pwd))) +pkg_name := $(word 1,$(cwd)) +prj_name := $(word 2,$(cwd)) + +# Procedures +# ---------- +pkgdir := $(RELEASE_DIR)/build/$(prj_name)/$(pkg_name)/$(tgt_arch) +blddir := $(pkgdir)/xil +xstdir := $(pkgdir)/xst +syndir := $(pkgdir)/syn +simdir := $(pkgdir)/sim +dirs := $(pkgdir) $(blddir) $(xstdir) $(syndir) $(simdir) + +ifneq ($(bcores),) +sdpaths := $(addprefix -sd , $(bcores)) +endif + +ifneq ($(guidefile),) + GUIDEFLAGS := -gf $(guidefile) +endif + +getstms = $(strip $(basename $(notdir $(1)))) +edfs = $(addsuffix .edf, $(addprefix $(1), $(call getstms,$(2)))) +ngcs = $(addsuffix .ngc, $(addprefix $(1), $(call getstms,$(2)))) +opts = $(addsuffix .opt, $(addprefix $(1), $(call getstms,$(2)))) +prjs = $(addsuffix .prj, $(addprefix $(1), $(call getstms,$(2)))) +done = $(addsuffix .done,$(addprefix $(1), $(call getstms,$(2)))) +getsrcfiles = $(shell srcs=`cut -f 3 -d ' ' $(1)`; echo $$srcs;) + +define wrapper_template + stem_$(1) := $$(call getstms,$(1)) + srcfiles_$$(stem_$(1)) := $$(addprefix $$(pwd)/,$$(call getsrcfiles,$(1))) + useiobuf_$$(stem_$(1)) := NO + src_$$(stem_$(1)) := $(1) + lso_$$(stem_$(1)) := $$(wildcard $$(patsubst %.src,%.lso,$(1))) + +$$(xstdir)/$$(stem_$(1)).ngc: $$(xstdir)/$$(stem_$(1)).opt $$(xstdir)/$$(stem_$(1)).prj $$(srcfiles_$$(stem_$(1))) + +$$(xstdir)/$$(stem_$(1)).prj: $$(src_$$(stem_$(1))) $$(lso_$$(stem_$(1))) +$$(xstdir)/$$(stem_$(1)).opt: $$(xstoptions) +endef + + +define synplify_template +# stem_$(1) := $$(call getstms,$(1)) +# srcfiles_$$(stem_$(1)) := $$(addprefix $$(pwd)/,$$(call getsrcfiles,$(1))) +# src_$$(stem_$(1)) := $(1) + src_$(1) := $$(pwd)/$$(syn_$(1)) + sdc_$(1) := $$(pwd)/$$(sdc_$(1)) + ucf_$(1) := $$(pwd)/$$(ucf_$(1)) + disiobuf_$(1) := 1 + +$$(syndir)/$(1).edf: $$(syndir)/$(1).prj $$(sdc_$(1)) $$(src_$(1)) $$(ucf_$(1)) + +$$(syndir)/$(1).prj: $$(synoptions) $$(src_$(1)) +endef + +define design_template + ace_$(1) := $$(pkgdir)/$(1)_ace.ace + bit_$(1) := $$(pkgdir)/$(1).bit + twr_$(1) := $$(pkgdir)/$(1).twr + ncd_$(1) := $$(pkgdir)/$(1).ncd + map_$(1) := $$(pkgdir)/$(1)_map.ncd + ngd_$(1) := $$(pkgdir)/$(1).ngd + ngcs_$(1) := $$(call ngcs,$$(xstdir)/,$$(wrappers_$(1)) $$(topwrapp_$(1))) + opts_$(1) := $$(call opts,$$(xstdir)/,$$(wrappers_$(1)) $$(topwrapp_$(1))) + prjs_$(1) := $$(call prjs,$$(xstdir)/,$$(wrappers_$(1)) $$(topwrapp_$(1))) + edfs_$(1) := $$(call edfs,$$(syndir)/,$$(synplifs_$(1)) $$(syn_$(1))) + tcls_$(1) := $$(call prjs,$$(syndir)/,$$(synplifs_$(1)) $$(syn_$(1))) + acefiles += $$(ace_$(1)) + bitfiles += $$(bit_$(1)) + twrfiles += $$(twr_$(1)) + ncdfiles += $$(ncd_$(1)) + mapfiles += $$(map_$(1)) + ngdfiles += $$(ngd_$(1)) + edffiles += $$(edfs_$(1)) $$(ngcs_$(1)) + prjfiles += $$(tcls_$(1)) $$(prjs_$(1)) $$(opts_$(1)) +ifneq ($$(bmm_$(1)),) + ubmm_$(1) := $$(blddir)/$(1).bmm + obmm_$(1) := -bm $$(notdir $$(bmm_$(1))) +$$(ubmm_$(1)): $$(bmm_$(1)) +endif +ifneq ($$(elf_$(1)),) + oelf_$(1) := -bd $$(elf_$(1)) +endif +ifneq ($$(syn_$(1)),) + edn_$(1) := $$(word $$(words $$(edfs_$(1))),$$(edfs_$(1))) +else + edn_$(1) := $$(word $$(words $$(ngcs_$(1))),$$(ngcs_$(1))) +endif + useiobuf_$(1) := YES + disiobuf_$(1) := 0 + +$$(ace_$(1)): $$(bit_$(1)) + +$$(bit_$(1)): $$(ncd_$(1)) $$(elf_$(1)) + +$$(twr_$(1)): $$(ncd_$(1)) + +$$(ncd_$(1)): $$(map_$(1)) + +$$(map_$(1)): $$(ngd_$(1)) + +$$(ngd_$(1)): $$(edfs_$(1)) $$(ngcs_$(1)) $$(ubmm_$(1)) +endef + +$(foreach dsg,$(designs),$(foreach wrapper,$(wrappers_$(dsg)) $(topwrapp_$(dsg)),$(eval $(call wrapper_template,$(wrapper))))) +#$(foreach dsg,$(designs),$(foreach syn,$(synplifs_$(dsg)) $(topsynpl_$(dsg)),$(eval $(call synplify_template,$(syn))))) +#cpo and perazzo eliminated loop over synplify stuff to simplify the makefile system. +$(foreach dsg,$(designs),$(eval $(call synplify_template,$(dsg)))) + +$(foreach dsg,$(designs),$(eval $(call design_template,$(dsg)))) + +define simwrapper_template + stem_$(1) := $$(call getstms,$(1)) + srcfiles_$$(stem_$(1)) := $$(addprefix $$(pwd)/,$$(call getsrcfiles,$(1))) + src_$$(stem_$(1)) := $(1) + lso_$$(stem_$(1)) := $$(wildcard $$(patsubst %.src,%.lso,$(1))) + +$$(simdir)/$$(stem_$(1)).done: $$(simdir)/$$(stem_$(1)).prj $$(srcfiles_$$(stem_$(1))) + +$$(simdir)/$$(stem_$(1)).prj: $$(src_$$(stem_$(1))) $$(lso_$$(stem_$(1))) +endef + +define simtoplevel_template + stem_$(1) := $$(call getstms,$(1)) + srcfiles_$$(stem_$(1)) := $$(addprefix $$(pwd)/,$$(call getsrcfiles,$(1))) + src_$$(stem_$(1)) := $(1) + lso_$$(stem_$(1)) := $$(wildcard $$(patsubst %.src,%.lso,$(1))) + done_$$(stem_$(1)) := $$(call done,$$(simdir)/,$$(wrappers_$$(stem_$(1)))) + +$$(simdir)/$$(stem_$(1)).done: $$(simdir)/$$(stem_$(1)).prj $$(srcfiles_$$(stem_$(1))) $$(done_$$(stem_$(1))) + +$$(simdir)/$$(stem_$(1)).prj: $$(src_$$(stem_$(1))) $$(lso_$$(stem_$(1))) +endef + +define simulation_template + sim_$(1) := $$(pkgdir)/$(1).sim + done_$(1) := $$(call done,$$(simdir)/,$$(wrappers_$(1)) $$(topwrapp_$(1))) + simfiles += $$(sim_$(1)) + +$$(sim_$(1)): $$(simdir)/.synopsys_vss.setup $$(done_$(1)) +endef + +$(foreach sim,$(simulations),$(foreach wrapper,$(wrappers_$(sim)),$(eval $(call simwrapper_template,$(wrapper))))) +$(foreach sim,$(simulations),$(eval $(call simtoplevel_template,$(topwrapp_$(sim))))) +$(foreach sim,$(simulations),$(eval $(call simulation_template,$(sim)))) + +# Rules +# ----- +.SUFFIXES: # Kills all implicit rules + +# Kill rules to remake source files, there really isn't anyway to do +# this and this just adds time to make's execution and verbage to +# debug output. +%.vhd :; +%.v :; +%.src :; +%.lso :; +%.ucf :; + +rules := all ace bit twr ncd map ngd edf prj sim dir clean cleansim print + +.PHONY: $(rules) + +all: ace sim; +ace: $(acefiles); +bit: $(bitfiles); +twr: $(twrfiles); +ncd: $(ncdfiles); +map: $(mapfiles); +ngd: $(ngdfiles); +edf: $(edffiles); +prj: $(prjfiles); +sim: $(simfiles); +dir: $(dirs); + +print: + @echo "pkgdir = $(pkgdir)" + @echo "ace = $(acefiles)" + @echo "bit = $(bitfiles)" + @echo "ncd = $(ncdfiles)" + @echo "map = $(mapfiles)" + @echo "ngd = $(ngdfiles)" + @echo "edf = $(edffiles)" + @echo "prj = $(prjfiles)" + @echo "sim = $(simfiles)" + @echo "ucf = $(ucffile)" + + +clean: + @echo "[CL] Remove $(pkgdir)" + $(quiet)rm -rf $(pkgdir) + +cleansim: + @echo "[CL] Remove $(simdir)" + $(quiet)rm -rf $(simdir) + + +# Directory structure +$(dirs): + $(quiet)mkdir -p $@ + + +# Xilinx +$(blddir)/%.bmm: +# Unfortunately the bmm file is needed under blddir by bitgen (through +# data2mem) since its location cannot be specified as bitgen argument + @echo "[BM] Copy BMM file to build directory for design $*" + $(quiet)cp $(bmm_$*) $(blddir) + +$(pkgdir)/%.ngd: + @echo "[GD] Generate NGD file for design $*" + $(quiet)cd $(blddir) && \ + $(NGDGEN) $(sdpaths) $(obmm_$*) -uc $(syndir)/synplicity.ucf $(edn_$*) $*.ngd && \ + mv $*.ngd ../ + +$(pkgdir)/%_map.ncd: + @echo "[MP] Generate MAP file for design $*" + $(quiet)cd $(blddir) && \ + $(MAPGEN) $(GUIDEFLAGS) -o $*_map.ncd ../$*.ngd $*.pcf && mv $*_map.ncd ../ + +$(pkgdir)/%.ncd: + @echo "[PR] Place and route design $*" + $(quiet)cd $(blddir) \ + && $(PARGEN) $(GUIDEFLAGS) ../$*_map.ncd $*.ncd $*.pcf && mv $*.ncd ../ + +$(pkgdir)/%.twr: + @echo "[BT] Generate timing report for design $*" + $(quiet)cd $(blddir) && \ + $(TWRGEN) -xml $* ../$*.ncd -o $*.twr $*.pcf && mv $*.twr ../ + +$(pkgdir)/%.bit: + @echo "[BT] Generate BIT file for design $*" + $(quiet)cd $(blddir) && \ + $(BITGEN) $(oelf_$*) ../$*.ncd $*.bit && mv $*.bit ../ + +$(pkgdir)/%_ace.ace: + @echo "[AC] Generate ACE file for design $*" + $(quiet)cd $(blddir) && \ + $(ACEGEN) -hw ../$*.bit -ace $*_ace.ace && mv $*_ace.ace ../ + + +# Xilinx XST +$(xstdir)/%.prj: + @echo "[XP] Generate list of source files for $*" + $(quiet)$(PRJGEN) $(scores) $(pwd) $@ $(src_$*) $(lso_$*) + +$(xstdir)/%.opt: + @echo "[XO] Generate synthesis options file for $*" + $(quiet)$(OPTGEN) $(xstoptions) $* $(useiobuf_$*) $(PLATFORM) $@ + +$(xstdir)/%.ngc: + @echo "[XD] Compile NGC file for $*" + $(quiet)cd $(xstdir) && rm -rf $* && $(XSTGEN) -ifn $*.opt + + +# Synplify +$(syndir)/%.prj: + @echo "[SL] Generate list of soure files for $*" + $(quiet)$(TCLGEN) $(synoptions) $* $(disiobuf_$*) $(pwd) $(sdc_$*) $(src_$*) $(ucf_$*) $@ + +$(syndir)/%.edf: + @echo "[SD] Compile EDF file for $*" + $(quiet)cd $(syndir) && rm -rf $* && $(SYNPLF) $*.prj + + +# Synopsys +$(simdir)/%.prj: + @echo "[SP] Generate list of simulation soure files for $*" + $(quiet)$(PRJGEN) $(scores) $(pwd) $@ $(src_$*) $(lso_$*) + +$(simdir)/%.done: + @echo "[SC] Compile SIM file for $*" + $(quiet)cd $(simdir) && \ + vhdlan -nc $(call getsrcfiles,$(simdir)/$*.prj) && touch $*.done + +$(simdir)/.synopsys_vss.setup: $(simoptions) + @echo "[ST] Copy simulation options file $<" + $(quiet)cp $< $@ + +$(pkgdir)/%.sim: + @echo "[SE] Generate simulation executable $*" + $(quiet)cd $(simdir) && rm -rf $@.db.dir \ + && scs -nc -debug -time "ps" -time_res "1ps" $* -exe $@ diff --git a/rce/make/hw/prjgen.py b/rce/make/hw/prjgen.py new file mode 100755 index 0000000000000000000000000000000000000000..542fea0a4c1a94e36f4541f91d236e2c65db6893 --- /dev/null +++ b/rce/make/hw/prjgen.py @@ -0,0 +1,64 @@ +#!/usr/bin/python + +import sys +import os +import glob + +if __name__ == '__main__': + xipcores = sys.argv[1] + usrcores = sys.argv[2] + prjfile = sys.argv[3] + srcfile = sys.argv[4] + + fprj = open(prjfile, 'w') + + if len(sys.argv) > 5: + lsofile = sys.argv[5] + flso = open(lsofile, 'r') + for library in flso.readlines(): + library = library.strip() + paos = glob.glob('%s/%s/data/*.pao' %(xipcores, library)) + for pao in paos: + fpao = open(pao, 'r') + for depline in fpao.readlines(): + tokens = depline.split() + if len(tokens) > 2 and tokens[0] == 'lib': + dep = tokens[1] + src = tokens[2] + if src == 'all': + vhdls = glob.glob('%s/%s/hdl/vhdl/*.vhd' %(xipcores, dep)) + verilogs = glob.glob('%s/%s/hdl/verilog/*.v' %(xipcores, dep)) + for vhdl in vhdls: + fprj.write('vhdl %s %s\n' %(dep, vhdl)) + for verilog in verilogs: + fprj.write('verilog %s %s\n' %(dep, verilog)) + else: + vhdl = '%s/%s/hdl/vhdl/%s.vhd' %(xipcores, dep, src) + verilog = '%s/%s/hdl/verilog/%s.v' %(xipcores, dep, src) + if os.access(vhdl, os.R_OK): + fprj.write('vhdl %s %s\n' %(dep, vhdl)) + elif os.access(verilog, os.R_OK): + fprj.write('verilog %s %s\n' %(dep, verilog)) + else: + fprj.close() + os.remove(prjfile) + raise 'cannot find core file %s or %s' %(vhdl, verilog) + flso.close() + + fsrc = open(srcfile, 'r') + for line in fsrc.readlines(): + tokens = line.split() + if len(tokens) == 3 and (tokens[0] == 'vhdl' or tokens[0] == 'verilog'): + lang = tokens[0] + dep = tokens[1] + src = tokens[2] + src = os.path.join(usrcores, src) + if os.access(src, os.R_OK): + fprj.write('%s %s %s\n' %(lang, dep, src)) + else: + fprj.close() + os.remove(prjfile) + raise 'cannot find user core file %s' %(src) + + fsrc.close() + fprj.close() diff --git a/rce/make/hw/tclgen.py b/rce/make/hw/tclgen.py new file mode 100755 index 0000000000000000000000000000000000000000..9ba8d6111cbb3b9d0896625d1c23b32a40ac246d --- /dev/null +++ b/rce/make/hw/tclgen.py @@ -0,0 +1,48 @@ +#!/usr/bin/python + +import sys +import os + +if __name__ == '__main__': + template = sys.argv[1] + projname = sys.argv[2] + disiobuf = sys.argv[3] + srcdir = sys.argv[4] + sdcfile = sys.argv[5] + srcfile = sys.argv[6] + ucffile = sys.argv[7] + tclfile = sys.argv[8] + + ftemplate = open(template, 'r') + fsrc = open(srcfile, 'r') + ftcl = open(tclfile, 'w') + + for line in fsrc.readlines(): + tokens = line.split() + if len(tokens) == 3 and (tokens[0] == 'vhdl' or tokens[0] == 'verilog'): + lang = tokens[0] + dep = tokens[1] + src = tokens[2] + src = os.path.join(srcdir, src) + if os.access(src, os.R_OK): + ftcl.write('add_file -%s -lib %s %s\n' %(lang, dep, src)) + else: + ftcl.close() + if os.access(tclfile, os.R_OK): + os.remove(tclfile) + raise 'cannot find user core file %s' %(src) + + ftcl.write('\nadd_file %s\n' %(ucffile)) + + sdcfile = os.path.join(srcdir, sdcfile) + ftcl.write('\nadd_file -constraint %s\n\n' %(sdcfile)) + + lines = ftemplate.readlines() + for line in lines: + line = line.replace('PROJNAME', projname) + line = line.replace('DISIOBUF', disiobuf) + ftcl.write(line) + + ftemplate.close() + fsrc.close() + ftcl.close() diff --git a/rce/make/share/Makefile.project.template b/rce/make/share/Makefile.project.template new file mode 100644 index 0000000000000000000000000000000000000000..bd8fffcb85eec9e196be993dd89e1b981169c01d --- /dev/null +++ b/rce/make/share/Makefile.project.template @@ -0,0 +1,17 @@ +# Project level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/.. +endif + +# Includes +# -------- +include $(RELEASE_DIR)/make/share/setup.mk +include flags.mk +include packages.mk +include $(RELEASE_DIR)/make/share/project.mk diff --git a/rce/make/share/packages.mk.template b/rce/make/share/packages.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..72ae08f46a673f82c226bc3c83975fac740448ad --- /dev/null +++ b/rce/make/share/packages.mk.template @@ -0,0 +1,2 @@ +# List packages for this project. Low level first. +# packages := pkg_a pkg_b diff --git a/rce/make/share/premake.mk b/rce/make/share/premake.mk new file mode 100644 index 0000000000000000000000000000000000000000..501b288530842d1adc3d30369d8985d0b29cad65 --- /dev/null +++ b/rce/make/share/premake.mk @@ -0,0 +1,41 @@ +# Prepare to run package level makefile +# ------------------------------------- +Makefile:; + +# This makefile is conditionally included at the start of each package +# specific Makefile. Its purpose is to correctly call itself after +# creating the appropriate directories, set tgt_arch and the target +# specific flags. + + +# Symbols +# ------- +# To be sure there is one, and only one, `-f Makefile' option +MAKE := $(filter-out -f Makefile, $(MAKE)) -f Makefile + +archs := $(arch_tgts) +archs.% := $(addsuffix .%,$(arch_tgts)) + +# Rule specific flags +clean-flags := no_depends=y +cleanall-flags := no_depends=y +userclean-flags := no_depends=y +print-flags := no_depends=y + + +# Rules +# ----- +.PHONY: $(archs) $(archs.%) + +define arch_template +$(1): + $$(quiet)$$(MAKE) PREMAKE_DONE=y tgt_arch=$(1) dir no_depends=y + $$(quiet)$$(MAKE) PREMAKE_DONE=y tgt_arch=$(1) all + +$(1).%: + $$(quiet)$$(MAKE) PREMAKE_DONE=y tgt_arch=$(1) dir no_depends=y + $$(quiet)$$(MAKE) PREMAKE_DONE=y tgt_arch=$(1) $$* $$($$*-flags) + +endef + +$(foreach arc,$(archs),$(eval $(call arch_template,$(arc)))) diff --git a/rce/make/share/project.mk b/rce/make/share/project.mk new file mode 100644 index 0000000000000000000000000000000000000000..d103f2d2da8fa3698fac1f6323d19ab2a66af340 --- /dev/null +++ b/rce/make/share/project.mk @@ -0,0 +1,39 @@ +# Project level makefile +# ---------------------- +Makefile:; + +# Symbols +# ------- +cwd := $(subst /, ,$(shell pwd)) +prj_name := $(word $(words $(cwd)),$(cwd)) + +archs := $(arch_tgts) +archs.% := $(addsuffix .%,$(arch_tgts)) +packages.% := $(addsuffix .%,$(packages)) + +# Rules +# ----- +.PHONY: $(archs) $(archs.%) $(packages) $(packages.%) + +define package_template +$(1).%: + $(quiet)echo "[PK] Target <$$*> package <$(1)>" + $(quiet)$$(MAKE) -C $(1) $$* +endef + +$(foreach pkg,$(packages),$(eval $(call package_template,$(pkg)))) + +define arch_template +packages_$(1) := $$(foreach pkg,$$(packages),$$(pkg).$(1)) +$(1): $$(packages_$(1)); +$(1).%: $$(addsuffix .%,$$(packages_$(1))); +endef + +$(foreach arc,$(archs),$(eval $(call arch_template,$(arc)))) + +cleanall: + @echo "[RO] Removing project $(prj_name) build directory" + $(quiet)$(RM) -r $(RELEASE_DIR)/build/$(prj_name) + +%:; + @echo "---- No target <$*> for project <$(prj_name)>" diff --git a/rce/make/share/release.mk b/rce/make/share/release.mk new file mode 100644 index 0000000000000000000000000000000000000000..40640337775e7cd8f6509d5fe3d9d606fce4bd5a --- /dev/null +++ b/rce/make/share/release.mk @@ -0,0 +1,82 @@ +# Top level makefile +# ------------------ +Makefile:; + +# Symbols +# ------- +SHELL := /bin/bash + +# Minimal directory tree +tree_dirs = build + +# Rules +# ----- +.PHONY: dir cleanall $(projects) $(projects.%) + +dir: $(tree_dirs); +$(tree_dirs): + @echo "[DR] Target <dir> at top level"; + $(quiet)mkdir -p $@ + +cleanall: + @echo "[CL] Target <cleanall> at top level"; + $(quiet)$(RM) -r build + +define soft-link + if [ ! -e $(1) ]; then \ + if [ -e $(2) ]; then \ + echo '[SL] Make soft link $(1)'; \ + ln -s $(2) $(1); \ + else \ + echo '[SL] *** project $(2) not found'; \ + fi \ + fi +endef + +define delete-soft-links + for prj in $(projects); do \ + if [ -h build/$$prj ]; then \ + $(RM) build/$$prj; \ + fi; \ + done +endef + +define project_template +ifeq ($$(strip $$($(1)_use)),release) +$(1).%: dir + $(quiet)echo "[PR] Target <$$*> project <$(1)>" + $$(MAKE) -C $(1) $$* +else +ifeq ($$(strip $$($(1)_use)),base) +ifneq ($(base_use),) +$(1).%: dir + @$$(call soft-link,build/$(1),$(base_use)/build/$(1)) + @$$(call soft-link,$(1),$(base_use)/$(1)) +else +$$(error 'Project $(1) specifies base but no base_use statement found.') +endif +else +ifneq ($$(findstring /,$$($(1)_use),),) +$(1).%: dir + @$$(call soft-link,build/$(1),$$($(1)_use)) +else +$$(error 'Project $(1) lacks a use statement.') +endif +endif +endif +endef + +# revisit release_base +# $(1).%: dir +# @$$(call soft-link,build/$(1),$$(release_base)/build/$(1)) +# @$$(call soft-link,$(1),$$(release_base)/$(1)) + +$(foreach prj,$(projects),$(eval $(call project_template,$(prj)))) + +define all-projects + for prj in $(projects); do \ + $(MAKE) $$prj.$*; \ + done +endef + +%:; @$(all-projects) diff --git a/rce/make/share/setup.mk b/rce/make/share/setup.mk new file mode 100644 index 0000000000000000000000000000000000000000..bb789b620708af9b4a7e8e28eb4754f5772b3837 --- /dev/null +++ b/rce/make/share/setup.mk @@ -0,0 +1,49 @@ +# Checks +# ------ +SHELL := /bin/bash +REQUIRED_MAKE_VERSION := 3.80 + +required_make_major_version := $(word 1,$(subst ., ,$(REQUIRED_MAKE_VERSION))) +required_make_minor_version := $(word 2,$(subst ., ,$(REQUIRED_MAKE_VERSION))) +make_major_version := $(word 1,$(subst ., ,$(MAKE_VERSION))) +make_minor_version := $(word 2,$(subst ., ,$(MAKE_VERSION))) + +test_make_version = $(shell \ + if [[ $(make_major_version) < $(required_make_major_version) || \ + $(make_major_version) == $(required_make_major_version) && \ + $(make_minor_version) < $(required_make_minor_version) ]] ; then \ + echo 'error'; \ + else \ + echo 'ok'; \ + fi) + +ifneq ($(call test_make_version), ok) +$(error 'Makefile version is $(MAKE_VERSION) but needs to be $(REQUIRED_MAKE_VERSION) or higher') +endif + + +# Symbols +# ------- +# To be sure there is one, and only one, `-f Makefile' option +MAKE := $(filter-out -f Makefile, $(MAKE)) -f Makefile + +# Define reverse function +reverse = $(shell \ + set reversed=""; \ + for entry in $(1); do \ + reversed="$$entry $$reversed"; \ + done; \ + echo $$reversed) + +# Set verbosity +ifeq ($(verbose),y) + quiet := + MAKEFLAGS := +else + quiet := @ + MAKEFLAGS := -s +endif + +# Target variable +# --------------- +tgt_arch := $(MAKECMDGOALS) diff --git a/rce/make/sw/Makefile.package.template b/rce/make/sw/Makefile.package.template new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/make/sw/Makefile.package.template @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/make/sw/constituents.mk.template b/rce/make/sw/constituents.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..a98aa32cadade5538f07dc7064a4bca73c66be40 --- /dev/null +++ b/rce/make/sw/constituents.mk.template @@ -0,0 +1,39 @@ +# List targets (if any) for this package +# tgtnames := exe_a exe_b + +# List source files for each target +# tgtsrcs_exe_a := src_1.cc src_2.cc +# tgtsrcs_exe_b := src_3.cc + +# List system libraries (if any) needed by exe_a as <dir>/<lib>. +# Note that <lib> is the name of the library, not of the file: i.e. +# <lib> for 'libc.so' is 'c'. Low level first. +# tgtslib_exe_a := /usr/lib/rt + +# List project libraries (if any) needed by exe_a as <project>/<lib>. +# Note that <lib> is the name of the library, not of the file: i.e. +# <lib> for 'libc.so' is 'c'. Low level first. +# tgtlibs_exe_a := prj_x/lib_y + +# List special include directories (if any) needed by exe_a as +# <project>/<incdir>. Note that the top level release directory is +# already in the search path. +# tgtincs_exe_a := prj_x/include prj_x/include/Linux + +# List system include directories (if any) needed by exe_a as <incdir>. +# tgtsinc_exe_a := /usr/include + +# List libraries (if any) for this package +# libnames := lib_a lib_b + +# List source files for each library +# libsrcs_lib_a := src_4.cc src_5.cc +# libsrcs_lib_b := src_6.cc + +# List special include directories (if any) needed by lib_a as +# <project>/<incdir>. Note that the top level release directory is +# already in the search path. +# libincs_lib_a := prj_x/include/Linux + +# List system include directories (if any) needed by lib_a as <incdir>. +# libsinc_lib_a := /usr/include diff --git a/rce/make/sw/flags.mk b/rce/make/sw/flags.mk new file mode 100644 index 0000000000000000000000000000000000000000..dca9fc386e954c2f38442478003a3498f70a7333 --- /dev/null +++ b/rce/make/sw/flags.mk @@ -0,0 +1,236 @@ +# Architecture flags +# ------------------ +arch_tgts := ppc-rtems-rce405 i686-slc5-gcc43 ppc-rtems-rceG1 +arch_opts := opt dbg + +define arch_opt_template +arch_tgts += $$(addsuffix -$(1),$$(arch_tgts)) +endef +$(foreach opt,$(arch_opts),$(eval $(call arch_opt_template,$(opt)))) + +# Separate the components of tgt_arch using the dash as a separator. +archwords := $(subst -, ,$(strip $(tgt_arch))) +tgt_opt := $(filter $(arch_opts),$(archwords)) +archwords := $(filter-out $(arch_opts),$(archwords)) +tgt_cpu_family := $(word 1,$(archwords)) +tgt_os := $(word 2,$(archwords)) +tgt_board := $(word 3,$(archwords)) + + +ifeq ($(tgt_os),slc5) +tgt_cpu_family=i386 +tgt_gcc_version:= $(tgt_board) +tgt_board=i386 +tgt_os:=linux +endif + +# Define a compile-time macro for each architecture component. +DEFINES := -Dtgt_opt_$(tgt_opt) +DEFINES += -Dtgt_cpu_family_$(tgt_cpu_family) +DEFINES += -Dtgt_os_$(tgt_os) +DEFINES += -Dtgt_board_$(tgt_board) + + +# i386 Linux specific flags +ifeq ($(tgt_os),linux) +ifeq ($(LINUXVERS),SLC6) +DEFINES+= -D__USE_XOPEN2K8 +endif +ifeq ($(RCE_CORE_VERSION),2.2) +DEFINES+=-DRCE_V2 -Dtgt_board_i386 +endif +#generic toolchain +# pick compiler shipping with OS +AS.EXE:=as +CC.EXE:=gcc +CXX.EXE:=g++ + + +ifeq ($(tgt_gcc_version),gcc43) +CC.EXE:=gcc43 +CXX.EXE:=g++43 +endif + + + + +LD.EXE=$(CXX.EXE) +LX.EXE=$(CXX.EXE) + +AS := $(AS.EXE) +CPP := $(CC) -E +CC := $(CC.EXE) +CXX := $(CXX.EXE) +LD := $(LD.EXE) +LX := $(LX.EXE) + +ifeq ($(tgt_cpu_family),i386) +LIBEXTNS := so +DEPFLAGS := -MM -m32 $(DEFINES) +DEFINES += -fPIC -D_REENTRANT -D__pentium__ -Wall +CPPFLAGS := +CFLAGS := -m32 -g +CXXFLAGS := $(CFLAGS) +CASFLAGS := -x assembler-with-cpp -P $(CFLAGS) +LDFLAGS := -m32 -shared -g +LXFLAGS := -m32 -g +endif +ifeq ($(tgt_cpu_family),x86_64) +LIBEXTNS := so +DEPFLAGS := -MM -m64 +DEFINES += -fPIC -D_REENTRANT -D__pentium__ -Wall +CPPFLAGS := +CFLAGS := -m64 +CXXFLAGS := $(CFLAGS) +CASFLAGS := -x assembler-with-cpp -P $(CFLAGS) +LDFLAGS := -m64 -shared +LXFLAGS := -m64 +endif +else +# Sparc Solaris specific flags +ifeq ($(tgt_cpu_family)-$(tgt_os),sparc-solaris) +AS := as +CPP := gcc -E +CC := gcc +CXX := g++ +LD := g++ +LX := g++ + +LIBEXTNS := so +DEPFLAGS := -MM +DEFINES += -fPIC -D_REENTRANT -Wall +CPPFLAGS := +CFLAGS := +CXXFLAGS := $(CFLAGS) +CASFLAGS := -x assembler-with-cpp -P $(CFLAGS) +LDFLAGS := -shared +LXFLAGS := +else +# PowerPC RTEMS specific flags +ifeq ($(tgt_cpu_family)-$(tgt_os),ppc-rtems) + + +#make sure for cross compile to unset COMPILER_PATH +# this will make the x-compiler to look for includes in the TDAQ compiler path if set +AS := unset COMPILER_PATH;powerpc-rtems4.9-as +CPP := unset COMPILER_PATH;powerpc-rtems4.9-cpp +CC := unset COMPILER_PATH;powerpc-rtems4.9-gcc +CXX := unset COMPILER_PATH;powerpc-rtems4.9-g++ +LD := unset COMPILER_PATH;powerpc-rtems4.9-ld +LX := unset COMPILER_PATH;powerpc-rtems4.9-g++ +AR := unset COMPILER_PATH;powerpc-rtems4.9-ar +OBJCOPY :=unset COMPILER_PATH;powerpc-rtems4.9-objcopy + +ifeq ($(tgt_board),rceG1) +AS := unset COMPILER_PATH;powerpc-rtems4.10-as +CPP := unset COMPILER_PATH;powerpc-rtems4.10-cpp +CC := unset COMPILER_PATH;powerpc-rtems4.10-gcc +CXX := unset COMPILER_PATH;powerpc-rtems4.10-g++ +LD := unset COMPILER_PATH;powerpc-rtems4.10-ld +LX := unset COMPILER_PATH;powerpc-rtems4.10-g++ +AR := unset COMPILER_PATH;powerpc-rtems4.10-ar +OBJCOPY := unset COMPILER_PATH;powerpc-rtems4.10-objcopy +endif + +ifeq ($(tgt_board),rce405) +RTEMSDIR := $(RELEASE_DIR)/build/rtems/target/powerpc-rtems/rce405/lib +tgt_cpu=403 +endif + +ifeq ($(tgt_board),rceG1) +RTEMSDIR := $(RELEASE_DIR)/build/rtems/target/powerpc-rtems4.10/virtex4/lib +tgt_cpu=405 +endif + + + +ifeq ($(tgt_board),ml405) +RTEMSDIR := $(RELEASE_DIR)/build/rtems/target/powerpc-rtems/ml405/lib +endif +ifeq ($(RCE_CORE),"") +LDTOOLSD := $(RELEASE_DIR)/rce/ldtools +else +LDTOOLSD := $(RCE_CORE)/ldtools +endif +LIBEXTNS := a + +DEPFLAGS := -B$(RTEMSDIR) -MM -Dppc405=ppc405 $(DEFINES) +DEFINES += -Dppc405=ppc405 +MDEFINES := $(DEFINES) -DEXPORT='__attribute__((visibility("default")))' + +ifeq ($(tgt_board),rceG1) +DEFINES += -Dtgt_gen=gen1 -Drtems_majorv_macro=4 -Drtems_minorv_macro=10 -Drtems_revision_macro=2 -DRCE_V2 +MDEFINES += -Dtgt_gen=gen1 -Drtems_majorv_macro=4 -Drtems_minorv_macro=10 -Drtems_revision_macro=2 -DRCE_V2 +DEPFLAGS+= -Dtgt_gen=gen1 -Drtems_majorv_macro=4 -Drtems_minorv_macro=10 -Drtems_revision_macro=2 -DRCE_V2 +endif +CPPFLAGS := +CFLAGS := -B$(RTEMSDIR) -specs bsp_specs -qrtems -mcpu=$(tgt_cpu) -Wall +CXXFLAGS := $(CFLAGS) +CASFLAGS := -x assembler-with-cpp -P $(CFLAGS) +LDFLAGS := -r +#remove -s flag to not strip symbols +#LXFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/dynamic_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/dynamic.ld -mcpu=$(tgt_cpu) +#LXFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/dynamic_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/dynamic.ld -mcpu=$(tgt_cpu) +#old for debugger +ifeq ($(RCE_CORE_VERSION),2.2) +#LXFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/dynamic_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/bootLoader.ld -mcpu=$(tgt_cpu) +#for debug image +LXFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/dynamic_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/dynamic.ld -mcpu=$(tgt_cpu) +else +LXFLAGS := -s -B$(RTEMSDIR) -specs $(LDTOOLSD)/dynamic_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/dynamic.ld -mcpu=$(tgt_cpu) +endif + + +MANAGERS := timer sem msg event signal part region dpmem io rtmon ext mp + +MCFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/module_specs -qrtems -Wall -fvisibility=hidden -mlongcall -fno-pic -mcpu=$(tgt_cpu) +MCXXFLAGS := $(MCFLAGS) +MCASFLAGS := -x assembler-with-cpp -P $(MCFLAGS) +MLDFLAGS := -r +#remove -s flag to not strip symbols +#MLXFLAGS := -B$(RTEMSDIR) -specs $(LDTOOLSD)/module_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/module.ld -mcpu=$(tgt_cpu) -shared -nostdlib +MLXFLAGS := -s -B$(RTEMSDIR) -specs $(LDTOOLSD)/module_specs -qrtems -qnolinkcmds -Wl,-T$(LDTOOLSD)/module.ld -mcpu=$(tgt_cpu) -shared -nostdlib + +ifeq ($(tgt_board),rceG1) +LXFLAGS += -L$(LDTOOLSD) -L$(LDTOOLSD)/rceG1 +LXFLAGS += $(RELEASE)/build/platform/obj/ppc-rtems-rceG1-opt/startup/src/Init.o +LXFLAGS += $(RELEASE)/build/platform/obj/ppc-rtems-rceG1-opt/startup/src/extrarefs.o +LXFLAGS += $(RELEASE)/build/platform/obj/ppc-rtems-rceG1-opt/startup/src/rce/Init.o +LXFLAGS += $(RELEASE)/build/platform/obj/ppc-rtems-rceG1-opt/startup/bldInfo_dpm.2.2.prod.o +MXFLAGS += -L$(LDTOOLSD) -L$(LDTOOLSD)/rceG1 +endif + +else +ifeq ($(tgt_cpu_family)-$(tgt_os),ppc-linux) +AS := as +CPP := gcc -E +CC := gcc +CXX := g++ +LD := g++ +LX := g++ + +LIBEXTNS := so +DEPFLAGS := -MM +DEFINES += -D_REENTRANT -Wall +CPPFLAGS := +CFLAGS := +CXXFLAGS := $(CFLAGS) +CASFLAGS := -x assembler-with-cpp -P $(CFLAGS) +LDFLAGS := -shared +LXFLAGS := + +endif +endif +endif +endif + + +ifeq ($(tgt_opt),opt) +DEFINES += -O4 +MDEFINES += -O4 +endif + +ifeq ($(tgt_opt),dbg) +DEFINES += -g +MDEFINES += -g +endif diff --git a/rce/make/sw/flags.mk.template b/rce/make/sw/flags.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..dadf67ae3ff5d46c9d44be7828a1aa034953263b --- /dev/null +++ b/rce/make/sw/flags.mk.template @@ -0,0 +1 @@ +include $(RELEASE_DIR)/make/sw/flags.mk diff --git a/rce/make/sw/idl.mk b/rce/make/sw/idl.mk new file mode 100644 index 0000000000000000000000000000000000000000..26e0977d5e676c720675deb6e3c97df770b49fa3 --- /dev/null +++ b/rce/make/sw/idl.mk @@ -0,0 +1,24 @@ +# Call omniidl to preprocess .idl files + + +$(objdir)/%SK.o: $(objdir)/%SK.cc + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$*SK.cc) $(DEFINES) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + + +$(objdir)/%SK.cc $(objdir)/%.hh: %.idl + @echo "[ID] IDL Preprocessing $<" + $(quiet)omniidl $(incdirs_$*SK.cc) -bcxx $(IDLFLAGS) -C$(objdir)/$(dir $*) $< + +$(modobjdir)/%SK.o: $(modobjdir)/%SK.cc + @echo "[MX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$*SK.cc) $(CPPFLAGS) $(MDEFINES) $(MCXXFLAGS) -c $< -o $@ + + +$(modobjdir)/%SK.cc $(modobjdir)/%.hh: %.idl + @echo "[ID] IDL Preprocessing $<" + $(quiet)omniidl $(incdirs_$*SK.cc) -bcxx $(IDLFLAGS) -C$(modobjdir)/$(dir $*) $< + + + + diff --git a/rce/make/sw/package.mk b/rce/make/sw/package.mk new file mode 100644 index 0000000000000000000000000000000000000000..0885ce14b8a988d5901fc9eb2c6dbee81f1ab5e3 --- /dev/null +++ b/rce/make/sw/package.mk @@ -0,0 +1,396 @@ +# Package level makefile +# ---------------------- +Makefile:; + +# Symbols +# ------- +SHELL := /bin/bash +RM := rm -f +MV := mv -f +empty := +space := $(empty) $(empty) + +cwd := $(call reverse,$(subst /, ,$(shell pwd))) +pkg_name := $(word 1,$(cwd)) +prj_name := $(word 2,$(cwd)) + +# Defines which directories are being created by this makefile +libdir := $(RELEASE_DIR)/build/$(prj_name)/lib/$(tgt_arch) +bindir := $(RELEASE_DIR)/build/$(prj_name)/bin/$(tgt_arch) +objdir := $(RELEASE_DIR)/build/$(prj_name)/obj/$(tgt_arch)/$(pkg_name) +moddir := $(RELEASE_DIR)/build/$(prj_name)/mod/$(tgt_arch) +modobjdir := $(RELEASE_DIR)/build/$(prj_name)/modobj/$(tgt_arch)/$(pkg_name) +modlibdir := $(RELEASE_DIR)/build/$(prj_name)/modlib/$(tgt_arch) +depdir := $(RELEASE_DIR)/build/$(prj_name)/dep/$(tgt_arch)/$(pkg_name) +moddepdir := $(RELEASE_DIR)/build/$(prj_name)/moddep/$(tgt_arch)/$(pkg_name) +prod_dirs := $(strip $(bindir) $(libdir) $(moddir) $(modlibdir)) +temp_dirs = $(strip $(sort $(foreach o,$(depends) $(objects),$(dir $(o))))) + +# Dummy shared library search (RTEMS only) +# ---------------------------------------- + +# In order to get a dynamic symbol table into a target it's necessary +# (but not sufficient) to search at least one shared library. Why a +# dynamic symbol table rather than a regular one? A dynamic symbol +# table is part of a loadable segment (and section) so ELF-loaders +# will automatically copy the table into memory; no painful hacks are +# required to extract the table and find a safe place for it. As a +# bonus we get a hash table to speed our lookups. + +# Make each target (executable) depend on the "dummy" library of +# package rce/ldtools. We can just append to the list of libraries +# for a target because the command line arguments generated +# for the final linking of the target don't depend on the type +# of library. It's up to rce/ldtools to make sure that the dummy +# library is indeed a shared library. + +ifeq ($(tgt_os),rtems) + +define adddummylib +ifndef tgtlibs_$(tgt) +tgtlibs_$(tgt) := +endif +ifeq ($(RCE_CORE_VERSION),2.2) +tgtlibs_$(tgt) += service/dummy +else +tgtlibs_$(tgt) += rce/dummy +endif +endef + +$(foreach tgt,$(tgtnames),$(eval $(adddummylib))) +endif + + +# Procedures +# ---------- + +# Define some procedures and create (different!) rules for libraries +# and targets. Note that 'eval' needs gmake >= 3.80. +libraries := +modules := +targets := +objects := +depends := +getobjects = $(strip \ + $(patsubst %.cc,$(1)/%.o,$(filter %.cc,$(2))) \ + $(patsubst %.cpp,$(1)/%.o,$(filter %.cpp,$(2))) \ + $(patsubst %.c,$(1)/%.o, $(filter %.c,$(2))) \ + $(patsubst %.s,$(1)/%.o, $(filter %.s,$(2)))) +getprj = $(word 1,$(subst /, ,$(1))) +getlib = $(word 2,$(subst /, ,$(1))) +getproject = $(RELEASE_DIR)/build/$(1)/lib/$(tgt_arch) +getlibrary = $(call getproject,$(call getprj,$(1)))/lib$(call getlib,$(1)).$(LIBEXTNS) +getlibraries = $(foreach prjlib,$(1),$(call getlibrary,$(prjlib))) +getprojects = $(foreach prjlib,$(1),$(call getprj,$(prjlib))) +getlinkdirs = $(addprefix -L, $(sort $(foreach prj,$(call getprojects,$(1)),$(call getproject,$(prj))))) +getlinksdir = $(addprefix -L, $(sort $(dir $(1)))) +getlinklibs = $(addprefix -l,$(foreach prjlib,$(1),$(call getlib,$(prjlib)))) +getlinkslib = $(addprefix -l,$(notdir $(1))) +getrpath = $$ORIGIN/../../../$(1)/lib/$(tgt_arch) +getrpaths = $(subst $(space),:,$(strip $(foreach prj,$(call getprojects,$(1)),$(call getrpath,$(prj))))) + +getmodname = $(word 1,$(subst ., ,$(1))) +getmodlibproject = $(RELEASE_DIR)/build/$(1)/modlib/$(tgt_arch) +getmodproject = $(RELEASE_DIR)/build/$(1)/mod/$(tgt_arch) +getmodlibrary = $(call getmodlibproject,$(call getprj,$(1)))/lib$(call getlib,$(1)).a +getmodlibraries = $(foreach prjlib,$(1),$(call getmodlibrary,$(prjlib))) +getmodlinkdirs = $(addprefix -L, $(sort $(foreach prj,$(call getprojects,$(1)),$(call getmodlibproject,$(prj))))) +expandneededmods = $(foreach needed,$(1),$(call getmodproject,$(call getprj,$(needed)))/$(call getlib,$(needed)).so) + + +define object_template + incdirs_$(1) := $$(addprefix -I$(RELEASE_DIR)/,$(2)) + incdirs_$(1) += -I$(RELEASE_DIR) + incdirs_$(1) += $$(addprefix -I$(RELEASE_DIR)/build/,$(2)) + incdirs_$(1) += -I$(RELEASE_DIR)/build + incdirs_$(1) += $$(addprefix -I,$(3)) +endef + +define library_template + library_$(1) := $$(libdir)/lib$(1).$(LIBEXTNS) + libobjs_$(1) := $$(call getobjects,$$(objdir),$$(libsrcs_$(1))) + libraries += $$(library_$(1)) + objects += $$(libobjs_$(1)) + depends += $$(libobjs_$(1):$$(objdir)/%.o=$$(depdir)/%.d) + libraries_$(1) := $$(call getlibraries,$$(liblibs_$(1))) + linkdirs_$(1) := $$(call getlinkdirs,$$(liblibs_$(1))) + linkdirs_$(1) += $$(call getlinksdir,$$(libslib_$(1))) +ifneq ($$(liblibs_$(1)),) + linklibs_$(1) := $$(call reverse,$$(call getlinklibs,$$(liblibs_$(1)))) +endif +ifneq ($$(libslib_$(1)),) + linklibs_$(1) += $$(call reverse,$$(call getlinkslib,$$(libslib_$(1)))) +endif +ifeq ($$(LIBEXTNS),so) +ifneq ($$(ifversn_$(1)),) + ifversnflags_$(1) := -Wl,--version-script=$$(ifversn_$(1)) +endif +endif + linkflags_$(1) := $$(linkdirs_$(1)) $$(linklibs_$(1)) +$$(library_$(1)): $$(libobjs_$(1)) +endef + +$(foreach lib,$(libnames),$(eval $(call library_template,$(lib)))) +$(foreach lib,$(libnames),$(foreach obj,$(libsrcs_$(lib)),$(eval $(call object_template,$(obj),$(libincs_$(lib)),$(libsinc_$(lib)))))) + +define target_template + target_$(1) := $$(bindir)/$(1) + tgtobjs_$(1) := $$(call getobjects,$$(objdir),$$(tgtsrcs_$(1))) + targets += $$(target_$(1)) + objects += $$(tgtobjs_$(1)) + depends += $$(tgtobjs_$(1):$$(objdir)/%.o=$$(depdir)/%.d) + libraries_$(1) := $$(call getlibraries,$$(tgtlibs_$(1))) + linkdirs_$(1) := $$(call getlinkdirs,$$(tgtlibs_$(1))) + linkdirs_$(1) += $$(call getlinksdir,$$(tgtslib_$(1))) +ifneq ($$(tgtlibs_$(1)),) + linklibs_$(1) := $$(call reverse,$$(call getlinklibs,$$(tgtlibs_$(1)))) +endif +ifneq ($$(tgtslib_$(1)),) + linklibs_$(1) += $$(call reverse,$$(call getlinkslib,$$(tgtslib_$(1)))) +endif +ifeq ($$(LIBEXTNS),so) + rpaths_$(1) := -Wl,-rpath='$$(call getrpaths,$$(tgtlibs_$(1)))' +endif + linkflags_$(1) := $$(linkdirs_$(1)) $$(linklibs_$(1)) $$(rpaths_$(1)) +ifneq ($$(MANAGERS),) + nomanagrs_$(1) := $$(filter-out $$(managrs_$(1)),$$(MANAGERS)) + nomanagrs_$(1) := $$(nomanagrs_$(1):%=$$(RTEMSDIR)/no-%.rel) + tgtobjs_$(1) += $$(nomanagrs_$(1)) +endif +$$(target_$(1)): $$(tgtobjs_$(1)) $$(libraries_$(1)) +endef + +$(foreach tgt,$(tgtnames),$(eval $(call target_template,$(tgt)))) +$(foreach tgt,$(tgtnames),$(foreach obj,$(tgtsrcs_$(tgt)),$(eval $(call object_template,$(obj),$(tgtincs_$(tgt)),$(tgtsinc_$(tgt)))))) + + +define module_library_template + library_$(1) := $$(modlibdir)/lib$(1).a + libobjs_$(1) := $$(call getobjects,$$(modobjdir),$$(libsrcs_$(1))) + libraries += $$(library_$(1)) + objects += $$(libobjs_$(1)) + depends += $$(libobjs_$(1):$$(modobjdir)/%.o=$$(moddepdir)/%.d) + libraries_$(1) := $$(call getmodlibraries,$$(liblibs_$(1))) + linkdirs_$(1) := $$(call getmodlinkdirs,$$(liblibs_$(1))) + linkdirs_$(1) += $$(call getmodlinksdir,$$(libslib_$(1))) +ifneq ($$(liblibs_$(1)),) + linklibs_$(1) := $$(call reverse,$$(call getlinklibs,$$(liblibs_$(1)))) +endif +ifneq ($$(libslib_$(1)),) + linklibs_$(1) += $$(call reverse,$$(call getlinkslib,$$(libslib_$(1)))) +endif + linkflags_$(1) := $$(linkdirs_$(1)) $$(linklibs_$(1)) +$$(library_$(1)): $$(libobjs_$(1)) +endef + +$(foreach lib,$(modlibnames),$(eval $(call module_library_template,$(lib)))) +$(foreach lib,$(modlibnames),$(foreach obj,$(libsrcs_$(lib)),$(eval $(call object_template,$(obj),$(libincs_$(lib)),$(libsinc_$(lib)))))) + + +define module_template + module_$(1) := $$(moddir)/$(1).$(majorv_$(1)).$(minorv_$(1)).$(branch_$(1)).so + modobjs_$(1) := $$(call getobjects,$$(modobjdir),$$(modsrcs_$(1))) + modules += $$(module_$(1)) + objects += $$(modobjs_$(1)) + depends += $$(modobjs_$(1):$$(modobjdir)/%.o=$$(moddepdir)/%.d) + libraries_$(1) := $$(call getmodlibraries,$$(modlibs_$(1))) + linkdirs_$(1) := $$(call getmodlinkdirs,$$(modlibs_$(1))) + linkdirs_$(1) += $$(call getlinksdir,$$(modslib_$(1))) +ifneq ($$(modlibs_$(1)),) + linklibs_$(1) := $$(call reverse,$$(call getlinklibs,$$(modlibs_$(1)))) +endif +ifneq ($$(modslib_$(1)),) + linklibs_$(1) += $$(call reverse,$$(call getlinkslib,$$(modslib_$(1)))) +endif + linkflags_$(1) := $$(linkdirs_$(1)) $$(linklibs_$(1)) +$$(module_$(1)): $$(modobjs_$(1)) $$(libraries_$(1)) $$(call expandneededmods,$$(modsneeded_$(1))) +endef + +$(foreach mod,$(modnames),$(eval $(call module_template,$(mod)))) +$(foreach mod,$(modnames),$(foreach obj,$(modsrcs_$(mod)),$(eval $(call object_template,$(obj),$(modincs_$(mod)),$(modsinc_$(mod)))))) + + +# Rules +# ----- +rules := all dir obj lib bin clean cleanall userall userclean print + +.PHONY: $(rules) $(libnames) $(tgtnames) + +.SUFFIXES: # Kills all implicit rules + +all: bin userall; + +obj: $(objects); + +lib: $(libraries); + +bin: lib $(targets) $(modules); + +dir: $(prod_dirs) $(temp_dirs); + +print: + @echo "bindir = $(bindir)" + @echo "moddir = $(moddir)" + @echo "libdir = $(libdir)" + @echo "objdir = $(objdir)" + @echo "modobjdir = $(modobjdir)" + @echo "depdir = $(depdir)" + @echo "moddepdir = $(moddepdir)" + @echo "targets = $(targets)" + @echo "libraries = $(libraries)" + @echo "modules = $(modules)" + @echo "depends = $(depends)" + @echo "objects = $(objects)" + @echo "managers = $(MANAGERS)" + +clean: userclean +ifneq ($(objects),) + @echo "[RO] Removing object files" + $(quiet)$(RM) $(objects) +endif +ifneq ($(depends),) + @echo "[RD] Removing depend files" + $(quiet)$(RM) $(depends) +endif +ifneq ($(libraries),) + @echo "[RL] Removing libraries: $(notdir $(libraries))" + $(quiet)$(RM) $(libraries) +endif +ifneq ($(targets),) + @echo "[RT] Removing targets: $(notdir $(targets))" + $(quiet)$(RM) $(targets) +endif +ifneq ($(modules),) + @echo "[RM] Removing modules: $(notdir $(modules))" + $(quiet)$(RM) $(modules) +endif + +cleanall: userclean + $(quiet)$(RM) -r $(temp_dirs) + + +# Directory structure +$(prod_dirs) $(temp_dirs): + $(quiet)mkdir -p $@ + + +# Libraries +$(libdir)/lib%.$(LIBEXTNS): + @echo "[LD] Build library $*" + $(quiet)$(LD) $(LDFLAGS) $(ifversnflags_$*) $(linkflags_$*) $^ -o $@ + + +# Exceutables +$(bindir)/%: + @echo "[LT] Linking target $*" + $(quiet)$(LX) $(DEFINES) $(tgtobjs_$*) $(linkflags_$*) $(LXFLAGS) -o $@ + +# Libraries for modules +$(modlibdir)/lib%.a: + @echo "[MD] Linking lib-for-modules $*" + $(quiet)$(LD) $(MLDFLAGS) $(linkflags_$*) $^ -o $@ + +# Modules +ifeq ($(RCE_CORE_VERSION),2.2) +ldtoolsobj := $(LDTOOLSD) +else +ldtoolsobj := $(RELEASE_DIR)/build/rce/modobj/$(tgt_arch)/ldtools +endif + +$(moddir)/%: + @echo "[LM] Linking module $* (modname = $(call getmodname,$*))" + $(quiet)$(LX) $(MLXFLAGS) -o $@ \ + -Wl,-soname,$(*:.so=) \ + -Wl,-Map,$(moddir)/$*.map \ + $(ldtoolsobj)/modbegin.o \ + $(ldtoolsobj)/rcework.o \ + $(modobjs_$(call getmodname,$*)) $(linkflags_$(call getmodname,$*)) \ + $(ldtoolsobj)/modend.o \ + $(modsneeded_$(call getmodname,$*)) + $(quiet)$(OBJCOPY) --set-section-flags .bss=alloc,contents,load $@ + +# Objects for C, C++ and assembly files not intended for modules +$(objdir)/%.o: %.c + @echo "[CC] Compiling $<" + $(quiet)$(CC) $(incdirs_$<) $(CPPFLAGS) $(DEFINES) $(CFLAGS) -c $< -o $@ + +$(objdir)/%.o: %.cc + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(DEFINES) $(CXXFLAGS) -c $< -o $@ + +$(objdir)/%.o: %.cpp + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(DEFINES) $(CXXFLAGS) -c $< -o $@ + +$(objdir)/%.o: %.s + @echo "[CS] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(DEFINES) $(CASFLAGS) -c $< -o $@ + + +# Module objects for C, C++ and assembly files +$(modobjdir)/%.o: %.c + @echo "[MC] Compiling $<" + $(quiet)$(CC) $(incdirs_$<) $(CPPFLAGS) $(MDEFINES) $(MCFLAGS) -c $< -o $@ + +$(modobjdir)/%.o: %.cc + @echo "[MX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(MDEFINES) $(MCXXFLAGS) -c $< -o $@ + +$(modobjdir)/%.o: %.cpp + @echo "[MX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(MDEFINES) $(MCXXFLAGS) -c $< -o $@ + +$(modobjdir)/%.o: %.s + @echo "[MS] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(CPPFLAGS) $(MDEFINES) $(MCASFLAGS) -c $< -o $@ + + +# Defines rules to (re)build dependency files +DEPSED = sed '\''s!$(notdir $*)\.o!$(objdir)/$*\.o $@!g'\'' +CXXDEP = $(CXX) $(incdirs_$<) $(CPPFLAGS) $(DEPFLAGS) +CCDEP = $(CC) $(incdirs_$<) $(CPPFLAGS) $(DEPFLAGS) + +$(depdir)/%.d: %.c + @echo "[DC] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CCDEP) $< | $(DEPSED) > $@' + +$(depdir)/%.d: %.cc + @echo "[DX] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CXXDEP) $< | $(DEPSED) > $@' + +$(depdir)/%.d: %.cpp + @echo "[DX] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CXXDEP) $< | $(DEPSED) > $@' + +$(depdir)/%.d: %.s + @echo "[DS] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CCDEP) $< | $(DEPSED) > $@' + +MODDEPSED = sed '\''s!$(notdir $*)\.o!$(modobjdir)/$*\.o $@!g'\'' + +$(moddepdir)/%.d: %.c + @echo "[MDC] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CCDEP) $< | $(MODDEPSED) > $@' + +$(moddepdir)/%.d: %.cc + @echo "[MDX] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CXXDEP) $< | $(MODDEPSED) > $@' + +$(moddepdir)/%.d: %.cpp + @echo "[MDX] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CXXDEP) $< | $(MODDEPSED) > $@' + +$(moddepdir)/%.d: %.s + @echo "[MDS] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(CCDEP) $< | $(MODDEPSED) > $@' + +# Include the dependency files. If one of the .d files in depends +# does not exist, then make invokes one of the rules [Dn] above to +# rebuild the missing .d file. This can be short-circuited by +# defining the symbol 'no_depends'. + +ifneq ($(depends),) +ifeq ($(no_depends),) +-include $(depends) +endif +endif diff --git a/rce/make/sw/python.mk b/rce/make/sw/python.mk new file mode 100644 index 0000000000000000000000000000000000000000..790fdc211e8060330da126778c248d34e2ba840b --- /dev/null +++ b/rce/make/sw/python.mk @@ -0,0 +1,41 @@ +# Call sip interpreter for python wrappers +$(objdir)/%_sip_wrap.o: $(objdir)/%_sip_wrap.cpp + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$*_sip_wrap.cpp) $(DEFINES) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + + +$(objdir)/%_sip_wrap.cpp: %_sip_wrap.sip + @echo "[WG] Python sip $<" + $(quiet)sip $(SIPFLAGS) -e -j 1 -c $(objdir)/ $< + cp $(objdir)/sip$*part0.cpp . + $(quiet)mv $(objdir)/sip$*part0.cpp $@ + +# $(incdirs_$*_sip_wrap.cpp) + + +# Call swig interpreter for python wrappers +$(objdir)/%_swig_wrap.o: $(objdir)/%_swig_wrap.c + @echo "[CC] Compiling $<" + $(quiet)$(CC) $(incdirs_$*_swig_wrap.c) $(DEFINES) $(CFLAGS) -c $< -o $@ + +$(objdir)/%_swig_wrap.c: %_swig_wrap.i + @echo "[WG] Python swig $<" + $(quiet)swig $(incdirs_$*_swig_wrap.c) -Wall -python -o $@ $< + +SWGDEPSED = sed '\''s!$(notdir $*)\_swig_wrap_wrap.c!$(objdir)/$*\_swig_wrap.c $@!g'\'' +SWGDEP = swig $(DEPFLAGS) $(incdirs_$*_swig_wrap.c) + +$(depdir)/%_swig_wrap.d: %_swig_wrap.i + @echo "[DI] Dependencies for $<" + $(quiet)$(SHELL) -ec '$(SWGDEP) $< | $(SWGDEPSED) > $@' + +# Include the dependency files. If one of the .d files in depends +# does not exist, then make invokes one of the rules [Dn] above to +# rebuild the missing .d file. This can be short-circuited by +# defining the symbol 'no_depends'. + +ifneq ($(depends),) +ifeq ($(no_depends),) +-include $(depends) +endif +endif diff --git a/rce/make/sw/qt.mk b/rce/make/sw/qt.mk new file mode 100644 index 0000000000000000000000000000000000000000..816877e4668cb05007c36bc8e0e607d9b048e6c0 --- /dev/null +++ b/rce/make/sw/qt.mk @@ -0,0 +1,10 @@ +# Call Qt meta object compiler (moc) +MOC := $(RELEASE_DIR)/build/qt/bin/moc + +$(objdir)/%_moc.o: %_moc.cc + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$<) $(DEFINES) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ + +%_moc.cc: %.hh + @echo "[MOC] Qt moc $<" + $(quiet)$(MOC) $< -o $@ diff --git a/rce/make/sw/rootcint.mk b/rce/make/sw/rootcint.mk new file mode 100644 index 0000000000000000000000000000000000000000..b20553709ddc845c18216f729f2e99a5f88c6a7b --- /dev/null +++ b/rce/make/sw/rootcint.mk @@ -0,0 +1,10 @@ +# Call rootcint to make root dictionary. +$(objdir)/%_rootDict.o: $(objdir)/%_rootDict.cc + @echo "[CX] Compiling $<" + $(quiet)$(CXX) $(incdirs_$(notdir $<)) $(DEFINES) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + + + +$(objdir)/%_rootDict.cc: %_Linkdef.hh $(GUIHEADERSDEP) + @echo "[RC] Rootcint Preprocessing $<" + $(quiet)rootcint -f $@ -c $(CPPFLAGS) $(guiheaders_$(subst _Linkdef.hh,,$<)) $< diff --git a/rce/make/tools/options.py b/rce/make/tools/options.py new file mode 100644 index 0000000000000000000000000000000000000000..68b8c2db4609cf8ad481a7f3d169f5035169546c --- /dev/null +++ b/rce/make/tools/options.py @@ -0,0 +1,47 @@ +import sys +import getopt + +class Options(object): + def __init__(self, mandatory, optional=[], switches=[]): + self.opts = {} + + self.__mand = mandatory + self.__optn = optional + self.__swtc = switches + + def __getattr__(self, attribute): + if attribute in self.opts: + return self.opts[attribute] + return None + + def usage(self, notes=''): + msg = 'usage: %s' %(sys.argv[0]) + for option in self.__mand: + msg += ' --%s <%sname>' %(option, option) + for option in self.__optn: + msg += ' [--%s <%sname>]' %(option, option) + for option in self.__swtc: + msg += ' [--%s]' %(option) + if notes != '': + msg += '\nnotes: ' + msg += notes + print msg + + + def parse(self): + opts = [] + for option in self.__mand: + opts.append(option+'=') + for option in self.__optn: + opts.append(option+'=') + for option in self.__swtc: + opts.append(option) + results = getopt.getopt(sys.argv[1:], '', opts) + if len(results[1]) > 0: + raise RuntimeError, 'unknown argument(s) \'%s\'' %(results[1]) + for opt in results[0]: + self.opts[opt[0][2:]] = opt[1] + for option in self.__mand: + if option not in self.opts: + raise RuntimeError, 'mandatory option \'--%s\' not found' %(option) + diff --git a/rce/make/tools/pkgcreate.py b/rce/make/tools/pkgcreate.py new file mode 100755 index 0000000000000000000000000000000000000000..c11c77cd389bb95865ec63e428676e8115c68124 --- /dev/null +++ b/rce/make/tools/pkgcreate.py @@ -0,0 +1,50 @@ +#!/usr/bin/python + +import sys +import os +import shutil + +from options import Options + +def __pkgcreate(options): + prjdir = options.project + pkgdir = os.path.join(prjdir, options.package) + + if not os.path.exists(prjdir): + os.mkdir(prjdir) + shutil.copy('make/share/Makefile.project.template', + os.path.join(prjdir, 'Makefile')) + shutil.copy('make/share/packages.mk.template', + os.path.join(prjdir, 'packages.mk')) + if options.hw is None: + shutil.copy('make/sw/flags.mk.template', + os.path.join(prjdir, 'flags.mk')) + else: + shutil.copy('make/hw/flags.mk.template', + os.path.join(prjdir, 'flags.mk')) + + if not os.path.exists(pkgdir): + os.mkdir(pkgdir) + if options.hw is None: + shutil.copy('make/sw/Makefile.package.template', + os.path.join(pkgdir, 'Makefile')) + shutil.copy('make/sw/constituents.mk.template', + os.path.join(pkgdir, 'constituents.mk')) + else: + shutil.copy('make/hw/Makefile.package.template', + os.path.join(pkgdir, 'Makefile')) + shutil.copy('make/hw/constituents.mk.template', + os.path.join(pkgdir, 'constituents.mk')) + else: + print "Package %s already exists" %(pkgdir) + + +if __name__ == '__main__': + options = Options(['project', 'package'], [], ['hw']) + try: + options.parse() + except Exception, msg: + options.usage(str(msg)) + sys.exit() + + __pkgcreate(options) diff --git a/rce/make/tools/prjupdate.py b/rce/make/tools/prjupdate.py new file mode 100755 index 0000000000000000000000000000000000000000..49e10535d4b84a96cf6041574c776bf4c4f6e449 --- /dev/null +++ b/rce/make/tools/prjupdate.py @@ -0,0 +1,48 @@ +#!/usr/bin/python + +import sys +import os +import shutil +import glob + +from options import Options + +def __prjupdate(options): + prjdir = options.project + + if os.path.exists(prjdir): + if os.path.exists(os.path.join(prjdir, 'Makefile')): + os.rename(os.path.join(prjdir, 'Makefile'), + os.path.join(prjdir, 'Makefile.orig')) + if os.path.exists(os.path.join(prjdir, 'flags.mk')): + os.rename(os.path.join(prjdir, 'flags.mk'), + os.path.join(prjdir, 'flags.mk.orig')) + shutil.copy('make/share/Makefile.project.template', + os.path.join(prjdir, 'Makefile')) + if options.hw is None: + shutil.copy('make/sw/flags.mk.template', + os.path.join(prjdir, 'flags.mk')) + else: + shutil.copy('make/hw/flags.mk.template', + os.path.join(prjdir, 'flags.mk')) + else: + print "Project %s does not exist" %(prjdir) + + pkgmakes = glob.glob(os.path.join(prjdir, '*/Makefile')) + for pkgmake in pkgmakes: + os.rename(pkgmake, pkgmake+'.orig') + if options.hw is None: + shutil.copy('make/sw/Makefile.package.template', pkgmake) + else: + shutil.copy('make/hw/Makefile.package.template', pkgmake) + + +if __name__ == '__main__': + options = Options(['project'], [], ['hw']) + try: + options.parse() + except Exception, msg: + options.usage(str(msg)) + sys.exit() + + __prjupdate(options) diff --git a/rce/make/tools/replace.pl b/rce/make/tools/replace.pl new file mode 100755 index 0000000000000000000000000000000000000000..35614c987cb4c707cdad9f645dd46a39366e76fb --- /dev/null +++ b/rce/make/tools/replace.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +# Check number of arguments +if($#ARGV < 2){ + print STDERR "Usage: $0 <srcstring> <dststring> <files>\n"; + exit; +} + +$srcstring = shift @ARGV; +$dststring = shift @ARGV; + +foreach $srcfile (@ARGV) { + open (SRCFILE, "<$srcfile") or die "Can't open $srcfile: $!\n"; + $dstfile = "$srcfile.replace"; + open (DSTFILE, ">$dstfile") or die "Can't open $dstfile: $!\n"; + while (<SRCFILE>) { + s/$srcstring/$dststring/g; + print DSTFILE; + } + close SRCFILE; + close DSTFILE; + rename $dstfile, $srcfile; +} diff --git a/rce/pixelrce/config/FEI3/IPCModule.cc b/rce/pixelrce/config/FEI3/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..dc2e50fbd62981b791871b0d25277573db2ae298 --- /dev/null +++ b/rce/pixelrce/config/FEI3/IPCModule.cc @@ -0,0 +1,203 @@ +#ifndef FEI3__IPCMODULE_CC +#define FEI3__IPCMODULE_CC +#include "util/RceName.hh" +#include "config/FEI3/IPCModule.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace FEI3{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI3Adapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::PixelModuleConfig &legacyModuleConfig){ + m_mcc.setRegister(Mcc::MCC_LV1,legacyModuleConfig.MCCRegisters.regLV1); + m_mcc.setRegister(Mcc::MCC_CSR,legacyModuleConfig.MCCRegisters.regCSR); + m_mcc.setRegister(Mcc::MCC_CAL,legacyModuleConfig.MCCRegisters.regCAL); + m_mcc.setRegister(Mcc::MCC_FEEN,legacyModuleConfig.maskEnableFEConfig); + + const ipc::PixelFEConfig *legacyFEConfig; + const ipc::PixelFETrims *legacyFETrims; + const ipc::PixelFEMasks *legacyFEMasks; + for(int chip=0;chip<N_FRONTENDS;++chip) { + m_frontend[chip]->setChipAddress(chip, legacyModuleConfig.FEConfig[chip].FEIndex); + legacyFEConfig = &legacyModuleConfig.FEConfig[chip]; + legacyFETrims = &legacyFEConfig->FETrims; + legacyFEMasks = &legacyFEConfig->FEMasks; + + globalLegacyToUsr(legacyFEConfig, chip); + + m_frontend[chip]->setVcalCoeff(0, legacyFEConfig->FECalib.vcalCoeff[0]); + m_frontend[chip]->setVcalCoeff(1, legacyFEConfig->FECalib.vcalCoeff[1]); + m_frontend[chip]->setVcalCoeff(2, legacyFEConfig->FECalib.vcalCoeff[2]); + m_frontend[chip]->setVcalCoeff(3, legacyFEConfig->FECalib.vcalCoeff[3]); + m_frontend[chip]->setCapVal(0, legacyFEConfig->FECalib.cinjLo); + m_frontend[chip]->setCapVal(1, legacyFEConfig->FECalib.cinjHi); + + for(int col=0;col<Frontend::N_COLS;++col) { + for(int row=0;row<Frontend::N_ROWS;++row) { + unsigned char tdac = legacyFETrims->dacThresholdTrim[row][col]; + unsigned char fdac = legacyFETrims->dacFeedbackTrim[row][col]; + unsigned mask = (1 << (row & 0x1f)); + unsigned char enable = (legacyFEMasks->maskEnable[row >> 5][col] & mask) ? 1 : 0; + unsigned char select = (legacyFEMasks->maskSelect[row >> 5][col] & mask) ? 1 : 0; + unsigned char kill = (legacyFEMasks->maskPreamp[row >> 5][col] & mask) ? 1 : 0; + unsigned char hitbus = (legacyFEMasks->maskHitbus[row >> 5][col] & mask) ? 1 : 0; + PixelRegister* pixel=m_frontend[chip]->getPixelRegister(col,row); + pixel->setField(PixelRegister::tdac, tdac); + pixel->setField(PixelRegister::fdac, fdac); + pixel->setField(PixelRegister::enable, enable); + pixel->setField(PixelRegister::select, select); + pixel->setField(PixelRegister::kill, kill); + pixel->setField(PixelRegister::hitbus, hitbus); + } + } + } + std::cout<<"Configure done"<<std::endl; + return 0; +} +template <class TP> +void IPCModule<TP>::globalLegacyToUsr(const ipc::PixelFEConfig* legacyFE, unsigned chip){ + + const ipc::PixelFEGlobal *feGlobal; + feGlobal = &legacyFE->FEGlobal; + + m_frontend[chip]->setGlobalRegField("latency", feGlobal->latency); + m_frontend[chip]->setGlobalRegField("selfTriggerDelay", feGlobal->selfLatency); + m_frontend[chip]->setGlobalRegField("selfTriggerWidth", feGlobal->selfWidth); + m_frontend[chip]->setGlobalRegField("enableSelfTrigger", feGlobal->enableSelfTrigger); + m_frontend[chip]->setGlobalRegField("enableHitParity", feGlobal->enableHitParity); + m_frontend[chip]->setGlobalRegField("doMux", feGlobal->muxDO); + m_frontend[chip]->setGlobalRegField("selectMonHit", feGlobal->muxMonHit); + m_frontend[chip]->setGlobalRegField("tsiTscEnable", feGlobal->enableTimestamp); + + m_frontend[chip]->setGlobalRegField("selectDataPhase", 0); /* previously spare */ + m_frontend[chip]->setGlobalRegField("enableEOEParity", 0); /* previously spare */ + + m_frontend[chip]->setGlobalRegField("hitBusScaler", 0); /* read-only */ + + m_frontend[chip]->setGlobalRegField("monLeakADCRefTest", feGlobal->monADCRef); + m_frontend[chip]->setGlobalRegField("monLeakADCDAC", feGlobal->dacMonLeakADC); + m_frontend[chip]->setGlobalRegField("monLeakDACTest", feGlobal->monMonLeakADC); + m_frontend[chip]->setGlobalRegField("monLeakADCEnableComparator", feGlobal->enableMonLeak); + m_frontend[chip]->setGlobalRegField("monLeakADCMonComp", 0); /* status */ + m_frontend[chip]->setGlobalRegField("aRegTrim", feGlobal->aregTrim); + m_frontend[chip]->setGlobalRegField("enableARegMeas", feGlobal->enableAregMeas); + m_frontend[chip]->setGlobalRegField("aRegMeas", feGlobal->aregMeas); + m_frontend[chip]->setGlobalRegField("enableAReg", feGlobal->enableAreg); + m_frontend[chip]->setGlobalRegField("enableLVDSRefMeas", feGlobal->enableLvdsRegMeas); + m_frontend[chip]->setGlobalRegField("dRegTrim", feGlobal->dregTrim); + m_frontend[chip]->setGlobalRegField("enableDRegMeas", feGlobal->enableDregMeas); + m_frontend[chip]->setGlobalRegField("dRegMeas", feGlobal->dregMeas); + m_frontend[chip]->setGlobalRegField("capMeasCircuitry", feGlobal->capMeasure); + + m_frontend[chip]->setGlobalRegField("enableCapTest", feGlobal->enableCapTest); + m_frontend[chip]->setGlobalRegField("enableAnalogOut", feGlobal->enableBuffer); + m_frontend[chip]->setGlobalRegField("enableTestPixelMux", feGlobal->muxTestPixel); + m_frontend[chip]->setGlobalRegField("enableVCalMeas", feGlobal->enableVcalMeasure); + m_frontend[chip]->setGlobalRegField("enableLeakMeas", feGlobal->enableLeakMeasure); + m_frontend[chip]->setGlobalRegField("enableBufferBoost", feGlobal->enableBufferBoost); + + m_frontend[chip]->setGlobalRegField("enableCP8", feGlobal->enableCP8); + m_frontend[chip]->setGlobalRegField("testDacForIVDD2Dac", feGlobal->monIVDD2); + m_frontend[chip]->setGlobalRegField("dacIVDD2", feGlobal->dacIVDD2); + m_frontend[chip]->setGlobalRegField("dacID", feGlobal->dacID); + m_frontend[chip]->setGlobalRegField("testDacForIDDac", feGlobal->monID); + + m_frontend[chip]->setGlobalRegField("enableCP7", feGlobal->enableCP7); + m_frontend[chip]->setGlobalRegField("testDacForIP2Dac", feGlobal->monIP2); + m_frontend[chip]->setGlobalRegField("dacIP2", feGlobal->dacIP2); + m_frontend[chip]->setGlobalRegField("dacIP", feGlobal->dacIP); + m_frontend[chip]->setGlobalRegField("testDacForIPDac", feGlobal->monIP); + + m_frontend[chip]->setGlobalRegField("enableCP6", feGlobal->enableCP6); + m_frontend[chip]->setGlobalRegField("testDacForITrimThDac", feGlobal->monITRIMTH); + m_frontend[chip]->setGlobalRegField("dacITRIMTH", feGlobal->dacITRIMTH); + m_frontend[chip]->setGlobalRegField("dacIF", feGlobal->dacIF); + m_frontend[chip]->setGlobalRegField("testDacForIFDac", feGlobal->monIF); + + m_frontend[chip]->setGlobalRegField("enableCP5", feGlobal->enableCP5); + m_frontend[chip]->setGlobalRegField("testDacForITrimIfDac", feGlobal->monITRIMIF); + m_frontend[chip]->setGlobalRegField("dacITRIMIF", feGlobal->dacITRIMIF); + m_frontend[chip]->setGlobalRegField("dacVCAL", feGlobal->dacVCAL); + m_frontend[chip]->setGlobalRegField("testDacForVCalDac", feGlobal->monVCAL); + + m_frontend[chip]->setGlobalRegField("enableCP4", feGlobal->enableCP4); + m_frontend[chip]->setGlobalRegField("enableCinjHigh", feGlobal->enableCinjHigh); + m_frontend[chip]->setGlobalRegField("enableExternalInj", feGlobal->enableExternal); + m_frontend[chip]->setGlobalRegField("enableTestAnalogRef", feGlobal->enableTestAnalogRef); + m_frontend[chip]->setGlobalRegField("eocMux", feGlobal->muxEOC); + m_frontend[chip]->setGlobalRegField("CEUClockControl", feGlobal->frequencyCEU); + + m_frontend[chip]->setGlobalRegField("enableDigitalInject", feGlobal->enableDigital); + m_frontend[chip]->setGlobalRegField("enableCP3", feGlobal->enableCP3); + m_frontend[chip]->setGlobalRegField("testDacForITH1Dac", feGlobal->monITH1); + m_frontend[chip]->setGlobalRegField("dacITH1", feGlobal->dacITH1); + m_frontend[chip]->setGlobalRegField("dacITH2", feGlobal->dacITH2); + m_frontend[chip]->setGlobalRegField("testDacForITH2Dac", feGlobal->monITH2); + + m_frontend[chip]->setGlobalRegField("enableCP2", feGlobal->enableCP2); + m_frontend[chip]->setGlobalRegField("testDacILDac", feGlobal->monIL); + m_frontend[chip]->setGlobalRegField("dacIL", feGlobal->dacIL); + m_frontend[chip]->setGlobalRegField("dacIL2", feGlobal->dacIL2); + m_frontend[chip]->setGlobalRegField("testDacIL2Dac", feGlobal->monIL2); + + m_frontend[chip]->setGlobalRegField("enableCP1", feGlobal->enableCP1); + m_frontend[chip]->setGlobalRegField("threshTOTMinimum", feGlobal->threshTOTMinimum); + m_frontend[chip]->setGlobalRegField("threshTOTDouble", feGlobal->threshTOTDouble); + m_frontend[chip]->setGlobalRegField("modeTOTThresh", feGlobal->modeTOTThresh); + + m_frontend[chip]->setGlobalRegField("enableCP0", feGlobal->enableCP0); + m_frontend[chip]->setGlobalRegField("enableHitbus", feGlobal->enableHitbus); + m_frontend[chip]->setGlobalRegField("gTDac", feGlobal->gdac); + m_frontend[chip]->setGlobalRegField("enableTune", feGlobal->enableTune); + m_frontend[chip]->setGlobalRegField("enableBiasComp", feGlobal->enableBiasComp); + m_frontend[chip]->setGlobalRegField("enableIpMonitor", feGlobal->enableIpMonitor); +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/pixelrce/config/FEI3/IPCModule.hh b/rce/pixelrce/config/FEI3/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..a93971adc65f0bb0c1b869293bf12fe6802e012e --- /dev/null +++ b/rce/pixelrce/config/FEI3/IPCModule.hh @@ -0,0 +1,27 @@ +#ifndef IPCFEI3MODULE_HH +#define IPCFEI3MODULE_HH + +#include "config/FEI3/Module.hh" +#include "ipc/object.h" +#include "PixelModuleConfig.hh" +#include "IPCFEI3Adapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI3{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>, public FEI3::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelModuleConfig &config); + void globalLegacyToUsr(const ipc::PixelFEConfig* legacy, unsigned chip); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/pixelrce/config/FEI4/IPCFEI4AModule.cc b/rce/pixelrce/config/FEI4/IPCFEI4AModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..9ccf44da8c0ad9a09a2314de4529395658413c3c --- /dev/null +++ b/rce/pixelrce/config/FEI4/IPCFEI4AModule.cc @@ -0,0 +1,314 @@ +#ifndef FEI4__IPCMODULE_CC +#define FEI4__IPCMODULE_CC +#include "util/RceName.hh" +#include "config/FEI4/IPCFEI4AModule.hh" +#include "config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "HW/SerialIF.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace FEI4{ + +template <class TP> +IPCFEI4AModule<TP>::IPCFEI4AModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI4AAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + FEI4AModule(name, id, inLink, outLink, fmt){ + // std::cout<<"IPCFEI4AModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCFEI4AModule<TP>::~IPCFEI4AModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCFEI4AModule<TP>::IPCsetChipAddress(CORBA::ULong addr){ + m_commands->setAddr(addr); +} +template <class TP> +CORBA::Long IPCFEI4AModule<TP>::IPCverifyModuleConfigHW(){ + return verifyModuleConfigHW(); +} +template <class TP> +CORBA::Long IPCFEI4AModule<TP>::IPCdownloadConfig(const ipc::PixelFEI4AConfig &config){ + // geographical address + m_gAddr=config.FECommand.address; + m_commands->setAddr(m_gAddr); + + + const ipc::PixelFEI4AGlobal *cfg=&config.FEGlobal; + // global register + m_global->setField("TrigCnt", cfg->TrigCnt , GlobalRegister::SW); + m_global->setField("Conf_AddrEnable", cfg->Conf_AddrEnable , GlobalRegister::SW); + m_global->setField("Reg2Spare", cfg->Reg2Spare , GlobalRegister::SW); + m_global->setField("ErrMask0", cfg->ErrMask0 , GlobalRegister::SW); + m_global->setField("ErrMask1", cfg->ErrMask1 , GlobalRegister::SW); + m_global->setField("PrmpVbpRight", cfg->PrmpVbpRight , GlobalRegister::SW); + m_global->setField("Vthin", cfg->Vthin , GlobalRegister::SW); + m_global->setField("DisVbn_CPPM", cfg->DisVbn_CPPM , GlobalRegister::SW); + m_global->setField("PrmpVbp", cfg->PrmpVbp , GlobalRegister::SW); + m_global->setField("TdacVbp", cfg->TdacVbp , GlobalRegister::SW); + m_global->setField("DisVbn", cfg->DisVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbn", cfg->Amp2Vbn , GlobalRegister::SW); + m_global->setField("Amp2VbpFol", cfg->Amp2VbpFol , GlobalRegister::SW); + m_global->setField("PrmpVbpTop", cfg->PrmpVbpTop , GlobalRegister::SW); + m_global->setField("Amp2Vbp", cfg->Amp2Vbp , GlobalRegister::SW); + m_global->setField("FdacVbn", cfg->FdacVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbpf", cfg->Amp2Vbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnFol", cfg->PrmpVbnFol , GlobalRegister::SW); + m_global->setField("PrmpVbpLeft", cfg->PrmpVbpLeft , GlobalRegister::SW); + m_global->setField("PrmpVbpf", cfg->PrmpVbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnLcc", cfg->PrmpVbnLcc , GlobalRegister::SW); + m_global->setField("PxStrobes", cfg->PxStrobes , GlobalRegister::SW); + m_global->setField("S0", cfg->S0 , GlobalRegister::SW); + m_global->setField("S1", cfg->S1 , GlobalRegister::SW); + m_global->setField("LVDSDrvIref", cfg->LVDSDrvIref , GlobalRegister::SW); + m_global->setField("BonnDac", cfg->BonnDac , GlobalRegister::SW); + m_global->setField("PllIbias", cfg->PllIbias , GlobalRegister::SW); + m_global->setField("LVDSDrvVos", cfg->LVDSDrvVos , GlobalRegister::SW); + m_global->setField("TempSensBias", cfg->TempSensBias , GlobalRegister::SW); + m_global->setField("PllIcp", cfg->PllIcp , GlobalRegister::SW); + m_global->setField("Reg17Spare", cfg->Reg17Spare , GlobalRegister::SW); + m_global->setField("PlsrIdacRamp", cfg->PlsrIdacRamp , GlobalRegister::SW); + m_global->setField("Reg18Spare", cfg->Reg18Spare , GlobalRegister::SW); + m_global->setField("PlsrVgOPamp", cfg->PlsrVgOPamp , GlobalRegister::SW); + m_global->setField("PlsrDacBias", cfg->PlsrDacBias , GlobalRegister::SW); + m_global->setField("Reg19Spare", cfg->Reg19Spare , GlobalRegister::SW); + m_global->setField("Vthin_AltCoarse", cfg->Vthin_AltCoarse , GlobalRegister::SW); + m_global->setField("Vthin_AltFine", cfg->Vthin_AltFine , GlobalRegister::SW); + m_global->setField("PlsrDAC", cfg->PlsrDAC , GlobalRegister::SW); + m_global->setField("DIGHITIN_Sel", cfg->DIGHITIN_Sel , GlobalRegister::SW); + m_global->setField("DINJ_Override", cfg->DINJ_Override , GlobalRegister::SW); + m_global->setField("HITLD_In", cfg->HITLD_In , GlobalRegister::SW); + m_global->setField("Reg21Spare", cfg->Reg21Spare , GlobalRegister::SW); + m_global->setField("Reg22Spare2", cfg->Reg22Spare2 , GlobalRegister::SW); + m_global->setField("Colpr_Addr", cfg->Colpr_Addr , GlobalRegister::SW); + m_global->setField("Colpr_Mode", cfg->Colpr_Mode , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg0", cfg->DisableColumnCnfg0 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg1", cfg->DisableColumnCnfg1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg2", cfg->DisableColumnCnfg2 , GlobalRegister::SW); + m_global->setField("TrigLat", cfg->TrigLat , GlobalRegister::SW); + m_global->setField("CMDcnt", cfg->CMDcnt , GlobalRegister::SW); + m_global->setField("StopModeCnfg", cfg->StopModeCnfg , GlobalRegister::SW); + m_global->setField("HitDiscCnfg", cfg->HitDiscCnfg , GlobalRegister::SW); + m_global->setField("EN_PLL", cfg->EN_PLL , GlobalRegister::SW); + m_global->setField("Efuse_sense", cfg->Efuse_sense , GlobalRegister::SW); + m_global->setField("Stop_Clk", cfg->Stop_Clk , GlobalRegister::SW); + m_global->setField("ReadErrorReq", cfg->ReadErrorReq , GlobalRegister::SW); + m_global->setField("ReadSkipped", cfg->ReadSkipped , GlobalRegister::SW); + m_global->setField("Reg27Spare", cfg->Reg27Spare , GlobalRegister::SW); + m_global->setField("GateHitOr", cfg->GateHitOr , GlobalRegister::SW); + m_global->setField("CalEn", cfg->CalEn , GlobalRegister::SW); + m_global->setField("SR_clr", cfg->SR_clr , GlobalRegister::SW); + m_global->setField("Latch_en", cfg->Latch_en , GlobalRegister::SW); + m_global->setField("SR_Clock", cfg->SR_Clock , GlobalRegister::SW); + m_global->setField("LVDSDrvSet06", cfg->LVDSDrvSet06 , GlobalRegister::SW); + m_global->setField("Reg28Spare", cfg->Reg28Spare , GlobalRegister::SW); + m_global->setField("EN40M", cfg->EN40M , GlobalRegister::SW); + m_global->setField("EN80M", cfg->EN80M , GlobalRegister::SW); + m_global->setField("CLK1", cfg->CLK1 , GlobalRegister::SW); + m_global->setField("CLK0", cfg->CLK0 , GlobalRegister::SW); + m_global->setField("EN160M", cfg->EN160M , GlobalRegister::SW); + m_global->setField("EN320M", cfg->EN320M , GlobalRegister::SW); + m_global->setField("Reg29Spare1", cfg->Reg29Spare1 , GlobalRegister::SW); + m_global->setField("no8b10b", cfg->no8b10b , GlobalRegister::SW); + m_global->setField("Clk2OutCnfg", cfg->Clk2OutCnfg , GlobalRegister::SW); + m_global->setField("EmptyRecord", cfg->EmptyRecord , GlobalRegister::SW); + m_global->setField("Reg29Spare2", cfg->Reg29Spare2 , GlobalRegister::SW); + m_global->setField("LVDSDrvEn", cfg->LVDSDrvEn , GlobalRegister::SW); + m_global->setField("LVDSDrvSet30", cfg->LVDSDrvSet30 , GlobalRegister::SW); + m_global->setField("LVDSDrvSet12", cfg->LVDSDrvSet12 , GlobalRegister::SW); + m_global->setField("PlsrRiseUpTau", cfg->PlsrRiseUpTau , GlobalRegister::SW); + m_global->setField("PlsrPwr", cfg->PlsrPwr , GlobalRegister::SW); + m_global->setField("PlsrDelay", cfg->PlsrDelay , GlobalRegister::SW); + m_global->setField("ExtDigCalSW", cfg->ExtDigCalSW , GlobalRegister::SW); + m_global->setField("ExtAnaCalSW", cfg->ExtAnaCalSW , GlobalRegister::SW); + m_global->setField("Reg31Spare", cfg->Reg31Spare , GlobalRegister::SW); + m_global->setField("SELB0", cfg->SELB0 , GlobalRegister::SW); + m_global->setField("SELB1", cfg->SELB1 , GlobalRegister::SW); + m_global->setField("SELB2", cfg->SELB2 , GlobalRegister::SW); + m_global->setField("EfuseCref", cfg->EfuseCref , GlobalRegister::SW); + m_global->setField("Chip_SN", cfg->Chip_SN , GlobalRegister::SW); + + setVcalCoeff(0, config.FECalib.vcalCoeff[0]); + setVcalCoeff(1, config.FECalib.vcalCoeff[1]); + setVcalCoeff(2, config.FECalib.vcalCoeff[2]); + setVcalCoeff(3, config.FECalib.vcalCoeff[3]); + setCapVal(0, config.FECalib.cinjLo); + setCapVal(1, config.FECalib.cinjHi); + + + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + //Pixel DACs + m_pixel->setField(PixelRegister::tdac, j+1, i+1, config.FETrims.dacThresholdTrim[i][j]); + m_pixel->setField(PixelRegister::fdac, j+1, i+1, config.FETrims.dacFeedbackTrim[i][j]); + //Mask bits + m_pixel->setField(PixelRegister::enable, j+1, i+1, config.FEMasks[i][j]>>ipc::enable); + m_pixel->setField(PixelRegister::largeCap, j+1, i+1, config.FEMasks[i][j]>>ipc::largeCap); + m_pixel->setField(PixelRegister::smallCap, j+1, i+1, config.FEMasks[i][j]>>ipc::smallCap); + m_pixel->setField(PixelRegister::hitbus, j+1, i+1, config.FEMasks[i][j]>>ipc::hitbus); + } + } + // Configure the formatter + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + pt->put("HitDiscCnfg",cfg->HitDiscCnfg); + AbsFormatter* fmt=getFormatter(); + if(fmt){ + std::cout<<"%%%%%%%%% Configuring Formatter"<<std::endl; + fmt->configure(pt); + } + delete pt; + + std::cout<<"Configure done"<<std::endl; + //dumpConfig(); + return 0; +} + +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val){ + switchModeHW(FECommands::CONF); + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->writeRegisterHW(reg, val); +} + +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->readRegisterHW(reg, val); +} +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCclearPixelLatches(){ + SerialIF::setChannelInMask(1<<getInLink()); + // choose double column + m_global->setField("Colpr_Addr", 0, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 3, GlobalRegister::HW); // all columns + setupS0S1HitldHW(0, 0, 0); + setupGlobalPulseHW(GlobalRegister::SR_clr); //latch enable + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + //now clear latches + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + setupPixelStrobesHW(0x1fff); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + setupPixelStrobesHW(0);//clear register + setupGlobalPulseHW(0); //clear register + delete bs; + return 0; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv){ + // clear pixel latches + //IPCclearPixelLatches(); + //retv=new ipc::uvec; + //return 0; + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + + if(data.length()!=PixelRegister::DROW_WORDS)return BAD_SIZE; //wrong amount of data + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + + switchModeHW(FECommands::CONF); + + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)&data[0], retvec); + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs); //global pulse + delete bs; + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + } + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + if(dcol>=PixelRegister::N_COLS/2)return BAD_DCOL; + // set config mode + switchModeHW(FECommands::CONF); + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + SerialIF::send(bs); //global pulse + delete bs; + } + //shift out bits and refill with config register. + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)m_pixel->getDoubleColumn(bit, dcol), retvec); + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + +template <class TP> +void IPCFEI4AModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCFEI4AModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/pixelrce/config/FEI4/IPCFEI4AModule.hh b/rce/pixelrce/config/FEI4/IPCFEI4AModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..ee303b98c7a889bd090bf6ee42d6c882c3aeb350 --- /dev/null +++ b/rce/pixelrce/config/FEI4/IPCFEI4AModule.hh @@ -0,0 +1,32 @@ +#ifndef IPCFEI4AMODULE_HH +#define IPCFEI4AMODULE_HH + +#include "config/FEI4/FEI4AModule.hh" +#include "ipc/object.h" +#include "IPCFEI4AAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI4{ +template <class TP = ipc::single_thread> +class IPCFEI4AModule: public IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>, public FEI4::FEI4AModule { +public: + IPCFEI4AModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + ~IPCFEI4AModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelFEI4AConfig &config); + void IPCsetChipAddress(CORBA::ULong addr); + CORBA::ULong IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val); + CORBA::ULong IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val); + CORBA::ULong IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv); + CORBA::ULong IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv); + CORBA::ULong IPCclearPixelLatches(); + CORBA::Long IPCverifyModuleConfigHW(); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/pixelrce/config/FEI4/IPCFEI4BModule.cc b/rce/pixelrce/config/FEI4/IPCFEI4BModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..6d6f3d412eb0bfa5cf3c3a5f2d0ea2a80fde97b3 --- /dev/null +++ b/rce/pixelrce/config/FEI4/IPCFEI4BModule.cc @@ -0,0 +1,331 @@ +#ifndef FEI4__FEI4BIPCMODULE_CC +#define FEI4__FEI4BIPCMODULE_CC +#include "util/RceName.hh" +#include "config/FEI4/IPCFEI4BModule.hh" +#include "config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "HW/SerialIF.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + + +namespace FEI4{ + +template <class TP> +IPCFEI4BModule<TP>::IPCFEI4BModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI4BAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + FEI4BModule(name, id, inLink, outLink, fmt){ + // std::cout<<"IPCFEI4BModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCFEI4BModule<TP>::~IPCFEI4BModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCFEI4BModule<TP>::IPCsetChipAddress(CORBA::ULong addr){ + m_commands->setAddr(addr); +} +template <class TP> +CORBA::Long IPCFEI4BModule<TP>::IPCverifyModuleConfigHW(){ + return verifyModuleConfigHW(); +} +template <class TP> +CORBA::Long IPCFEI4BModule<TP>::IPCdownloadConfig(const ipc::PixelFEI4BConfig &config){ + // geographical address + m_gAddr=config.FECommand.address; + m_commands->setAddr(m_gAddr); + + const ipc::PixelFEI4BGlobal *cfg=&config.FEGlobal; + // global register + m_global->setField("TrigCnt", cfg->TrigCnt , GlobalRegister::SW); + m_global->setField("Conf_AddrEnable", cfg->Conf_AddrEnable , GlobalRegister::SW); + m_global->setField("Reg2Spare", cfg->Reg2Spare , GlobalRegister::SW); + m_global->setField("ErrMask0", cfg->ErrMask0 , GlobalRegister::SW); + m_global->setField("ErrMask1", cfg->ErrMask1 , GlobalRegister::SW); + m_global->setField("PrmpVbpRight", cfg->PrmpVbpRight , GlobalRegister::SW); + m_global->setField("BufVgOpAmp", cfg->BufVgOpAmp , GlobalRegister::SW); + m_global->setField("Reg6Spare", cfg->Reg6Spare , GlobalRegister::SW); + m_global->setField("PrmpVbp", cfg->PrmpVbp , GlobalRegister::SW); + m_global->setField("TdacVbp", cfg->TdacVbp , GlobalRegister::SW); + m_global->setField("DisVbn", cfg->DisVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbn", cfg->Amp2Vbn , GlobalRegister::SW); + m_global->setField("Amp2VbpFol", cfg->Amp2VbpFol , GlobalRegister::SW); + m_global->setField("Reg9Spare", cfg->Reg9Spare , GlobalRegister::SW); + m_global->setField("Amp2Vbp", cfg->Amp2Vbp , GlobalRegister::SW); + m_global->setField("FdacVbn", cfg->FdacVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbpf", cfg->Amp2Vbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnFol", cfg->PrmpVbnFol , GlobalRegister::SW); + m_global->setField("PrmpVbpLeft", cfg->PrmpVbpLeft , GlobalRegister::SW); + m_global->setField("PrmpVbpf", cfg->PrmpVbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnLcc", cfg->PrmpVbnLcc , GlobalRegister::SW); + m_global->setField("Reg13Spare", cfg->Reg13Spare , GlobalRegister::SW); + m_global->setField("PxStrobes", cfg->PxStrobes , GlobalRegister::SW); + m_global->setField("S0", cfg->S0 , GlobalRegister::SW); + m_global->setField("S1", cfg->S1 , GlobalRegister::SW); + m_global->setField("LVDSDrvIref", cfg->LVDSDrvIref , GlobalRegister::SW); + m_global->setField("GADCOpAmp", cfg->GADCOpAmp , GlobalRegister::SW); + m_global->setField("PllIbias", cfg->PllIbias , GlobalRegister::SW); + m_global->setField("LVDSDrvVos", cfg->LVDSDrvVos , GlobalRegister::SW); + m_global->setField("TempSensBias", cfg->TempSensBias , GlobalRegister::SW); + m_global->setField("PllIcp", cfg->PllIcp , GlobalRegister::SW); + m_global->setField("Reg17Spare", cfg->Reg17Spare , GlobalRegister::SW); + m_global->setField("PlsrIdacRamp", cfg->PlsrIdacRamp , GlobalRegister::SW); + m_global->setField("VrefDigTune", cfg->VrefDigTune , GlobalRegister::SW); + m_global->setField("PlsrVgOPamp", cfg->PlsrVgOPamp , GlobalRegister::SW); + m_global->setField("PlsrDacBias", cfg->PlsrDacBias , GlobalRegister::SW); + m_global->setField("VrefAnTune", cfg->VrefAnTune , GlobalRegister::SW); + m_global->setField("Vthin_AltCoarse", cfg->Vthin_AltCoarse , GlobalRegister::SW); + m_global->setField("Vthin_AltFine", cfg->Vthin_AltFine , GlobalRegister::SW); + m_global->setField("PlsrDAC", cfg->PlsrDAC , GlobalRegister::SW); + m_global->setField("DIGHITIN_Sel", cfg->DIGHITIN_Sel , GlobalRegister::SW); + m_global->setField("DINJ_Override", cfg->DINJ_Override , GlobalRegister::SW); + m_global->setField("HITLD_In", cfg->HITLD_In , GlobalRegister::SW); + m_global->setField("Reg21Spare", cfg->Reg21Spare , GlobalRegister::SW); + m_global->setField("Reg22Spare2", cfg->Reg22Spare2 , GlobalRegister::SW); + m_global->setField("Colpr_Addr", cfg->Colpr_Addr , GlobalRegister::SW); + m_global->setField("Colpr_Mode", cfg->Colpr_Mode , GlobalRegister::SW); + m_global->setField("Reg22Spare1", cfg->Reg22Spare1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg0", cfg->DisableColumnCnfg0 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg1", cfg->DisableColumnCnfg1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg2", cfg->DisableColumnCnfg2 , GlobalRegister::SW); + m_global->setField("TrigLat", cfg->TrigLat , GlobalRegister::SW); + m_global->setField("CMDcnt", cfg->CMDcnt , GlobalRegister::SW); + m_global->setField("StopModeCnfg", cfg->StopModeCnfg , GlobalRegister::SW); + m_global->setField("HitDiscCnfg", cfg->HitDiscCnfg , GlobalRegister::SW); + m_global->setField("EN_PLL", cfg->EN_PLL , GlobalRegister::SW); + m_global->setField("Efuse_sense", cfg->Efuse_sense , GlobalRegister::SW); + m_global->setField("Stop_Clk", cfg->Stop_Clk , GlobalRegister::SW); + m_global->setField("ReadErrorReq", cfg->ReadErrorReq , GlobalRegister::SW); + m_global->setField("Reg27Spare1", cfg->Reg27Spare1 , GlobalRegister::SW); + m_global->setField("GADC_Enable", cfg->GADC_Enable , GlobalRegister::SW); + m_global->setField("ShiftReadBack", cfg->ShiftReadBack , GlobalRegister::SW); + m_global->setField("Reg27Spare2", cfg->Reg27Spare2 , GlobalRegister::SW); + m_global->setField("GateHitOr", cfg->GateHitOr , GlobalRegister::SW); + m_global->setField("CalEn", cfg->CalEn , GlobalRegister::SW); + m_global->setField("SR_clr", cfg->SR_clr , GlobalRegister::SW); + m_global->setField("Latch_en", cfg->Latch_en , GlobalRegister::SW); + m_global->setField("SR_Clock", cfg->SR_Clock , GlobalRegister::SW); + m_global->setField("LVDSDrvSet06", cfg->LVDSDrvSet06 , GlobalRegister::SW); + m_global->setField("Reg28Spare", cfg->Reg28Spare , GlobalRegister::SW); + m_global->setField("EN40M", cfg->EN40M , GlobalRegister::SW); + m_global->setField("EN80M", cfg->EN80M , GlobalRegister::SW); + m_global->setField("CLK1", cfg->CLK1 , GlobalRegister::SW); + m_global->setField("CLK0", cfg->CLK0 , GlobalRegister::SW); + m_global->setField("EN160M", cfg->EN160M , GlobalRegister::SW); + m_global->setField("EN320M", cfg->EN320M , GlobalRegister::SW); + m_global->setField("Reg29Spare1", cfg->Reg29Spare1 , GlobalRegister::SW); + m_global->setField("no8b10b", cfg->no8b10b , GlobalRegister::SW); + m_global->setField("Clk2OutCnfg", cfg->Clk2OutCnfg , GlobalRegister::SW); + m_global->setField("EmptyRecord", cfg->EmptyRecord , GlobalRegister::SW); + m_global->setField("Reg29Spare2", cfg->Reg29Spare2 , GlobalRegister::SW); + m_global->setField("LVDSDrvEn", cfg->LVDSDrvEn , GlobalRegister::SW); + m_global->setField("LVDSDrvSet30", cfg->LVDSDrvSet30 , GlobalRegister::SW); + m_global->setField("LVDSDrvSet12", cfg->LVDSDrvSet12 , GlobalRegister::SW); + m_global->setField("TempSensDiodeSel", cfg->TempSensDiodeSel , GlobalRegister::SW); + m_global->setField("TempSensDisable", cfg->TempSensDisable , GlobalRegister::SW); + m_global->setField("IleakRange", cfg->IleakRange , GlobalRegister::SW); + m_global->setField("Reg30Spare", cfg->Reg30Spare , GlobalRegister::SW); + m_global->setField("PlsrRiseUpTau", cfg->PlsrRiseUpTau , GlobalRegister::SW); + m_global->setField("PlsrPwr", cfg->PlsrPwr , GlobalRegister::SW); + m_global->setField("PlsrDelay", cfg->PlsrDelay , GlobalRegister::SW); + m_global->setField("ExtDigCalSW", cfg->ExtDigCalSW , GlobalRegister::SW); + m_global->setField("ExtAnaCalSW", cfg->ExtAnaCalSW , GlobalRegister::SW); + m_global->setField("Reg31Spare", cfg->Reg31Spare , GlobalRegister::SW); + m_global->setField("GADCSel", cfg->GADCSel , GlobalRegister::SW); + m_global->setField("SELB0", cfg->SELB0 , GlobalRegister::SW); + m_global->setField("SELB1", cfg->SELB1 , GlobalRegister::SW); + m_global->setField("SELB2", cfg->SELB2 , GlobalRegister::SW); + m_global->setField("Reg34Spare1", cfg->Reg34Spare1 , GlobalRegister::SW); + m_global->setField("PrmpVbpMsnEn", cfg->PrmpVbpMsnEn , GlobalRegister::SW); + m_global->setField("Reg34Spare2", cfg->Reg34Spare2 , GlobalRegister::SW); + m_global->setField("Chip_SN", cfg->Chip_SN , GlobalRegister::SW); + m_global->setField("Reg1Spare", cfg->Reg1Spare , GlobalRegister::SW); + m_global->setField("SmallHitErase", cfg->SmallHitErase , GlobalRegister::SW); + m_global->setField("Eventlimit", cfg->Eventlimit , GlobalRegister::SW); + + setVcalCoeff(0, config.FECalib.vcalCoeff[0]); + setVcalCoeff(1, config.FECalib.vcalCoeff[1]); + setVcalCoeff(2, config.FECalib.vcalCoeff[2]); + setVcalCoeff(3, config.FECalib.vcalCoeff[3]); + setCapVal(0, config.FECalib.cinjLo); + setCapVal(1, config.FECalib.cinjHi); + + + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + //Pixel DACs + m_pixel->setField(PixelRegister::tdac, j+1, i+1, config.FETrims.dacThresholdTrim[i][j]); + m_pixel->setField(PixelRegister::fdac, j+1, i+1, config.FETrims.dacFeedbackTrim[i][j]); + //Mask bits + m_pixel->setField(PixelRegister::enable, j+1, i+1, config.FEMasks[i][j]>>ipc::enable); + m_pixel->setField(PixelRegister::largeCap, j+1, i+1, config.FEMasks[i][j]>>ipc::largeCap); + m_pixel->setField(PixelRegister::smallCap, j+1, i+1, config.FEMasks[i][j]>>ipc::smallCap); + m_pixel->setField(PixelRegister::hitbus, j+1, i+1, config.FEMasks[i][j]>>ipc::hitbus); + } + } + // Configure the formatter + AbsFormatter* fmt=getFormatter(); + if(fmt){ + std::cout<<"%%%%%%%%% Configuring Formatter"<<std::endl; + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + pt->put("HitDiscCnfg",cfg->HitDiscCnfg); + fmt->configure(pt); + delete pt; + } + + std::cout<<"Configure done"<<std::endl; + //dumpConfig(std::cout); + return 0; +} + +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val){ + switchModeHW(FECommands::CONF); + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->writeRegisterHW(reg, val); +} + +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->readRegisterHW(reg, val); +} +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCclearPixelLatches(){ + SerialIF::setChannelInMask(1<<getInLink()); + // choose double column + m_global->setField("Colpr_Addr", 0, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 3, GlobalRegister::HW); // all columns + setupS0S1HitldHW(0, 0, 0); + setupGlobalPulseHW(GlobalRegister::SR_clr); //latch enable + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + //now clear latches + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + setupPixelStrobesHW(0x1fff); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + setupPixelStrobesHW(0);//clear register + setupGlobalPulseHW(0); //clear register + delete bs; + return 0; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv){ + // clear pixel latches + //IPCclearPixelLatches(); + //retv=new ipc::uvec; + //return 0; + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + + if(data.length()!=PixelRegister::DROW_WORDS)return BAD_SIZE; //wrong amount of data + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + + switchModeHW(FECommands::CONF); + + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + m_global->setField("ShiftReadBack",0, GlobalRegister::HW); + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)&data[0], retvec); + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs); //global pulse + delete bs; + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + } + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + if(dcol>=PixelRegister::N_COLS/2)return BAD_DCOL; + // set config mode + switchModeHW(FECommands::CONF); + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + m_global->setField("ShiftReadBack",1, GlobalRegister::HW); //enable readback + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + SerialIF::send(bs); //global pulse + delete bs; + } + //shift out bits and refill with config register. + m_global->setField("ShiftReadBack",0, GlobalRegister::SW); //setupGlobalPulse does the HW write for that register + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)m_pixel->getDoubleColumn(bit, dcol), retvec); + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + +template <class TP> +void IPCFEI4BModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCFEI4BModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/pixelrce/config/FEI4/IPCFEI4BModule.hh b/rce/pixelrce/config/FEI4/IPCFEI4BModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..bac03f8c18c1bb2ddfc94e0c3ed09170c8cab872 --- /dev/null +++ b/rce/pixelrce/config/FEI4/IPCFEI4BModule.hh @@ -0,0 +1,32 @@ +#ifndef IPCFEI4BMODULE_HH +#define IPCFEI4BMODULE_HH + +#include "config/FEI4/FEI4BModule.hh" +#include "ipc/object.h" +#include "IPCFEI4BAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI4{ +template <class TP = ipc::single_thread> +class IPCFEI4BModule: public IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>, public FEI4::FEI4BModule { +public: + IPCFEI4BModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + ~IPCFEI4BModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelFEI4BConfig &config); + void IPCsetChipAddress(CORBA::ULong addr); + CORBA::ULong IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val); + CORBA::ULong IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val); + CORBA::ULong IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv); + CORBA::ULong IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv); + CORBA::ULong IPCclearPixelLatches(); + CORBA::Long IPCverifyModuleConfigHW(); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/pixelrce/config/IPCConfigIF.cc b/rce/pixelrce/config/IPCConfigIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..ac4ef551d3afee2125629f610d313dcccdb8d2c9 --- /dev/null +++ b/rce/pixelrce/config/IPCConfigIF.cc @@ -0,0 +1,140 @@ +#ifndef IPCCONFIGIF_CC +#define IPCCONFIGIF_CC + +#include "config/IPCConfigIF.hh" + +template <class TP> +IPCConfigIF<TP>::IPCConfigIF(IPCPartition & p, const char * name, ModuleFactory* mf): + IPCNamedObject<POA_ipc::IPCConfigIFAdapter, TP>( p, name ) , ConfigIF(mf){ + try { + IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCConfigIF<TP>::~IPCConfigIF(){ + try { + IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +//template <class TP> +//void IPCConfigIF<TP>::IPCsetupParameter(const char* name, CORBA::Long val){ +// setupParameter(name, val); +//} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCsetupParameter(const char* name, CORBA::Long val){ + setupParameter(name, val, false); //do not enable data taking because chip may be unconfigured + return 0; +} +template <class TP> +void IPCConfigIF<TP>::IPCsetupMaskStage(CORBA::Long stage){ + setupMaskStage(stage); +} +template <class TP> +void IPCConfigIF<TP>::IPCsendTrigger(){ + sendTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCenableTrigger(){ + enableTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCdisableTrigger(){ + disableTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCresetFE(){ + resetFE(); +} +template <class TP> +void IPCConfigIF<TP>::IPCconfigureModulesHW(){ + configureModulesHW(); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCverifyModuleConfigHW(CORBA::Long id){ + return verifyModuleConfigHW(id); +} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCwriteHWregister(CORBA::ULong addr, CORBA::ULong val){ + return writeHWregister(addr,val); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWregister(CORBA::ULong addr, CORBA::ULong& val){ + return readHWregister(addr, (unsigned int&)val); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCsendHWcommand(CORBA::Octet opcode){ + return sendHWcommand(opcode); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCwriteHWblockData(const ipc::blockdata& data){ + std::vector<unsigned> bldat; + for(size_t i=0;i<data.length();i++)bldat.push_back(data[i]); + return writeHWblockData(bldat); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWblockData(const ipc::blockdata& data, ipc::blockdata_out retv){ + std::vector<unsigned> bldat; + for(size_t i=0;i<data.length();i++)bldat.push_back(data[i]); + std::vector<unsigned> retvec; + unsigned retval=readHWblockData(bldat, retvec); + retv=new ipc::blockdata; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return retval; +} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWbuffers(ipc::chardata_out retv){ + std::vector<unsigned char> retvec; + unsigned retval=readHWbuffers(retvec); + retv=new ipc::chardata; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::Octet)retvec[i]; + return retval; +} + +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCnTrigger(){ + return nTrigger(); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCsetupTriggerIF(const char* type){ + setupTriggerIF(type); + return 0; +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCsetupModule(const char* name, const char* type, const ipc::ModSetup& par, const char* formatter){ + //std::cout<<"IPCsetupModule"<<std::endl; + return setupModule(name, type, par.id, par.inLink, par.outLink, formatter); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCdeleteModules(){ + deleteModules(); + return 0; +} +template <class TP> +void IPCConfigIF<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/pixelrce/config/IPCConfigIF.hh b/rce/pixelrce/config/IPCConfigIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..0b35ebe727c91904262812c2a3fac11be4b900d4 --- /dev/null +++ b/rce/pixelrce/config/IPCConfigIF.hh @@ -0,0 +1,41 @@ +#ifndef IPCCONFIGIF_HH +#define IPCCONFIGIF_HH + +#include "IPCConfigIFAdapter.hh" +#include "ipc/object.h" +#include "config/ConfigIF.hh" +#include "config/ModuleFactory.hh" +#include <omnithread.h> + +class IPCPartition; + +template <class TP = ipc::single_thread> +class IPCConfigIF: public IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>, public ConfigIF { +public: + IPCConfigIF(IPCPartition & p, const char * name, ModuleFactory* mf); + ~IPCConfigIF(); + void IPCsendTrigger(); + //void IPCsetupParameter(const char* name, CORBA::Long val); + CORBA::ULong IPCsetupParameter(const char* name, CORBA::Long val); + void IPCsetupMaskStage(CORBA::Long stage); + void IPCenableTrigger(); + void IPCdisableTrigger(); + void IPCresetFE(); + void IPCconfigureModulesHW(); + CORBA::Long IPCverifyModuleConfigHW(CORBA::Long id); + CORBA::ULong IPCwriteHWregister(CORBA::ULong addr, CORBA::ULong val); + CORBA::ULong IPCsendHWcommand(CORBA::Octet opcode); + CORBA::ULong IPCwriteHWblockData(const ipc::blockdata& data); + CORBA::ULong IPCreadHWblockData(const ipc::blockdata & data, ipc::blockdata_out retv); + CORBA::ULong IPCreadHWbuffers(ipc::chardata_out retv); + CORBA::ULong IPCreadHWregister(CORBA::ULong addr, CORBA::ULong &val); + CORBA::Long IPCdeleteModules(); + CORBA::Long IPCnTrigger(); + CORBA::Long IPCsetupTriggerIF(const char* type); + CORBA::Long IPCsetupModule(const char* name, const char* type, const ipc::ModSetup& par, const char* formatter); + void shutdown(); + +}; + + +#endif diff --git a/rce/pixelrce/config/IPCModuleFactory.cc b/rce/pixelrce/config/IPCModuleFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..0c95f8150ab9b3f97a1d2bc59f5745014608a924 --- /dev/null +++ b/rce/pixelrce/config/IPCModuleFactory.cc @@ -0,0 +1,116 @@ +#include "config/IPCModuleFactory.hh" +#include "config/FormatterFactory.hh" +#include "config/FEI3/Module.hh" +#include "config/FEI3/IPCModule.cc" +#include "config/FEI4/IPCFEI4AModule.cc" +#include "config/FEI4/IPCFEI4BModule.cc" +#include "config/hitbus/IPCModule.cc" +#include "config/afp-hptdc/IPCModule.cc" +#include "config/Trigger.hh" +#include "config/MultiTrigger.hh" +#include "config/EventFromFileTrigger.hh" +#include "config/MeasurementTrigger.hh" +#include "config/MultiShotTrigger.hh" +#include "config/HitorTrigger.hh" +#include "config/FEI4/TemperatureTrigger.hh" +#include "config/FEI4/MonleakTrigger.hh" +#include "config/FEI4/SNTrigger.hh" +#include "config/FEI4/Fei4RegisterTestTrigger.hh" +#include "util/exceptions.hh" +#include "stdio.h" +#include <iostream> + +IPCModuleFactory::IPCModuleFactory(IPCPartition& p):ModuleFactory(),m_partition(p){ + m_modulegroups.push_back(&m_modgroupi3); + m_modulegroups.push_back(&m_modgroupi4a); + m_modulegroups.push_back(&m_modgroupi4b); + m_modulegroups.push_back(&m_modgrouphitbus); + m_modulegroups.push_back(&m_modgroupafphptdc); +} + + +AbsModule* IPCModuleFactory::createModule(const char* name, const char* type, unsigned id, unsigned inLink, unsigned outLink, const char* formatter){ + FormatterFactory ff; + AbsFormatter* theformatter=ff.createFormatter(formatter, id); + if(std::string(type)=="FEI3"){ + FEI3::Module *mod= new FEI3::Module(name, id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI3_singleThread"){ + FEI3::Module *mod= new FEI3::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI3_multiThread"){ + FEI3::Module *mod= new FEI3::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4A_singleThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4AModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4a.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4A_multiThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4AModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4a.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4B_singleThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4BModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4b.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4B_multiThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4BModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4b.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_Hitbus_singleThread"){ + Hitbus::Module *mod= new Hitbus::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgrouphitbus.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_Hitbus_multiThread"){ + Hitbus::Module *mod= new Hitbus::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgrouphitbus.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_AFPHPTDC_singleThread"){ + afphptdc::Module *mod= new afphptdc::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupafphptdc.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_AFPHPTDC_multiThread"){ + std::cout<<"Adding module"<<std::endl; + afphptdc::Module *mod= new afphptdc::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + std::cout<<"Added module"<<std::endl; + m_modgroupafphptdc.addModule(mod); + return mod; + } + std::cout<<"Unknown module type "<<type<<std::endl; + rcecalib::Unknown_Module_Type issue; + throw issue; + return 0; +} + +AbsTrigger* IPCModuleFactory::createTriggerIF(const char* type, ConfigIF* cif){ + // std::cout << "Creating trigger of type " << type << std::endl; + if(std::string(type)=="default") return new FEI3::Trigger; + else if(std::string(type)=="FEI3")return new FEI3::Trigger; + else if(std::string(type)=="EventFromFile")return new EventFromFileTrigger; + else if(std::string(type)=="MultiShot")return new MultiShotTrigger; + else if(std::string(type)=="MultiTrigger")return new MultiTrigger; + else if(std::string(type)=="Hitor")return new HitorTrigger(cif); + else if(std::string(type)=="Temperature")return new FEI4::TemperatureTrigger; + else if(std::string(type)=="Monleak")return new FEI4::MonleakTrigger; + else if(std::string(type)=="SerialNumber")return new FEI4::SNTrigger; + else if(std::string(type)=="Fei4RegisterTest")return new FEI4::Fei4RegisterTestTrigger; +#ifdef __rtems__ + else if(std::string(type)=="Measurement")return new MeasurementTrigger; +#endif + char msg[128]; + printf("No Trigger type %s",type); + assert(0); +} diff --git a/rce/pixelrce/config/IPCModuleFactory.hh b/rce/pixelrce/config/IPCModuleFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..18d181308d8dfbd6faa982013681ac7656e78f43 --- /dev/null +++ b/rce/pixelrce/config/IPCModuleFactory.hh @@ -0,0 +1,32 @@ +#ifndef IPCMODULEFACTORY_HH +#define IPCMODULEFACTORY_HH + +#include "ipc/partition.h" + +#include "config/ModuleFactory.hh" +#include "config/FEI3/ModuleGroup.hh" +#include "config/FEI4/ModuleGroup.hh" +#include "config/hitbus/ModuleGroup.hh" +#include "config/afp-hptdc/ModuleGroup.hh" + +class ConfigIF; +class AbsFormatter; + +class IPCModuleFactory: public ModuleFactory { +public: + IPCModuleFactory(IPCPartition &p); + AbsModule* createModule(const char* name, const char* type, unsigned id, unsigned inpos, unsigned outPos, const char* formatter); + AbsFormatter* createFormatter(const char* formatter, int id); + AbsTrigger* createTriggerIF(const char* type, ConfigIF* cif); +private: + IPCPartition &m_partition; + FEI3::ModuleGroup m_modgroupi3; + FEI4::ModuleGroup m_modgroupi4a; + FEI4::ModuleGroup m_modgroupi4b; + Hitbus::ModuleGroup m_modgrouphitbus; + afphptdc::ModuleGroup m_modgroupafphptdc; + +}; + + +#endif diff --git a/rce/pixelrce/config/afp-hptdc/IPCModule.cc b/rce/pixelrce/config/afp-hptdc/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..612fc010b67dd349cc094b6362c74ae4323688d7 --- /dev/null +++ b/rce/pixelrce/config/afp-hptdc/IPCModule.cc @@ -0,0 +1,185 @@ +#ifndef AFPHPTDC__IPCMODULE_CC +#define AFPHPTDC__IPCMODULE_CC +#include "util/RceName.hh" +#include "config/afp-hptdc/IPCModule.hh" +#include "ipc/partition.h" +#include <boost/property_tree/ptree.hpp> +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace afphptdc{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::AFPHPTDCModuleConfig &config){ + setFpgaField("test", config.test); + setFpgaField("tdcControl", config.tdcControl); + setFpgaField("run", config.run); + setFpgaField("bypassLut", config.bypassLut); + setFpgaField("localClockEn", config.localClockEn); + setFpgaField("calClockEn", config.calClockEn); + setFpgaField("refEn", config.refEn); + setFpgaField("hitTestEn", config.hitTestEn); + setFpgaField("inputSel", config.inputSel); + setFpgaField("address", config.address); + setFpgaField("fanspeed", config.fanspeed); + setFpgaField("channelEn", config.channelEn); + + for(int i=0;i<3;i++){ + for (int j=31;j>=0;j--){ + char offs[32]; + sprintf(offs, "offset%d", j); + setTdcField(offs, i, config.offset[j][i]); + } + setTdcField("test_select", i, config.test_select[i]); + setTdcField("enable_error_mark", i, config.enable_error_mark[i]); + setTdcField("enable_error_bypass", i, config.enable_error_bypass[i]); + setTdcField("enable_error", i, config.enable_error[i]); + setTdcField("readout_single_cycle_speed", i, config.readout_single_cycle_speed[i]); + setTdcField("serial_delay", i, config.serial_delay[i]); + setTdcField("strobe_select", i, config.strobe_select[i]); + setTdcField("readout_speed_select", i, config.readout_speed_select[i]); + setTdcField("token_delay", i, config.token_delay[i]); + setTdcField("enable_local_trailer", i, config.enable_local_trailer[i]); + setTdcField("enable_local_header", i, config.enable_local_header[i]); + setTdcField("enable_global_trailer", i, config.enable_global_trailer[i]); + setTdcField("enable_global_header", i, config.enable_global_header[i]); + setTdcField("keep_token", i, config.keep_token[i]); + setTdcField("master", i, config.master[i]); + setTdcField("enable_bytewise", i, config.enable_bytewise[i]); + setTdcField("enable_serial", i, config.enable_serial[i]); + setTdcField("enable_jtag_readout", i, config.enable_jtag_readout[i]); + setTdcField("tdc_id", i, config.tdc_id[i]); + setTdcField("select_bypass_inputs", i, config.select_bypass_inputs[i]); + setTdcField("readout_fifo_size", i, config.readout_fifo_size[i]); + setTdcField("reject_count_offset", i, config.reject_count_offset[i]); + setTdcField("search_window", i, config.search_window[i]); + setTdcField("match_window", i, config.match_window[i]); + setTdcField("leading_resolution", i, config.leading_resolution[i]); + setTdcField("fixed_pattern", i, config.fixed_pattern[i]); + setTdcField("enable_fixed_pattern", i, config.enable_fixed_pattern[i]); + setTdcField("max_event_size", i, config.max_event_size[i]); + setTdcField("reject_readout_fifo_full", i, config.reject_readout_fifo_full[i]); + setTdcField("enable_readout_occupancy", i, config.enable_readout_occupancy[i]); + setTdcField("enable_readout_separator", i, config.enable_readout_separator[i]); + setTdcField("enable_overflow_detect", i, config.enable_overflow_detect[i]); + setTdcField("enable_relative", i, config.enable_relative[i]); + setTdcField("enable_automatic_reject", i, config.enable_automatic_reject[i]); + setTdcField("event_count_offset", i, config.event_count_offset[i]); + setTdcField("trigger_count_offset", i, config.trigger_count_offset[i]); + setTdcField("enable_set_counters_on_bunch_reset", i, config.enable_set_counters_on_bunch_reset[i]); + setTdcField("enable_master_reset_code", i, config.enable_master_reset_code[i]); + setTdcField("enable_master_reset_code_on_event_reset", i, config.enable_master_reset_code_on_event_reset[i]); + setTdcField("enable_reset_channel_buffer_when_separator", i, config.enable_reset_channel_buffer_when_separator[i]); + setTdcField("enable_separator_on_event_reset", i, config.enable_separator_on_event_reset[i]); + setTdcField("enable_separator_on_bunch_reset", i, config.enable_separator_on_bunch_reset[i]); + setTdcField("enable_direct_event_reset", i, config.enable_direct_event_reset[i]); + setTdcField("enable_direct_bunch_reset", i, config.enable_direct_bunch_reset[i]); + setTdcField("enable_direct_trigger", i, config.enable_direct_trigger[i]); + setTdcField("coarse_count_offset", i, config.coarse_count_offset[i]); + setTdcField("dll_tap_adjust3_0", i, config.dll_tap_adjust3_0[i]); + setTdcField("dll_tap_adjust7_4", i, config.dll_tap_adjust7_4[i]); + setTdcField("dll_tap_adjust11_8", i, config.dll_tap_adjust11_8[i]); + setTdcField("dll_tap_adjust15_12", i, config.dll_tap_adjust15_12[i]); + setTdcField("dll_tap_adjust19_16", i, config.dll_tap_adjust19_16[i]); + setTdcField("dll_tap_adjust23_20", i, config.dll_tap_adjust23_20[i]); + setTdcField("dll_tap_adjust27_24", i, config.dll_tap_adjust27_24[i]); + setTdcField("dll_tap_adjust31_28", i, config.dll_tap_adjust31_28[i]); + setTdcField("rc_adjust", i, config.rc_adjust[i]); + setTdcField("not_used", i, config.not_used[i]); + setTdcField("low_power_mode", i, config.low_power_mode[i]); + setTdcField("width_select", i, config.width_select[i]); + setTdcField("vernier_offset", i, config.vernier_offset[i]); + setTdcField("dll_control", i, config.dll_control[i]); + setTdcField("dead_time", i, config.dead_time[i]); + setTdcField("test_invert", i, config.test_invert[i]); + setTdcField("test_mode", i, config.test_mode[i]); + setTdcField("enable_trailing", i, config.enable_trailing[i]); + setTdcField("enable_leading", i, config.enable_leading[i]); + setTdcField("mode_rc_compression", i, config.mode_rc_compression[i]); + setTdcField("mode_rc", i, config.mode_rc[i]); + setTdcField("dll_mode", i, config.dll_mode[i]); + setTdcField("pll_control", i, config.pll_control[i]); + setTdcField("serial_clock_delay", i, config.serial_clock_delay[i]); + setTdcField("io_clock_delay", i, config.io_clock_delay[i]); + setTdcField("core_clock_delay", i, config.core_clock_delay[i]); + setTdcField("dll_clock_delay", i, config.dll_clock_delay[i]); + setTdcField("serial_clock_source", i, config.serial_clock_source[i]); + setTdcField("io_clock_source", i, config.io_clock_source[i]); + setTdcField("core_clock_source", i, config.core_clock_source[i]); + setTdcField("dll_clock_source", i, config.dll_clock_source[i]); + setTdcField("roll_over", i, config.roll_over[i]); + setTdcField("enable_matching", i, config.enable_matching[i]); + setTdcField("enable_pair", i, config.enable_pair[i]); + setTdcField("enable_ttl_serial", i, config.enable_ttl_serial[i]); + setTdcField("enable_ttl_control", i, config.enable_ttl_control[i]); + setTdcField("enable_ttl_reset", i, config.enable_ttl_reset[i]); + setTdcField("enable_ttl_clock", i, config.enable_ttl_clock[i]); + setTdcField("enable_ttl_hit", i, config.enable_ttl_hit[i]); + } + AbsFormatter* fmt=getFormatter(); + if(fmt){ + // configure the formatter with the calibration constants + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + for(int i=0;i<2;i++){ + for(int j=0;j<12;j++){ + for(int k=0;k<1024;k++){ + char name[32]; + sprintf(name, "c_%d_%d_%d", i, j, k); + pt->put(name, config.calib[i][j][k]); + } + } + } + std::cout<<"%%%%%%%%% Configuring HPTDC Formatter"<<std::endl; + fmt->configure(pt); + delete pt; + } + return 0; +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/pixelrce/config/afp-hptdc/IPCModule.hh b/rce/pixelrce/config/afp-hptdc/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..4ac7ed405f7cd1dd6bc85de9df2ce7e9d8d07bdb --- /dev/null +++ b/rce/pixelrce/config/afp-hptdc/IPCModule.hh @@ -0,0 +1,26 @@ +#ifndef IPCAFPHPTDCMODULE_HH +#define IPCAFPHPTDCMODULE_HH + +#include "config/afp-hptdc/Module.hh" +#include "ipc/object.h" +#include "AFPHPTDCModuleConfig.hh" +#include "IPCAFPHPTDCAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace afphptdc{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>, public afphptdc::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::AFPHPTDCModuleConfig &config); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/pixelrce/config/hitbus/IPCModule.cc b/rce/pixelrce/config/hitbus/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..164fb3be1de4e884f876194e65d73d66d327d9fe --- /dev/null +++ b/rce/pixelrce/config/hitbus/IPCModule.cc @@ -0,0 +1,74 @@ +#ifndef HITBUS__IPCMODULE_CC +#define HITBUS__IPCMODULE_CC +#include "util/RceName.hh" +#include "config/hitbus/IPCModule.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace Hitbus{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCHitbusAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::HitbusModuleConfig &config){ + setRegister("bpm", config.bpm); + setRegister("delay_tam1", config.delay_tam1); + setRegister("delay_tam2", config.delay_tam2); + setRegister("delay_tam3", config.delay_tam3); + setRegister("delay_tbm1", config.delay_tbm1); + setRegister("delay_tbm2", config.delay_tbm2); + setRegister("delay_tbm3", config.delay_tbm3); + setRegister("bypass_delay", config.bypass_delay); + setRegister("clock", config.clock); + setRegister("function_A", config.function_A); + setRegister("function_B", config.function_B); + std::cout<<"Configure done"<<std::endl; + return 0; +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/pixelrce/config/hitbus/IPCModule.hh b/rce/pixelrce/config/hitbus/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..d4fc9a3cd5a207b36200006c8b105416954b4ef3 --- /dev/null +++ b/rce/pixelrce/config/hitbus/IPCModule.hh @@ -0,0 +1,26 @@ +#ifndef IPCHITBUSMODULE_HH +#define IPCHITBUSMODULE_HH + +#include "config/hitbus/Module.hh" +#include "ipc/object.h" +#include "HitbusModuleConfig.hh" +#include "IPCHitbusAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace Hitbus{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>, public Hitbus::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::HitbusModuleConfig &config); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/pixelrce/idl/IPCAFPHPTDCAdapter.idl b/rce/pixelrce/idl/IPCAFPHPTDCAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..3a754bdb908eb8faef0c5d9876eb11e5505d73e6 --- /dev/null +++ b/rce/pixelrce/idl/IPCAFPHPTDCAdapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCAFPHPTDCADAPTER_IDL +#define IPCAFPHPTDCADAPTER_IDL + +#include <ipc/ipc.idl> +#include "AFPHPTDCModuleConfig.idl" + +module ipc +{ + interface IPCAFPHPTDCAdapter : ipc::servant + { + long IPCdownloadConfig(in AFPHPTDCModuleConfig config); + + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCConfigIFAdapter.idl b/rce/pixelrce/idl/IPCConfigIFAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..1f3e73505fea6b80bf8c5c84e6b4f6f6fc6ffc10 --- /dev/null +++ b/rce/pixelrce/idl/IPCConfigIFAdapter.idl @@ -0,0 +1,42 @@ +#ifndef IPCCONFIGIF_IDL +#define IPCCONFIGIF_IDL + +#include <ipc/ipc.idl> + +module ipc +{ + struct ModSetup{ + long id; + long inLink; + long outLink; + }; + + typedef sequence<unsigned long> blockdata; + typedef sequence<octet> chardata; + + interface IPCConfigIFAdapter : ipc::servant + { + oneway void IPCsendTrigger(); + //oneway void IPCsetupParameter(in string name, in long val); + unsigned long IPCsetupParameter(in string name, in long val); + oneway void IPCsetupMaskStage(in long stage); + oneway void IPCenableTrigger(); + oneway void IPCdisableTrigger(); + oneway void IPCresetFE(); + oneway void IPCconfigureModulesHW(); + unsigned long IPCwriteHWregister(in unsigned long addr, in unsigned long val); + unsigned long IPCreadHWregister(in unsigned long addr, out unsigned long val); + unsigned long IPCsendHWcommand(in octet opcode); + unsigned long IPCwriteHWblockData(in blockdata data); + unsigned long IPCreadHWblockData(in blockdata data, out blockdata retv); + unsigned long IPCreadHWbuffers(out chardata retv); + long IPCverifyModuleConfigHW(in long id); + long IPCdeleteModules(); + long IPCnTrigger(); + long IPCsetupTriggerIF(in string type); + long IPCsetupModule(in string name, in string type, in ModSetup par, in string formatter); + + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCFEI3Adapter.idl b/rce/pixelrce/idl/IPCFEI3Adapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..6305f3f3f7f0c83e6abc528e76476465822d0891 --- /dev/null +++ b/rce/pixelrce/idl/IPCFEI3Adapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCFEI3ADAPTER_IDL +#define IPCFEI3ADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelModuleConfig.idl" + +module ipc +{ + interface IPCFEI3Adapter : ipc::servant + { + long IPCdownloadConfig(in PixelModuleConfig config); + + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCFEI4AAdapter.idl b/rce/pixelrce/idl/IPCFEI4AAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..2ceb0576d16a88862740e7e3d2ef5b619708095f --- /dev/null +++ b/rce/pixelrce/idl/IPCFEI4AAdapter.idl @@ -0,0 +1,20 @@ +#ifndef IPCFEI4AADAPTER_IDL +#define IPCFEI4AADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelFEI4AConfig.idl" + +module ipc +{ + interface IPCFEI4AAdapter : ipc::servant + { + long IPCdownloadConfig(in PixelFEI4AConfig config); + oneway void IPCsetChipAddress(in unsigned long val); + unsigned long IPCwriteHWglobalRegister(in long reg, in unsigned short val); + unsigned long IPCreadHWglobalRegister(in long reg, out unsigned short val); + unsigned long IPCwriteDoubleColumnHW(in unsigned long bit, in unsigned long dcol, in uvec data, out uvec readback); + unsigned long IPCreadDoubleColumnHW(in unsigned long bit, in unsigned long dcol, out uvec readback); + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCFEI4BAdapter.idl b/rce/pixelrce/idl/IPCFEI4BAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..798e8b4cc33417db15cd01335ae3df31a8204a4c --- /dev/null +++ b/rce/pixelrce/idl/IPCFEI4BAdapter.idl @@ -0,0 +1,20 @@ +#ifndef IPCFEI4BADAPTER_IDL +#define IPCFEI4BADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelFEI4BConfig.idl" + +module ipc +{ + interface IPCFEI4BAdapter : ipc::servant + { + long IPCdownloadConfig(in PixelFEI4BConfig config); + oneway void IPCsetChipAddress(in unsigned long val); + unsigned long IPCwriteHWglobalRegister(in long reg, in unsigned short val); + unsigned long IPCreadHWglobalRegister(in long reg, out unsigned short val); + unsigned long IPCwriteDoubleColumnHW(in unsigned long bit, in unsigned long dcol, in uvec data, out uvec readback); + unsigned long IPCreadDoubleColumnHW(in unsigned long bit, in unsigned long dcol, out uvec readback); + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCHitbusAdapter.idl b/rce/pixelrce/idl/IPCHitbusAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..eb0ac8e8482ca4f7bb6c81df2d068fddc877a7c5 --- /dev/null +++ b/rce/pixelrce/idl/IPCHitbusAdapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCHITBUSADAPTER_IDL +#define IPCHITBUSADAPTER_IDL + +#include <ipc/ipc.idl> +#include "HitbusModuleConfig.idl" + +module ipc +{ + interface IPCHitbusAdapter : ipc::servant + { + long IPCdownloadConfig(in HitbusModuleConfig config); + + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCScanAdapter.idl b/rce/pixelrce/idl/IPCScanAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..ab7e3688f28b41174065c7707cf2f78120df8cf7 --- /dev/null +++ b/rce/pixelrce/idl/IPCScanAdapter.idl @@ -0,0 +1,21 @@ +#ifndef IPCSCANADAPTER_IDL +#define IPCSCANADAPTER_IDL + +#include <ipc/ipc.idl> +#include "ScanOptions.idl" + +module ipc +{ + interface IPCScanAdapter : ipc::servant + { + oneway void IPCstartScan(); + oneway void IPCpause(); + oneway void IPCresume(); + oneway void IPCwaitForData(); + oneway void IPCstopWaiting(); + long IPCgetStatus(); + oneway void IPCabort(); + }; +}; + +#endif diff --git a/rce/pixelrce/idl/IPCScanRootAdapter.idl b/rce/pixelrce/idl/IPCScanRootAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..a6e5d89715f3d8ac2c9e4ae90fbcd24c678c1251 --- /dev/null +++ b/rce/pixelrce/idl/IPCScanRootAdapter.idl @@ -0,0 +1,23 @@ +#ifndef IPCSCANROOTADAPTER_IDL +#define IPCSCANROOTADAPTER_IDL + +#include <ipc/ipc.idl> +#include "ScanOptions.idl" +#include "Callback.idl" + +module ipc +{ + typedef sequence<string> StringVect; + + interface IPCScanRootAdapter : ipc::servant + { + long IPCconfigureScan(in ScanOptions options); + StringVect IPCgetHistoNames(in string reg); + StringVect IPCgetPublishedHistoNames(); + unsigned long IPCnEvents(); + oneway void IPCresynch(); + oneway void IPCconfigureCallback(in Callback cb, in Priority pr); + }; +}; + +#endif diff --git a/rce/pixelrce/scanctrl/IPCRceCallback.cc b/rce/pixelrce/scanctrl/IPCRceCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..763b6545aa98f880b423a57dd8d053c492acdc42 --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCRceCallback.cc @@ -0,0 +1,35 @@ +#include "scanctrl/IPCRceCallback.hh" +#include <iostream> + +IPCRceCallback::IPCRceCallback(): RceCallback(){ +} + +void IPCRceCallback::configure(ipc::Callback_ptr cb, ipc::Priority pr){ + m_cb = ipc::Callback::_duplicate( cb ); + m_pr=pr; + m_configured=true; +} + +void IPCRceCallback::SendMsg(ipc::Priority pr, const ipc::CallbackParams *msg){ + if(m_configured){ + if(pr>=m_pr){ + try { + m_cb->notify( *msg ); + } + catch(...) { + std::cout << "callback : notification fails" << std::endl; + } + } + } +} +void IPCRceCallback::Shutdown(){ + if(m_configured){ + try { + m_cb->stopServer(); + } + catch(...) { + std::cout << "callback : notification fails" << std::endl; + } + m_configured=false; + } +} diff --git a/rce/pixelrce/scanctrl/IPCRceCallback.hh b/rce/pixelrce/scanctrl/IPCRceCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..96b64e11388c0d783239edbfd647fe59ee2a6d25 --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCRceCallback.hh @@ -0,0 +1,18 @@ +#ifndef IPCRCECALLBACK_HH +#define IPCRCECALLBACK_HH + +#include "scanctrl/RceCallback.hh" +#include <omnithread.h> + +class IPCRceCallback: public RceCallback{ +public: + IPCRceCallback(); + void SendMsg(ipc::Priority pr, const ipc::CallbackParams *msg); + void Shutdown(); + void configure( ipc::Callback_ptr cb, ipc::Priority pr); +private: + ipc::Callback_var m_cb; + +}; + +#endif diff --git a/rce/pixelrce/scanctrl/IPCScan.cc b/rce/pixelrce/scanctrl/IPCScan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8c1de989b619cf45d3cfafdc455c31fb8d5c585d --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCScan.cc @@ -0,0 +1,99 @@ +#ifndef IPCSCAN_CC +#define IPCSCAN_CC + +#include "scanctrl/IPCScan.hh" +#include "ers/ers.h" +#include "ipc/partition.h" +#include <boost/property_tree/ptree.hpp> + +#include <string> +#include <iostream> + + +template <class TP> +void* IPCScan<TP>::startScanStatic(void* arg){ + ((IPCScan<TP>*)arg)->startScan(); + return 0; +} + +template <class TP> +IPCScan<TP>::IPCScan(IPCPartition & p, const char * name): + IPCNamedObject<POA_ipc::IPCScanAdapter, TP>( p, name ) , + Scan() { + + try { + IPCNamedObject<POA_ipc::IPCScanAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + + + +template <class TP> +IPCScan<TP>::~IPCScan(){ + try { + IPCNamedObject<POA_ipc::IPCScanAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCScan<TP>::IPCpause(){ + std::cout<<"Pause"<<std::endl; + pause(); +} +template <class TP> +void IPCScan<TP>::IPCresume(){ + std::cout<<"Resume"<<std::endl; + resume(); +} +template <class TP> +void IPCScan<TP>::IPCabort(){ + std::cout<<"Abort"<<std::endl; + abort(); +} +template <class TP> +void IPCScan<TP>::IPCstartScan(){ + pthread_t mthread; + pthread_attr_t attr; + int ret; + // setting a new size + int stacksize = (PTHREAD_STACK_MIN + 0x20000); + pthread_attr_init(&attr); + ret=pthread_attr_setstacksize(&attr, stacksize); + pthread_create( &mthread, &attr , startScanStatic, this); + pthread_detach(mthread); + //startScan(); +} +template <class TP> +void IPCScan<TP>::IPCwaitForData(){ + waitForData(); +} +template <class TP> +void IPCScan<TP>::IPCstopWaiting(){ + stopWaiting(); +} +template <class TP> +CORBA::Long IPCScan<TP>::IPCgetStatus(){ + return getStatus(); +} + +template <class TP> +void IPCScan<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/pixelrce/scanctrl/IPCScan.hh b/rce/pixelrce/scanctrl/IPCScan.hh new file mode 100644 index 0000000000000000000000000000000000000000..ba2357a17be0da0c36f40c307b5a8ceb5e1f72fc --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCScan.hh @@ -0,0 +1,29 @@ +#ifndef IPCSCAN_HH +#define IPCSCAN_HH + +#include "scanctrl/Scan.hh" +#include "ipc/object.h" +#include "ScanOptions.hh" +#include "IPCScanAdapter.hh" + +class IPCPartition; + +template <class TP = ipc::single_thread> +class IPCScan: public IPCNamedObject<POA_ipc::IPCScanAdapter,TP>, public Scan { +public: + IPCScan(IPCPartition & p, const char * name); + ~IPCScan(); + void IPCpause(); + void IPCresume(); + void IPCwaitForData(); + void IPCstopWaiting(); + void IPCabort(); + void IPCstartScan(); + CORBA::Long IPCgetStatus(); + void shutdown(); + static void *startScanStatic(void *arg); + +}; + + +#endif diff --git a/rce/pixelrce/scanctrl/IPCScanRoot.cc b/rce/pixelrce/scanctrl/IPCScanRoot.cc new file mode 100644 index 0000000000000000000000000000000000000000..4ede2a25095a2fc32c5f457389fa35aab82e348d --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCScanRoot.cc @@ -0,0 +1,184 @@ +#ifndef IPCSCANROOT_CC +#define IPCSCANROOT_CC + +#include "scanctrl/IPCScanRoot.hh" +#include "ers/ers.h" +#include "ipc/partition.h" +#include <boost/property_tree/ptree.hpp> +#include "dataproc/AbsDataProc.hh" +#include "dataproc/AbsReceiver.hh" +#include "config/ConfigIF.hh" +#include "scanctrl/Scan.hh" +#include "util/HistoManager.hh" +#include "scanctrl/IPCRceCallback.hh" + +#include <string> +#include <iostream> + + +template <class TP> +IPCScanRoot<TP>::IPCScanRoot(IPCPartition & p, const char * name, ConfigIF* cif, Scan* scan): + IPCNamedObject<POA_ipc::IPCScanRootAdapter, TP>( p, name ) , ScanRoot(cif,scan), m_cb(new IPCRceCallback){ + try { + IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCScanRoot<TP>::~IPCScanRoot(){ + try { + IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCScanRoot<TP>::IPCconfigureScan(const ipc::ScanOptions &options){ + //PixScan::dump(options); + //std::cout<<"Start IPCScanRoot "<<std::endl; + //convert struct into property tree + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + //Top level + pt->put("Name",options.name); // scan name. Can be used as a file name, for example. + pt->put("scanType",options.scanType); // scan type. Determines what loop setup to use + pt->put("Receiver",options.receiver); + pt->put("DataHandler",options.dataHandler); + pt->put("DataProc",options.dataProc); + pt->put("Timeout.Seconds",options.timeout.seconds); + pt->put("Timeout.Nanoseconds",options.timeout.nanoseconds); + pt->put("Timeout.AllowedTimeouts",options.timeout.allowedTimeouts); + pt->put("runNumber", options.runNumber); + pt->put("stagingMode",options.stagingMode); + //maskStages is not used in NewDsp, only nMaskStages + pt->put("maskStages", options.maskStages); + pt->put("nMaskStages",options.nMaskStages); + pt->put("firstStage",options.firstStage); + pt->put("stepStage",options.stepStage); + pt->put("nLoops",options.nLoops); + //Loops + for(int i=0;i<options.nLoops;i++){ + char loopname[128]; + sprintf (loopname,"scanLoop_%d.",i); + pt->put(std::string(loopname)+"scanParameter", options.scanLoop[i].scanParameter); + pt->put(std::string(loopname)+"nPoints",options.scanLoop[i].nPoints); + pt->put(std::string(loopname)+"endofLoopAction.Action", options.scanLoop[i].endofLoopAction.Action); + pt->put(std::string(loopname)+"endofLoopAction.fitFunction", options.scanLoop[i].endofLoopAction.fitFunction); + pt->put(std::string(loopname)+"endofLoopAction.targetThreshold", options.scanLoop[i].endofLoopAction.targetThreshold); + if(options.scanLoop[i].dataPoints.length()>0){ + char pointname[10]; + for(unsigned int j=0;j<options.scanLoop[i].dataPoints.length();j++){ + sprintf(pointname,"P_%d",j); + pt->put(std::string(loopname)+"dataPoints."+pointname,options.scanLoop[i].dataPoints[j]); + } + } + } + //Trigger options + pt->put("trigOpt.nEvents",options.trigOpt.nEvents); + pt->put("trigOpt.triggerMask",options.trigOpt.triggerMask); + pt->put("trigOpt.moduleTrgMask",options.trigOpt.moduleTrgMask); + pt->put("trigOpt.triggerDataOn",options.trigOpt.triggerDataOn); + pt->put("trigOpt.deadtime",options.trigOpt.deadtime); + pt->put("trigOpt.nL1AperEvent",options.trigOpt.nL1AperEvent); + pt->put("trigOpt.nTriggersPerGroup",options.trigOpt.nTriggersPerGroup); + pt->put("trigOpt.nTriggers",options.trigOpt.nTriggers); + pt->put("trigOpt.Lvl1_Latency",options.trigOpt.Lvl1_Latency); + pt->put("trigOpt.Lvl1_Latency_Secondary",options.trigOpt.Lvl1_Latency_Secondary); + pt->put("trigOpt.strobeDuration",options.trigOpt.strobeDuration); + pt->put("trigOpt.strobeMCCDelay",options.trigOpt.strobeMCCDelay); + pt->put("trigOpt.strobeMCCDelayRange",options.trigOpt.strobeMCCDelayRange); + pt->put("trigOpt.CalL1ADelay",options.trigOpt.CalL1ADelay); + pt->put("trigOpt.eventInterval",options.trigOpt.eventInterval); + pt->put("trigOpt.injectForTrigger",options.trigOpt.injectForTrigger); + pt->put("trigOpt.vcal_charge",options.trigOpt.vcal_charge); + pt->put("trigOpt.threshold",options.trigOpt.threshold); + pt->put("trigOpt.hitbusConfig",options.trigOpt.hitbusConfig); + + // each option gets an entry in the tree below optionsMask with value 1 + for (unsigned int i=0;i<options.trigOpt.optionsMask.length();i++){ + pt->put(std::string("trigOpt.optionsMask.")+(const char*)options.trigOpt.optionsMask[i],1); + } + pt->put("trigOpt.triggerMode", options.trigOpt.triggerMode); + + // front-end options + pt->put("feOpt.phi",options.feOpt.phi); + pt->put("feOpt.totThresholdMode",options.feOpt.totThresholdMode); + pt->put("feOpt.totMinimum",options.feOpt.totMinimum); + pt->put("feOpt.totTwalk",options.feOpt.totTwalk); + pt->put("feOpt.totLeMode",options.feOpt.totLeMode); + pt->put("feOpt.hitbus",options.feOpt.hitbus); + + pt->put("nHistoNames",options.histos.length()); + if(options.histos.length()>0){ + char pointname[10]; + for(unsigned int j=0;j<options.histos.length();j++){ + sprintf(pointname,"Name_%d",j); + pt->put(std::string("HistoNames.")+pointname,options.histos[j]); + } + } + //Trigger options + //call the real initScan function + //std::cout<<"Calling ScanRoot "<<std::endl; + configureScan(pt); + delete pt; + return 0; +} + +template <class TP> +ipc::StringVect* IPCScanRoot<TP>::IPCgetHistoNames(const char* reg){ + std::vector<std::string> strvec=HistoManager::instance()->getHistoNames(reg); + ipc::StringVect &ipcstringvect=*new ipc::StringVect; + ipcstringvect.length(strvec.size()); + for(size_t i=0;i<strvec.size();i++){ + ipcstringvect[i]=CORBA::string_dup(strvec[i].c_str()); + } + return &ipcstringvect; +} +template <class TP> +ipc::StringVect* IPCScanRoot<TP>::IPCgetPublishedHistoNames(){ + std::vector<std::string> strvec=HistoManager::instance()->getPublishedHistoNames(); + ipc::StringVect &ipcstringvect=*new ipc::StringVect; + ipcstringvect.length(strvec.size()); + for(size_t i=0;i<strvec.size();i++){ + ipcstringvect[i]=CORBA::string_dup(strvec[i].c_str()); + } + return &ipcstringvect; +} + +template <class TP> +CORBA::ULong IPCScanRoot<TP>::IPCnEvents(){ + if(m_dataProc) + return m_dataProc->nEvents(); + else + return 0; +} +template <class TP> +void IPCScanRoot<TP>::IPCresynch(){ + if(m_receiver) + m_receiver->resynch(); +} + +template <class TP> +void IPCScanRoot<TP>::IPCconfigureCallback(ipc::Callback_ptr cb, ipc::Priority pr){ + m_cb->configure(cb,pr); +} + +template <class TP> +void IPCScanRoot<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/pixelrce/scanctrl/IPCScanRoot.hh b/rce/pixelrce/scanctrl/IPCScanRoot.hh new file mode 100644 index 0000000000000000000000000000000000000000..0704ccd7a20db0c0af0bab53e30471e10e20d17a --- /dev/null +++ b/rce/pixelrce/scanctrl/IPCScanRoot.hh @@ -0,0 +1,31 @@ +#ifndef IPCSCANROOT_HH +#define IPCSCANROOT_HH + +#include "scanctrl/ScanRoot.hh" +#include "ipc/object.h" +#include "ScanOptions.hh" +#include "IPCScanRootAdapter.hh" + +class IPCPartition; +class ConfigIF; +class Scan; +class IPCRceCallback; + +template <class TP = ipc::single_thread> +class IPCScanRoot: public IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>, public ScanRoot { +public: + IPCScanRoot(IPCPartition & p, const char * name, ConfigIF* cif, Scan* scan); + ~IPCScanRoot(); + CORBA::Long IPCconfigureScan(const ipc::ScanOptions &options); + ipc::StringVect* IPCgetHistoNames(const char* reg); + ipc::StringVect* IPCgetPublishedHistoNames(); + CORBA::ULong IPCnEvents(); + void IPCresynch(); + void IPCconfigureCallback(ipc::Callback_ptr cb, ipc::Priority pr); + void shutdown(); +private: + IPCRceCallback* m_cb; +}; + + +#endif diff --git a/rce/pixelrce/server/IPCCalibGui.cc b/rce/pixelrce/server/IPCCalibGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..0d3c696505b96594fc253a1da97cd70afaeab65e --- /dev/null +++ b/rce/pixelrce/server/IPCCalibGui.cc @@ -0,0 +1,54 @@ + +#include <ipc/partition.h> +#include <ipc/core.h> +#include "server/CalibGui.hh" +#include "server/IPCController.hh" +#include "server/IPCHistoController.hh" +#include <boost/program_options.hpp> +#include <TROOT.h> +#include <TStyle.h> +#include "TApplication.h" + +int main(int argc, char **argv){ + // + // Initialize command line parameters with default values + // + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Parse arguments +// + boost::program_options::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("partition,p", boost::program_options::value<std::string>(), "partition to work in."); + boost::program_options::variables_map vm; + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + if(vm.count("help")){ + std::cout<<desc<<std::endl; + exit(0); + } + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(vm.count("partition"))p_name=vm["partition"].as<std::string>().c_str(); + IPCPartition* partition=new IPCPartition(p_name ); + AbsController* controller=new IPCController(*partition); + AbsHistoController* hcontroller=new IPCHistoController(*partition); + //check if somebody else is using the partition + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + + TApplication theapp("app",&argc,argv); + new CalibGui(controller, hcontroller, gClient->GetRoot(),800,735); + theapp.Run(); + return 0; +} + diff --git a/rce/pixelrce/server/IPCCallback.hh b/rce/pixelrce/server/IPCCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..0d41d7ebfc48ec9b6fb949b7fae540617fa8c493 --- /dev/null +++ b/rce/pixelrce/server/IPCCallback.hh @@ -0,0 +1,30 @@ +#ifndef IPCCALLBACK_HH +#define IPCCALLBACK_HH + +#include "ipc/object.h" +#include "Callback.hh" +#include <boost/thread/mutex.hpp> + +class IPCCallback : public IPCObject<POA_ipc::Callback> +{ +public: + IPCCallback(): m_rce(0){} + void notify( const ipc::CallbackParams &msg )=0; + void stopServer()=0; + void addRce(){m_rce++;} + void stop(){ + boost::mutex::scoped_lock pl( m_mutex ); + m_cond.notify_one(); + } + void run(){ + boost::mutex::scoped_lock pl(m_mutex); + m_cond.wait(pl); + } + +protected: + int m_rce; + boost::mutex m_mutex; + boost::condition_variable m_cond; +}; + +#endif diff --git a/rce/pixelrce/server/IPCController.cc b/rce/pixelrce/server/IPCController.cc new file mode 100644 index 0000000000000000000000000000000000000000..ce5954ae7c2e68adacf586565d42174ac2ff53ec --- /dev/null +++ b/rce/pixelrce/server/IPCController.cc @@ -0,0 +1,851 @@ + +#include "server/IPCController.hh" +#include "server/IPCRegularCallback.hh" +#include "server/IPCGuiCallback.hh" +#include "server/PixScan.hh" +#include "IPCFEI3Adapter.hh" +#include "IPCFEI4AAdapter.hh" +#include "IPCFEI4BAdapter.hh" +#include "IPCHitbusAdapter.hh" +#include "IPCAFPHPTDCAdapter.hh" +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCScanRootAdapter.hh" +#include <is/infoT.h> +#include <is/infodictionary.h> +#include "ScanOptions.hh" +#include "ers/ers.h" +#include <stdio.h> +#include <string> + +IPCController::IPCController(IPCPartition &p):m_partition(p){} + +void IPCController::addRce(int rce){ + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)return; //RCE has already been added. + m_rces.push_back(rce); +} + + +void IPCController::downloadModuleConfig(int rce, int id, PixelConfig* config){ + config->downloadConfig(m_partition, rce, id); +} + +void IPCController::addModule(const char* name, const char* type, int id, int inLink, int outLink, int rce, const char* formatter){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + sprintf(cfa, "configIF_RCE%d",rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::ModSetup s; + s.id=id; + s.inLink=inLink; + s.outLink=outLink; + std::string typestring; + if(std::string(type)=="FEI3")typestring="IPC_FEI3_multiThread"; + else if(std::string(type)=="FEI4A")typestring="IPC_FEI4A_multiThread"; + else if(std::string(type)=="FEI4B")typestring="IPC_FEI4B_multiThread"; + else if(std::string(type)=="Hitbus")typestring="IPC_Hitbus_multiThread"; + else if(std::string(type)=="HPTDC")typestring="IPC_AFPHPTDC_multiThread"; + else(assert(0)); + handle -> IPCsetupModule( name,typestring.c_str(),s , formatter); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +int IPCController::setupTrigger(const char* type){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + return m_rces[i]+1000; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCsetupTriggerIF(type); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + return 0; +} + +void IPCController::removeAllModules(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCdeleteModules(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} +void IPCController::startScan(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCstartScan( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::abortScan(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCabort( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::stopWaitingForData(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCstopWaiting( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::getEventInfo(unsigned* nevent) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + sprintf(cfa, "configIF_RCE%d", m_rces[0]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + *nevent= handle -> IPCnTrigger(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} +int IPCController::verifyModuleConfigHW(int rce, int id) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + int retval=0; + sprintf(cfa, "configIF_RCE%d",rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + retval|=handle -> IPCverifyModuleConfigHW(id); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return retval; +} + +void IPCController::setupParameter(const char* par, int val) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCsetupParameter(par, val); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::setupMaskStage(int stage) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCsetupMaskStage(stage); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + + +void IPCController::downloadScanConfig(ipc::ScanOptions& options){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCconfigureScan(options); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::waitForScanCompletion(ipc::Priority pr, CallbackInfo* callb){ + IPCCallback *cb=new IPCGuiCallback(callb); + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCconfigureCallback(cb->_this(), pr ); + cb->addRce(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + cb->run(); + cb->_destroy(); +} +void IPCController::runScan(ipc::Priority pr, CallbackInfo* callb){ + IPCCallback *cb=new IPCGuiCallback(callb); + ipc::IPCScanRootAdapter_var rhandle; + ipc::IPCScanAdapter_var shandle; + char cfa[128]; + char cfb[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + sprintf(cfb, "scanCtrl_RCE%d", m_rces[i]); + try { + shandle = m_partition.lookup<ipc::IPCScanAdapter>( cfb ); + rhandle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + rhandle -> IPCconfigureCallback(cb->_this(), pr ); + cb->addRce(); + shandle->IPCstartScan(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + cb->run(); + cb->_destroy(); +} + +unsigned IPCController::getNEventsProcessed(){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + //maybe have to change if have multiple RCE's? + sprintf(cfa, "scanRoot_RCE%d", m_rces[0]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle -> IPCnEvents( ); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 0; +} + +void IPCController::resynch(){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + + for(size_t i=0;i<m_rces.size();i++){ + std::cout<<"IPCController sending resynch command to RCE "<<m_rces[i]<<std::endl; + + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCresynch( ); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + } + +} + +void IPCController::resetFE(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCresetFE(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::configureModulesHW(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCconfigureModulesHW(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +unsigned IPCController::writeHWglobalRegister(const char* name, int reg, unsigned short val){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return modhandle->IPCwriteHWglobalRegister(reg,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWglobalRegister(const char* name, int reg, unsigned short &val){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return modhandle->IPCreadHWglobalRegister(reg,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::writeHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> data, std::vector<unsigned> &retvec){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::uvec ipcdata; + ipc::uvec_var retv; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + unsigned stat= modhandle->IPCwriteDoubleColumnHW(bit, dcol, ipcdata, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::readHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> &retvec){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::uvec_var retv; + unsigned stat= modhandle->IPCreadDoubleColumnHW(bit, dcol, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::sendHWcommand(int rce, unsigned char opcode){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCsendHWcommand(opcode); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::writeHWregister(int rce, unsigned addr, unsigned val){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCwriteHWregister(addr,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWregister(int rce, unsigned addr, unsigned &val){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCreadHWregister((CORBA::ULong)addr,(CORBA::ULong&) val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::writeHWblockData(int rce, std::vector<unsigned>& data){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::blockdata ipcdata; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + return handle->IPCwriteHWblockData(ipcdata); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::readHWblockData(int rce, std::vector<unsigned>& data,std::vector<unsigned>& retvec ){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::blockdata ipcdata; + ipc::blockdata_var retv; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + unsigned stat= handle->IPCreadHWblockData(ipcdata, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWbuffers(int rce, std::vector<unsigned char>& retvec ){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::chardata_var retv; + unsigned nbuf= handle->IPCreadHWbuffers(retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return nbuf; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return (unsigned)-1; +} + +int IPCController::getScanStatus(){ + ipc::IPCScanAdapter_var handle; + int status=0; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + status|= handle->IPCgetStatus(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + return status; +} + +bool IPCController::guiRunning(){ + ISInfoDictionary dict(m_partition); + ISInfoInt gui_running(0); + try{ + dict.getValue("RceIsServer.GUI_running", gui_running); + }catch(daq::is::RepositoryNotFound){ + std::cout<<"RceIsServer not running in the partition"<<std::endl; + exit(0); + }catch(daq::is::InfoNotFound){ + //std::cout<<"No entry for GUI_running"<<std::endl; + } + return gui_running; +} +void IPCController::setGuiRunning(bool on){ + ISInfoDictionary dict(m_partition); + ISInfoInt gui_running(on); + dict.checkin("RceIsServer.GUI_running", gui_running); +} diff --git a/rce/pixelrce/server/IPCController.hh b/rce/pixelrce/server/IPCController.hh new file mode 100644 index 0000000000000000000000000000000000000000..21599ff3501a4267438fffac83e48bbdb5c977f7 --- /dev/null +++ b/rce/pixelrce/server/IPCController.hh @@ -0,0 +1,64 @@ +#ifndef IPCCONTROLLER_HH +#define IPCCONTROLLER_HH + +#include "ipc/partition.h" +#include "server/AbsController.hh" +#include "config/PixelConfig.hh" +#include "IPCScanRootAdapter.hh" +#include "IPCScanAdapter.hh" +#include <vector> +#include <map> + +class IPCCallback; +class CallbackInfo; +namespace ipc{ + class ScanOptions; +} + +class IPCController: public AbsController{ +public: + IPCController() {}; + IPCController(IPCPartition &p); + void addRce(int rce); + bool guiRunning(); + void setGuiRunning(bool on); + + void downloadModuleConfig(int rce, int id, PixelConfig* config); + void addModule(const char* name, const char* type, int id, int inLink, int outLink, int rce, const char* formatter); + int setupTrigger(const char* type="default"); + void removeAllModules(); + void resetFE(); + void configureModulesHW(); + + unsigned writeHWglobalRegister(const char* name, int reg, unsigned short val); + unsigned readHWglobalRegister(const char* name, int reg, unsigned short& val); + unsigned writeHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> data, std::vector<unsigned> &retvec); + unsigned readHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> &retvec); + + unsigned writeHWregister(int rce, unsigned addr, unsigned val); + unsigned readHWregister(int rce, unsigned addr, unsigned& val); + unsigned sendHWcommand(int rce, unsigned char opcode); + unsigned writeHWblockData(int rce, std::vector<unsigned> &data); + unsigned readHWblockData(int rce, std::vector<unsigned> &data, std::vector<unsigned>& retvec); + unsigned readHWbuffers(int rce, std::vector<unsigned char>& retvec); + + void downloadScanConfig(ipc::ScanOptions &scn); + int verifyModuleConfigHW(int rce, int id); + + void waitForScanCompletion(ipc::Priority pr, CallbackInfo* callb); + void runScan(ipc::Priority pr, CallbackInfo* callb); + void startScan(); + void abortScan(); + void stopWaitingForData(); + void getEventInfo(unsigned* nevent); + int getScanStatus(); + unsigned getNEventsProcessed(); + void resynch(); + void setupParameter(const char* par, int val); + void setupMaskStage(int stage); +private: + + IPCPartition m_partition; +}; + +#endif diff --git a/rce/pixelrce/server/IPCCosmicGui.cc b/rce/pixelrce/server/IPCCosmicGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..ace91aed835d9e9157d8abcf0d86267185f0a09e --- /dev/null +++ b/rce/pixelrce/server/IPCCosmicGui.cc @@ -0,0 +1,62 @@ + +#include <ipc/partition.h> +#include <ipc/core.h> +#include "server/CosmicGui.hh" +#include "server/IPCController.hh" +#include "util/HistoManager.hh" +#include "TApplication.h" +#include <TROOT.h> +#include <TStyle.h> +#include <boost/program_options.hpp> +#include <is/infoT.h> +#include <is/infodictionary.h> + +int main(int argc, char **argv){ + // + // Initialize command line parameters with default values + // + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + bool start; + boost::program_options::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("start,s", boost::program_options::value<bool>(&start)->default_value(false), "Start run when GUI comes up") + ("partition,p", boost::program_options::value<std::string>(), "partition to work in."); + boost::program_options::variables_map vm; + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + if(vm.count("help")){ + std::cout<<desc<<std::endl; + exit(0); + } + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(vm.count("partition"))p_name=vm["partition"].as<std::string>().c_str(); + try{ + IPCPartition p(p_name ); + IPCController controller(p); + AbsController &acontroller(controller); + new HistoManager(0); + + gROOT->SetStyle("Plain"); + TApplication theapp("app",&argc,argv); + new CosmicGui(acontroller, start, gClient->GetRoot(),800, 735); + theapp.Run(); + return 0; + }catch(...){ + std::cout<<"Partition "<<p_name<<" does not exist."<<std::endl; + exit(0); + } +} + + diff --git a/rce/pixelrce/server/IPCGuiCallback.cc b/rce/pixelrce/server/IPCGuiCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..cc1096153d37e7a815e00796c01b07640a16e865 --- /dev/null +++ b/rce/pixelrce/server/IPCGuiCallback.cc @@ -0,0 +1,29 @@ + +#include "server/IPCGuiCallback.hh" +#include "server/CallbackInfo.hh" + +void IPCGuiCallback::notify(const ipc::CallbackParams& msg){ + if(msg.status==ipc::SCANNING){ + m_cbinfo->setStage(msg.maskStage); + m_cbinfo->addToMask(CallbackInfo::NEWSTAGE); + std::cout<<"RCE "<<msg.rce<<": Mask Stage "<<msg.maskStage<<std::endl; + }else if(msg.status==ipc::FITTING){ + std::cout<<"RCE "<<msg.rce<<": Fitting"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::FIT); + }else if(msg.status==ipc::DOWNLOADING){ + std::cout<<"RCE "<<msg.rce<<": Downloading"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::DOWNLOAD); + }else if(msg.status==ipc::FAILED){ + m_cbinfo->addToMask(CallbackInfo::FAILED); + std::cout<<"RCE "<<msg.rce<<": Failed"<<std::endl; + } +} + +void IPCGuiCallback::stopServer(){ + m_rce--; + if(m_rce<=0){ + m_cbinfo->addToMask(CallbackInfo::STOP); + stop(); + } +} + diff --git a/rce/pixelrce/server/IPCGuiCallback.hh b/rce/pixelrce/server/IPCGuiCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..77e779b9ab9a31c087717e319b6faefea67ba71e --- /dev/null +++ b/rce/pixelrce/server/IPCGuiCallback.hh @@ -0,0 +1,18 @@ +#ifndef IPCGUICALLBACK_HH +#define IPCGUICALLBACK_HH + +#include "server/IPCCallback.hh" + +class CallbackInfo; + +class IPCGuiCallback : public IPCCallback { +public: + IPCGuiCallback(CallbackInfo* info): IPCCallback(),m_cbinfo(info){ + } + void notify( const ipc::CallbackParams & msg ); + void stopServer(); +private: + CallbackInfo* m_cbinfo; +}; + +#endif diff --git a/rce/pixelrce/server/IPCHistoController.cc b/rce/pixelrce/server/IPCHistoController.cc new file mode 100644 index 0000000000000000000000000000000000000000..dfe22e24cc78c64cbe64328e4190fa66a80df845 --- /dev/null +++ b/rce/pixelrce/server/IPCHistoController.cc @@ -0,0 +1,170 @@ + +#include "server/IPCHistoController.hh" +#include "IPCScanRootAdapter.hh" +#include "ers/ers.h" +#include <oh/OHIterator.h> +#ifdef TDAQ_RELEASE_4 +#include <oh/OHServerIterator.h> +#endif +#include <oh/OHRootReceiver.h> +#include <is/infodictionary.h> +#include "TH1D.h" +#include "TH2D.h" +#include "TH2C.h" +#include "TH2S.h" + +class HistoReceiver : public OHRootReceiver { +public: + void clearList(){ + m_list.clear(); + } + void receive( OHRootHistogram & h ) + { + m_list.push_back(h.histogram.get()); + h.histogram.release(); // we ask the histogram auto_ptr to drop ownership + // for the histogram since it will be kept by ROOT + } + std::vector<TH1*>& getHistos(){return m_list;} +private: + std::vector<TH1*> m_list; +}; + +IPCHistoController::IPCHistoController(IPCPartition &p):m_partition(p){} +void IPCHistoController::addRce(int rce){ + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)return; //RCE has already been added. + m_rces.push_back(rce); +} +void IPCHistoController::removeAllRces(){ + m_rces.clear(); +} + +std::vector<TH1*> IPCHistoController::getHistos(const char* reg){ + HistoReceiver hr; + try{ + OHHistogramIterator it( m_partition, "RceIsServer", ".*", reg); + while ( it++ ){ + it.retrieve( hr ); + if(hr.getHistos().back()!=0) + hr.getHistos().back()->SetName(it.name().c_str()); + } + }catch(daq::is::InvalidCriteria){ + std::cout<<"Invalid object"<<std::endl; + }catch(daq::is::RepositoryNotFound){ + std::cout<<"Object not found"<<std::endl; + }catch ( daq::ipc::InvalidPartition & ex ){ + std::cout<<"partition does not exist"<<std::endl; + }catch ( daq::is::Exception & ex ){ + std::cout<<"IS exception"<<std::endl; + }catch(...){ + std::cout<<"Something else went wrong"<<std::endl; + } + return hr.getHistos(); +} + +std::vector<std::string> IPCHistoController::getHistoNames(const char* reg){ + std::vector<std::string> retvect; + ipc::StringVect_var stringvect; + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + stringvect=handle -> IPCgetHistoNames(reg); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + + for(unsigned int i=0;i<stringvect->length();i++){ + retvect.push_back(std::string(stringvect[i])); + } + } + return retvect; +} + +std::vector<std::string> IPCHistoController::getPublishedHistoNames(){ + std::vector<std::string> retvect; + ipc::StringVect_var stringvect; + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + stringvect=handle -> IPCgetPublishedHistoNames(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + + for(unsigned int i=0;i<stringvect->length();i++){ + retvect.push_back(std::string(stringvect[i])); + } + } + return retvect; + } + + + +bool IPCHistoController::clear() +{ +#ifndef TDAQ_RELEASE_4 + ISInfoDictionary dict(m_partition); + try{ + dict.removeAll("RceIsServer", ~oh::Histogram::type() ); + } + catch( daq::is::Exception &ex){ + ers::error( ex ); + return false; + } + return true; +#else + try { + OHServerIterator sit( m_partition, "RceIsServer" ); + while ( sit++ ) { + try { + OHHistogramIterator hit(m_partition, sit.name(), ".*", ".*"); + if ( hit.entries() ) { + hit.removeAll(); + } + } catch( ers::Issue & ex ) { + ers::error( ex ); + return false; + } + } + } catch ( ers::Issue & ex ) { + ers::error( ex ); + return false; + } + + return true; +#endif +} + diff --git a/rce/pixelrce/server/IPCHistoController.hh b/rce/pixelrce/server/IPCHistoController.hh new file mode 100644 index 0000000000000000000000000000000000000000..df10265b967bc0ab57c59a54777e4ee49560ff25 --- /dev/null +++ b/rce/pixelrce/server/IPCHistoController.hh @@ -0,0 +1,30 @@ +#ifndef IPCHISTOCONTROLLER_HH +#define IPCHISTOCONTROLLER_HH + +#include "ipc/partition.h" +#include "IPCScanRootAdapter.hh" +#include "server/AbsHistoController.hh" +#include <vector> + +#include <TH1.h> + + +class IPCHistoController: public AbsHistoController{ +public: + IPCHistoController() {}; + IPCHistoController(IPCPartition &p); + + void addRce(int rce); + void removeAllRces(); + std::vector<TH1*> getHistos(const char* reg); + std::vector<std::string> getHistoNames(const char* reg); + std::vector<std::string> getPublishedHistoNames(); + + std::string getIPCPartitionName() { return m_partition.name(); } + + bool clear(); + + IPCPartition m_partition; +}; + +#endif diff --git a/rce/pixelrce/server/IPCRceOfflineProducer.cc b/rce/pixelrce/server/IPCRceOfflineProducer.cc new file mode 100644 index 0000000000000000000000000000000000000000..cb16288531d4e9313ce18fc78b51e820ce455cc8 --- /dev/null +++ b/rce/pixelrce/server/IPCRceOfflineProducer.cc @@ -0,0 +1,76 @@ +#include <ipc/core.h> +#include "server/RceOfflineProducer.hh" +#include "server/IPCController.hh" +#include "util/HistoManager.hh" +#include <boost/program_options.hpp> +#include <netdb.h> + + +int main ( int argc, char ** argv ) +{ + int rce; + std::string hostname; + boost::program_options::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("rce,r", boost::program_options::value<int>(&rce)->required(), "RCE to connect to") + ("runcontrol,d", boost::program_options::value<std::string>(&hostname)->required(), "Runcontrol hostname") + ("partition,p", boost::program_options::value<std::string>(), "partition to work in."); + boost::program_options::variables_map vm; + try{ + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + }catch(boost::program_options::error& e){ + std::cout<<std::endl<<"ERROR: "<<e.what()<<std::endl<<std::endl; + std::cout<<desc<<std::endl; + exit(0); + } + + if(vm.count("help")){ + std::cout<<desc<<std::endl; + exit(0); + } + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + std::string rchost; + hostent * ipAddrContainer = gethostbyname(hostname.c_str()); + if (ipAddrContainer != 0) { + int nBytes; + if (ipAddrContainer->h_addrtype == AF_INET) nBytes = 4; + else if (ipAddrContainer->h_addrtype == AF_INET6) nBytes = 6; + else { + std::cout << "Unrecognized IP address type. Run not started." + << std::endl; + exit(0); + } + std::stringstream ss("tcp://"); + ss << "tcp://"; + for (int i = 0, curVal; i < nBytes; i++) + { + curVal = static_cast<int>(ipAddrContainer->h_addr[i]); + if (curVal < 0) curVal += 256; + ss << curVal; + if (i != nBytes - 1) ss << "."; + } + ss<<":44000"; + rchost=ss.str(); + }else{ + std::cout<<"Bad IP address. Exiting."<<std::endl; + exit(0); + } + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(vm.count("partition"))p_name=vm["partition"].as<std::string>().c_str(); + IPCPartition p(p_name ); + IPCController controller(p); + new HistoManager(0); + RceOfflineProducer producer("RceOfflineProducer", rchost.c_str(), &controller, rce); + sleep(100000000); +} diff --git a/rce/pixelrce/server/IPCRegularCallback.cc b/rce/pixelrce/server/IPCRegularCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..ea0a12c291861190ab7e40d29589e581297754c2 --- /dev/null +++ b/rce/pixelrce/server/IPCRegularCallback.cc @@ -0,0 +1,19 @@ + +#include "server/IPCRegularCallback.hh" + +void IPCRegularCallback::notify(const ipc::CallbackParams& msg){ + if(msg.status==ipc::SCANNING){ + std::cout<<"RCE "<<msg.rce<<": Mask Stage "<<msg.maskStage<<std::endl; + }else if(msg.status==ipc::FITTING){ + std::cout<<"RCE "<<msg.rce<<": Fitting"<<std::endl; + } +} + +void IPCRegularCallback::stopServer(){ + m_rce--; + if(m_rce<=0){ + std::cout<<"Done"<<std::endl; + stop(); + } +} + diff --git a/rce/pixelrce/server/IPCRegularCallback.hh b/rce/pixelrce/server/IPCRegularCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..b9a9a5928187168cbd5e92b88d364ceb36c64304 --- /dev/null +++ b/rce/pixelrce/server/IPCRegularCallback.hh @@ -0,0 +1,13 @@ +#ifndef IPCREGULARCALLBACK_HH +#define IPCREGULARCALLBACK_HH + +#include "server/IPCCallback.hh" + +class IPCRegularCallback : public IPCCallback { +public: + IPCRegularCallback(): IPCCallback(){} + void notify( const ipc::CallbackParams & msg ); + void stopServer(); +}; + +#endif diff --git a/rce/pixelrce/server/IPClinux_server_pgp.cc b/rce/pixelrce/server/IPClinux_server_pgp.cc new file mode 100644 index 0000000000000000000000000000000000000000..0e3ae500074f57600802c2c61067acc553d016b7 --- /dev/null +++ b/rce/pixelrce/server/IPClinux_server_pgp.cc @@ -0,0 +1,104 @@ +// +// linux_server_pgp.cc +// +// IPC based calibration executable for Linux. +// +// Martin Kocian +///////////////////////////////////////////////////////////////////////////////// +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include "util/IPCProvider.hh" +#include "util/HistoManager.hh" +#include "scanctrl/IPCScan.cc" +#include "scanctrl/IPCScanRoot.cc" +#include "config/IPCConfigIF.cc" +#include "HW/SerialHexdump.hh" +#include "HW/SerialPgpFei4.hh" +#include "config/IPCModuleFactory.hh" +#include "util/RceName.hh" +#include "util/IsMonitoring.hh" +#include "scanctrl/Scan.hh" +#include "server/PgpModL.hh" +boost::mutex mutex; +boost::condition_variable cond; + + +void sig_handler( int sig ) +{ + std::cout << " :: [IPCServer::sigint_handler] the signal " << sig << " received - exiting ... "<<std::endl; + boost::mutex::scoped_lock pl( mutex ); + cond.notify_one(); +} + + +////////////////////////////////////////// +// +// Main function +// +////////////////////////////////////////// + + +int main ( int argc, char ** argv ) +{ + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + + signal( SIGINT , sig_handler ); + signal( SIGTERM, sig_handler ); + + + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + IPCPartition p((const char*)p_name); + + //Serial IF + PgpModL pgp; + pgp.open(); + //new SerialHexdump; + new SerialPgpFei4; + + new IsMonitoring(p, "RceIsServer", RceName::getRceNumber()); + + //Module Factory + + ModuleFactory *moduleFactory=new IPCModuleFactory(p); + + char name[128]; + sprintf(name, "configIF_RCE%d", RceName::getRceNumber()); + // Config IF + IPCConfigIF<ipc::single_thread> *cif=new IPCConfigIF<ipc::single_thread>(p, name, moduleFactory); + + sprintf(name, "scanCtrl_RCE%d", RceName::getRceNumber()); + IPCScan<ipc::multi_thread> *scan = new IPCScan<ipc::multi_thread>( p, name); + sprintf(name, "scanRoot_RCE%d", RceName::getRceNumber()); + IPCScanRoot<ipc::single_thread> * scanroot = new IPCScanRoot<ipc::single_thread>( p, name, (ConfigIF*)cif, (Scan*)scan); + + sprintf(name, "RCE%d", RceName::getRceNumber()); + Provider* ipcprov=new Provider(p,"RceIsServer", name); + new HistoManager(ipcprov); + // + std::cout << "ipc_test_server has been started." << std::endl; + + boost::mutex::scoped_lock pl(mutex); + cond.wait(pl); + std::cout << "Shutdown." << std::endl; + + cif->_destroy(); + scanroot->_destroy(); + scan->_destroy(); + + return 0; +} diff --git a/rce/pixelrce/server/IPCrebootHSIO.cc b/rce/pixelrce/server/IPCrebootHSIO.cc new file mode 100644 index 0000000000000000000000000000000000000000..61b78d2051af760aab1ba6db8b53986ff8df8feb --- /dev/null +++ b/rce/pixelrce/server/IPCrebootHSIO.cc @@ -0,0 +1,80 @@ + +#include <ipc/partition.h> +#include <ipc/core.h> +#include <ipc/object.h> +#include <boost/regex.hpp> +#include "server/IPCController.hh" +#include "IPCConfigIFAdapter.hh" + +#include <boost/program_options.hpp> +#include <iostream> +#include <stdlib.h> + +int main( int argc, char ** argv ){ + boost::program_options::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("partition,p", boost::program_options::value<std::string>(), "partition to work in."); + boost::program_options::variables_map vm; + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + if(vm.count("help")){ + std::cout<<desc<<std::endl; + exit(0); + } + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(vm.count("partition"))p_name=vm["partition"].as<std::string>().c_str(); + IPCPartition p(p_name ); + IPCController controller(p); + // How many RCEs are in the partition? + std::map< std::string, ipc::IPCConfigIFAdapter_var > objects; + std::vector<int> rces; + p.getObjects<ipc::IPCConfigIFAdapter>( objects ); + std::map< std::string, ipc::IPCConfigIFAdapter_var >::iterator it; + for ( it = objects.begin(); it != objects.end(); it++ ){ + boost::regex re("configIF_RCE(\\d+)"); + boost::cmatch matches; + if(boost::regex_search(it->first.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + rces.push_back(strtol(match.c_str(),0,10)); + } + } + if(rces.size()==0){ + std::cout<<"No RCE in your partition. Exiting."<<std::endl; + exit(0); + } + int rce=rces[0]; + if(rces.size()>1){ + std::cout<<"There are multiple RCEs in your partition:"<<std::endl; + while(1){ + for(size_t i=0;i<rces.size();i++)std::cout<<rces[i]<<std::endl; + std::cout<<"Which one has the HSIO attached that you would like to reboot (99 = all)?"<<std::endl; + std::cin>>rce; + bool valid=false; + for(size_t i=0;i<rces.size();i++)if(rce==99 || rce==rces[i])valid=true; + if(valid)break; + std::cout<<"This RCE is not on the list. Try again."<<std::endl; + } + } + for(size_t i=0;i<rces.size();i++){ + if(rce==99||rce==rces[i]){ + controller.addRce(rces[i]); + std::cout<<"Rebooting HSIO on RCE "<<rces[i]<<std::endl; + controller.sendHWcommand(rces[i],8); //reboot + } + } +} diff --git a/rce/pixelrce/util/IPCProvider.hh b/rce/pixelrce/util/IPCProvider.hh new file mode 100644 index 0000000000000000000000000000000000000000..b5497092e693538ea68cbf20cda63da11bddbfc9 --- /dev/null +++ b/rce/pixelrce/util/IPCProvider.hh @@ -0,0 +1,53 @@ +#ifndef PROVIDER_HH +#define PROVIDER_HH +#include "ipc/partition.h" +#include "oh/OHRawProvider.h" +#include "util/RceHistoAxis.hh" + +class OHBins; +template<class T> class OHRawProvider; + +class Provider { +public: + Provider(IPCPartition& p, const char* servername, const char* providername){ + m_provider=new OHRawProvider<>(p, servername, providername, 0); + } + ~Provider(){ + delete m_provider; + } + double dsw(float inval){ +#ifdef __rtems__ + return (double)inval; +#else + double invald=(double)inval; + unsigned long long iv=*(unsigned long long*)&invald; + unsigned long long ov=iv<<32 | iv>>32; + return *(double*)&ov; +#endif + } + template<class TC,class TE> + void publish(const std::string & name, + const std::string & title, + RceHistoAxis & xaxis, + const TC * bins, + const TE * errors, + bool hasOverflowAndUnderflow, + int tag , + const std::vector< std::pair<std::string,std::string> > & annotations) ; + template<class TC,class TE> + void publish(const std::string & name, + const std::string & title, + RceHistoAxis & xaxis, + RceHistoAxis & yaxis, + const TC * bins, + const TE * errors, + bool hasOverflowAndUnderflow, + int tag , + const std::vector< std::pair<std::string,std::string> > & annotations ) ; +private: + OHRawProvider<OHBins>* m_provider; +}; + +#include "util/IPCProvider.i" + +#endif diff --git a/rce/pixelrce/util/IPCProvider.i b/rce/pixelrce/util/IPCProvider.i new file mode 100644 index 0000000000000000000000000000000000000000..c6a82a2b63b7ff398d8cc76a7a9a688833fcc91c --- /dev/null +++ b/rce/pixelrce/util/IPCProvider.i @@ -0,0 +1,58 @@ +#ifndef PROVIDER_CC +#define PROVIDER_CC + + +template<class TC,class TE> +void +Provider::publish(const std::string & name, + const std::string & title, + RceHistoAxis & xaxis, + const TC * bins, + const TE * errors, + bool hasOverflowAndUnderflow, + int tag , + const std::vector< std::pair<std::string,std::string> > & annotations){ + OHAxis xaxisoh=OHMakeAxis<double>(xaxis.label().c_str(), xaxis.bincount(), dsw(xaxis.low()), dsw(xaxis.width()) ); + // Publish in OH + try { + m_provider->publish(name, title, xaxisoh, bins, errors, hasOverflowAndUnderflow, tag, annotations); + } catch (daq::oh::RepositoryNotFound) { + std::string mess = "The repository is not found "; + std::cout<<mess<<std::endl; + } catch (daq::oh::ObjectTypeMismatch) { + std::string mess = "Arguments invalid "; + std::cout<<mess<<std::endl; + } catch (...) { + std::string mess = "Unknown exception thrown "; + std::cout<<mess<<std::endl; + } +} + +template<class TC,class TE> +void +Provider::publish(const std::string & name, + const std::string & title, + RceHistoAxis & xaxis, + RceHistoAxis & yaxis, + const TC * bins, + const TE * errors, + bool hasOverflowAndUnderflow, + int tag, + const std::vector< std::pair<std::string,std::string> > & annotations ) { + OHAxis xaxisoh=OHMakeAxis<double>(xaxis.label().c_str(), xaxis.bincount(), dsw(xaxis.low()), dsw(xaxis.width()) ); + OHAxis yaxisoh=OHMakeAxis<double>(yaxis.label().c_str(), yaxis.bincount(), dsw(yaxis.low()), dsw(yaxis.width()) ); + try { + m_provider->publish(name, title, xaxisoh, yaxisoh, bins, errors, hasOverflowAndUnderflow, tag, annotations); + } catch (daq::oh::RepositoryNotFound) { + std::string mess = "The repository is not found "; + std::cout<<mess<<std::endl; + } catch (daq::oh::ObjectTypeMismatch) { + std::string mess = "Arguments invalid "; + std::cout<<mess<<std::endl; + } catch (...) { + std::string mess = "Unknown exception thrown "; + std::cout<<mess<<std::endl; + } +} + +#endif diff --git a/rce/projects.mk b/rce/projects.mk new file mode 100644 index 0000000000000000000000000000000000000000..43dc1696c2435b254e5b80c0d8706fe54c380185 --- /dev/null +++ b/rce/projects.mk @@ -0,0 +1,34 @@ +# List of projects (low level first) +projects := rtems +projects+= root +ifeq ($(RCE_CORE_VERSION),2.2) +projects+=tool +projects+=configuration +projects+=service +projects+=oldPpi +projects+=platform +else +projects+= rce +projects+= rceusr +projects+= rceapp +endif +projects+= rcecalib +projects+= rcedcs +rtems_use := $(RTEMS) +ifeq ($(RCE_CORE_VERSION),2.2) +tool_use:=$(RCE_CORE)/build/tool +configuration_use:=$(RCE_CORE)/build/configuration +service_use:=$(RCE_CORE)/build/service +oldPpi_use:=$(RCE_CORE)/build/oldPpi +platform_use+=$(RCE_CORE)/build/platform +else +rce_use := $(RCE_CORE)/build/rce +rceusr_use := $(RCE_CORE)/build/rceusr +rceapp_use := $(RCE_CORE)/build/rceapp +endif +rcecalib_use := release +rcedcs_use := release +root_use := $(ROOTSYS) + + + diff --git a/rce/rcecalib/HW/BitStream.hh b/rce/rcecalib/HW/BitStream.hh new file mode 100644 index 0000000000000000000000000000000000000000..8023f0f6316d9226a9b8bf0eb7fdd3ae8cf033ec --- /dev/null +++ b/rce/rcecalib/HW/BitStream.hh @@ -0,0 +1,22 @@ +#ifndef BITSTREAM_HH +#define BITSTREAM_HH + +#include <vector> + +typedef std::vector<unsigned> BitStream; + +class BitStreamUtils{ +public: + static void byteSwap(BitStream* bs){ + for (unsigned int i=0;i<bs->size();i++){ + unsigned tmp=(*bs)[i]; + (*bs)[i] = ((tmp&0xff)<<24) | ((tmp&0xff00)<<8) | + ((tmp&0xff0000)>>8) | ((tmp&0xff000000)>>24); + } + } + static void prependZeros(BitStream *bs, int num=4){ + for(int i=0;i<num;i++)bs->push_back(0); + } +}; + +#endif diff --git a/rce/rcecalib/HW/Headers.hh b/rce/rcecalib/HW/Headers.hh new file mode 100644 index 0000000000000000000000000000000000000000..daa46766ecb3cb4d1f41baacaf9b531573f529f7 --- /dev/null +++ b/rce/rcecalib/HW/Headers.hh @@ -0,0 +1,107 @@ +#include <new> + +namespace PgpTrans{ + + class PgpHeader { + public: + enum VChannel {VC0, VC1, VC2, VC3}; + PgpHeader() {} + PgpHeader(VChannel vc, unsigned dest, unsigned tid) {_data = (tid<<8) | + (dest&1)<<2 | vc;} + unsigned tid() const {return (_data&0xffffff00)>>8;} + VChannel vc() const {return (VChannel)(_data&0x3);} + unsigned const destination() {return ((_data&4)>>2);} + private: + unsigned _data; + }; + + class PgpHeaderSwapped { + public: + enum VChannel {VC0, VC1, VC2, VC3}; + PgpHeaderSwapped() {} + PgpHeaderSwapped(VChannel vc, unsigned dest, unsigned tid) {_data = (tid<<8) | + (dest&1)<<2 | vc;} + unsigned tid() const {return (_data&0xffffff00)>>24;} + VChannel vc() const {return (VChannel)((_data>>16)&0x3);} + unsigned const destination() {return (((_data>>16)&4)>>2);} + private: + unsigned _data; + }; + + class RegHeader { + public: + RegHeader() {} + enum Opcode {Read, Write, Set, Clear}; + RegHeader(unsigned address, Opcode oc) {_data = (oc<<30) | address;} + RegHeader(unsigned address, Opcode oc, unsigned writeData) { + new(this) RegHeader(address, oc); + data = writeData; + } + unsigned address() {return _data&0xffffff;} + Opcode opcode() {return (Opcode)((_data>>30)&0x3);} + unsigned timeout() {return _status&0x20000;} + unsigned fail() {return _status&0x10000;} + unsigned status() {return _status;} + private: + unsigned _data; + public: + unsigned data; + private: + unsigned _status; + }; + + class RegTxHeader { + public: + RegTxHeader() {} + PgpHeader pgpHeader; + RegHeader regHeader; + RegTxHeader(unsigned tid, unsigned addr, RegHeader::Opcode oc) : + pgpHeader(PgpHeader::VC1, 0, tid), regHeader(addr, oc) {} + RegTxHeader(unsigned tid, unsigned addr, RegHeader::Opcode oc, + unsigned data) { + new(this) RegTxHeader(tid, addr, oc); + regHeader.data=data; + } + }; + + class RegRxHeader { + public: + RegRxHeader() {} + PgpHeader pgpHeader; + RegHeader regHeader; + }; + class CmdHeader { + public: + CmdHeader() {} + CmdHeader( unsigned char oc) {_data = (unsigned)oc;} + unsigned char opcode() {return (unsigned char)(_data&0xff);} + private: + unsigned _data; + }; + + class CmdTxHeader { + public: + CmdTxHeader() {} + PgpHeader pgpHeader; + CmdHeader cmdHeader; + CmdTxHeader( unsigned char oc, unsigned tid=0) : + pgpHeader(PgpHeader::VC0, 0, tid), cmdHeader(oc) {} + }; + class BlockWriteHeader{ + public: + BlockWriteHeader(bool handshake){ + _data= handshake ? 1: 0; + } + private: + unsigned _data; + }; + class BlockWriteTxHeader { + public: + PgpHeader pgpHeader; + BlockWriteHeader blockHeader; + BlockWriteTxHeader(bool handshake ) : + pgpHeader(PgpHeader::VC3, 0, 0),blockHeader(handshake){} + }; + +} + diff --git a/rce/rcecalib/HW/Makefile b/rce/rcecalib/HW/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/rcecalib/HW/Makefile @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/rcecalib/HW/RCDImaster.cc b/rce/rcecalib/HW/RCDImaster.cc new file mode 100644 index 0000000000000000000000000000000000000000..3dc84e91272a3af318a98b84f001a132e62b7e4b --- /dev/null +++ b/rce/rcecalib/HW/RCDImaster.cc @@ -0,0 +1,344 @@ +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, pic, Tds.hh) +#include DAT_PUBLIC( oldPpi, pic, Pool.hh) +#include DAT_PUBLIC( oldPpi, pgp, Driver.hh) +#include DAT_PUBLIC( oldPpi, pgp, DriverList.hh) +#include DAT_PUBLIC( service, fci, Exception.hh) +#else +#include "rce/pic/Tds.hh" +#include "rce/pgp/Driver.hh" +#include "rce/pgp/DriverList.hh" +#include "rce/service/Exception.hh" +#include "rce/pic/Pool.hh" +#endif +#include "RCDImaster.hh" +#include "Headers.hh" +#include "Receiver.hh" +#include <stdio.h> +#include <assert.h> +#include <iostream> + +using namespace PgpTrans; + +RCDImaster* RCDImaster::_instance=0; +omni_mutex RCDImaster::_guard; + +RCDImaster* RCDImaster::instance(){ + if( ! _instance){ + omni_mutex_lock ml(_guard); + if( ! _instance){ + _instance=new RCDImaster; + } + } + return _instance; +} + + + +RCDImaster::RCDImaster():_pgp_driver(0),_receiver(0),_pool(0), + _tid(0),_data_cond(&_data_mutex), + _status(0), _data(0), _handshake(false),_blockread(false){ + try { + const RcePic::Params Tx = { + RcePic::NonContiguous, + 16, // Header + 64*132, // Payload + 32 // Number of buffers + }; + + RcePic::Pool * pool = new RcePic::Pool::Pool(Tx); + RcePgp::DriverList * driverList = RcePgp::DriverList::instance(); + setPool(pool); // tell the handler so it can put back the buffers + RcePgp::Driver * pgpd = 0; + for (int i=0;i<4;i++){ + pgpd=driverList->handler(static_cast<RcePgp::port_number_t>(i), this); + } + pgpd=driverList->lookup(static_cast<RcePgp::port_number_t>(0)); + if (!pgpd){ + printf("serialPorts: Could not find the driver\n"); + assert(0); + } + setDriver(pgpd); + rtems_task_wake_after(10); // hack wait for initialization to complete + } catch (RceSvc::Exception& e) { + printf("*** rce exception %s", e.what()); + } catch (std::exception& e) { + printf("*** c++ exception %s", e.what()); + } + //printf("Handler %p\n",this); + m_counter=0; + +} + + + +void RCDImaster::setPool(RcePic::Pool *p){_pool=p;} + +void RCDImaster::setDriver(RcePgp::Driver *pgpd){_pgp_driver=pgpd;} + +void RCDImaster::setReceiver(Receiver* receiver){_receiver=receiver;} +Receiver* RCDImaster::receiver(){return _receiver;} + +unsigned int RCDImaster::writeRegister(unsigned address, unsigned value){ + // std::cout<<"Register write address "<<address<<" value "<<value<<std::endl; + //std::cout<<"RCDImaster"<<std::endl; + RcePic::Tds* tds=_pool->allocate(); + assert (tds!=0); + _tid++; + new(tds->header())RegTxHeader(_tid,address, RegHeader::Write, value); + tds->payloadsize(0); + // printf("Write register\n"); + omni_mutex_lock pl( _data_mutex ); + _pgp_driver->post(tds,RcePgp::Driver::Contiguous,RcePgp::Driver::DoNotComplete); + //printf("P %d",_pgp_driver->port_number()); + //printf("b\n"); + //printf("Posted \n"); + unsigned long abs_sec,abs_nsec; + omni_thread::get_time(&abs_sec,&abs_nsec,0,RECEIVETIMEOUT); + int signalled=_data_cond.timedwait(abs_sec,abs_nsec); + if(signalled==0){ //timeout. Something went wrong with the data. + printf("PGP Write Register: No reply from front end.\n"); + _pool->deallocate(tds); + return RECEIVEFAILED; + } + //printf("Status %d\n",stat); + //printf("a\n"); + //printf("Write register done\n"); + _pool->deallocate(tds); + return _status; +} +unsigned int RCDImaster::blockWrite(RcePic::Tds* tds){ + _pgp_driver->post(tds,RcePgp::Driver::NonContiguous,RcePgp::Driver::DoNotComplete); + return 0; +} + +unsigned int RCDImaster::blockWrite(unsigned* data, int size, bool handshake,bool byteswap){ + //printf("Size %d\n",size); + RcePic::Tds* tds=_pool->allocate(); + assert (tds!=0); + char* header=(char*)tds->header(); + int headersize=tds->headersize(); + for (int i=0;i<headersize;i++)header[i]=0; + new(tds->header())BlockWriteTxHeader(handshake); + unsigned* payload=(unsigned*)tds->payload(); + for(int i=0;i<size;i++){ +#ifdef SWAP_DATA +#warning Swapping of data turned on + if(byteswap) + payload[i]= ((data[i]&0xff)<<8) | ((data[i]&0xff00)>>8) | + ((data[i]&0xff0000)<<8) | ((data[i]&0xff000000)>>8); + else + payload[i]=data[i]<<16 | data[i]>>16; +#else + if(byteswap) + payload[i]= ((data[i]&0xff)<<24) | ((data[i]&0xff00)<<8) | + ((data[i]&0xff0000)>>8) | ((data[i]&0xff000000)>>24); + else{ + payload[i]=data[i]; + // std::cout<<"data "<<data[i]<<std::endl; + } +#endif + } + tds->payloadsize(size*sizeof(unsigned)); + tds->flush(true); + _handshake=handshake; + //printf("Posting config data\n"); + if(handshake){ + _data_mutex.lock(); + //m_timer.Start(); + } + //else { + // m_timer.Start(); + // m_counter=0; + //} + _pgp_driver->post(tds,RcePgp::Driver::NonContiguous,RcePgp::Driver::DoNotComplete); + if(handshake){ + unsigned long abs_sec,abs_nsec; + omni_thread::get_time(&abs_sec,&abs_nsec,0,RECEIVETIMEOUT); + int signalled=_data_cond.timedwait(abs_sec,abs_nsec); + _data_mutex.unlock(); + if(signalled==0){ //timeout. Something went wrong with the data. + std::cout<<"PGP Block R/W: No reply from frontend."<<std::endl; + _pool->deallocate(tds); + return RECEIVEFAILED; + } + } + _pool->deallocate(tds); + //printf("Done posting config data\n"); + return 0; +} + +unsigned int RCDImaster::blockRead(unsigned* data, int size, std::vector<unsigned>& retvec){ + _blockread=true; + blockWrite(data,size,true,false); + _blockread=false; + if(nBuffers()!=0){ + unsigned char *header, *payload; + unsigned headerlen, payloadlen; + currentBuffer(header, headerlen, payload, payloadlen); + payloadlen/=sizeof(unsigned); + unsigned* ptr=(unsigned*)payload; + for(unsigned i=0;i<payloadlen;i++) retvec.push_back(*ptr++); + discardCurrentBuffer(); + } + return 0; +} +unsigned int RCDImaster::readBuffers(std::vector<unsigned char>& retvec){ + unsigned char *header, *payload; + unsigned headerlen, payloadlen; + unsigned count=0; + while(nBuffers()!=0){ + count++; + currentBuffer(header, headerlen, payload, payloadlen); + for(unsigned i=0;i<payloadlen;i++) retvec.push_back(payload[i]); + if(payloadlen%3!=0){ + retvec.push_back(0); + if(payloadlen%3==1) retvec.push_back(0); + } + discardCurrentBuffer(); + } + return count; +} + +unsigned int RCDImaster::readRegister(unsigned address, unsigned &value){ + RcePic::Tds* tds=_pool->allocate(); + _tid++; + if(_tid>0xffffff)_tid=0; + new(tds->header())RegTxHeader(_tid,address, RegHeader::Read); + tds->payloadsize(0); + // printf("Read register tid=%d\n",_tid); + omni_mutex_lock pl( _data_mutex ); + _pgp_driver->post(tds,RcePgp::Driver::Contiguous,RcePgp::Driver::DoNotComplete); + unsigned long abs_sec,abs_nsec; + omni_thread::get_time(&abs_sec,&abs_nsec,0,RECEIVETIMEOUT); + int signalled=_data_cond.timedwait(abs_sec,abs_nsec); + if(signalled==0){ //timeout. Something went wrong with the data. + printf("PGP Read Register: No reply from frontend.\n"); + _pool->deallocate(tds); + return RECEIVEFAILED; + } + value=_data; + //printf("Read register done tid=%d\n",_tid); + _pool->deallocate(tds); + return _status; +} + +unsigned int RCDImaster::sendCommand(unsigned char opcode, unsigned context){ + // if(opcode==111){ + // m_timer.Print("RCDImaster"); + // m_timer.Reset(); + // return 0; + //} + RcePic::Tds* tds=_pool->allocate(); + new(tds->header())CmdTxHeader(opcode, context&0xffffff ); + tds->payloadsize(0); + _pgp_driver->post(tds,RcePgp::Driver::Contiguous,RcePgp::Driver::DoNotComplete); + _pool->deallocate(tds); + return 0; +} + +unsigned RCDImaster::transferred(RcePic::Tds* tds) { + return ((unsigned*)tds->result())[1]; +} + +void RCDImaster::completed(RcePic::Tds *tds, RcePgp::Driver* pgpd) +{ + // if(tds->edw()!=0)printf("Completion error %d\n",tds->edw()); + // _pool->deallocate(tds); +} +//int ibuf=0; +void RCDImaster::received(RcePic::Tds *tds, RcePgp::Driver *pgpd){ + PgpHeader *pgpheader=(PgpHeader*)tds->header(); + if (pgpheader->vc()==1 && pgpheader->destination()==0){ // Register + //std::cout<<"Register"<<std::endl; + RegRxHeader* rxheader= (RegRxHeader*)tds->header(); + unsigned tid=rxheader->pgpHeader.tid(); + if(tid!=_tid){ + printf ("Bad tid\n"); + } + _status=rxheader->regHeader.status(); + _data=rxheader->regHeader.data; + if (rxheader->regHeader.fail()){ + printf("Register operation failed\n"); + } else if (rxheader->regHeader.timeout()){ + printf("Register operation timed out\n"); + } + pgpd->release(tds,true); + omni_mutex_lock pl( _data_mutex ); + _data_cond.signal(); + } else if (pgpheader->vc()==0 && pgpheader->destination()==0){ // data + //std::cout<<"Data"<<std::endl; + if(_receiver!=NULL && _blockread==false){ + // if(_handshake==false){ + PgpData pgpdata; + pgpdata.header=(unsigned char*)tds->header(); + pgpdata.payload=(unsigned*)tds->payload(); + unsigned size=transferred(tds); + const unsigned headersize=8; + pgpdata.payloadSize=size/sizeof(unsigned)- headersize; + if(size%4!=0)std::cout<<"PGP Data size not a multiple of 32 bit."<<std::endl; + _receiver->receive(&pgpdata); + // m_counter++; + //if(m_counter==16){ + // m_timer.Stop(); + //} + //} + // printf("%d Did not release buffer\n",ibuf++); + pgpd->release(tds,true); + }else{ + _buffers.push_back(tds); + } + if(_handshake){ + _handshake=false; + omni_mutex_lock pl( _data_mutex ); + _data_cond.signal(); + } + }else{ + printf("Received message with vc = %d dest = %d\n",pgpheader->vc(),pgpheader->destination()); + //assert(0); + omni_mutex_lock pl( _data_mutex ); + _data_cond.signal(); + } +} + +unsigned RCDImaster::nBuffers(){ + return _buffers.size(); +} + +int RCDImaster::currentBuffer(unsigned char*& header, unsigned &headerSize, unsigned char*&payload, unsigned &payloadSize){ + int retval=1; + if(_buffers.empty()){ + header=0; + headerSize=0; + payload=0; + payloadSize=0; + retval=1; + }else{ + RcePic::Tds *tds=*_buffers.begin(); + header=(unsigned char*)tds->header(); + headerSize=tds->headersize(); + payload=(unsigned char*)tds->payload(); + payloadSize=transferred(tds)-headerSize; + retval=0; + } + return retval; +} + +int RCDImaster::discardCurrentBuffer(){ + int retval=1; + if(_buffers.empty()){ + retval=1; + }else{ + RcePic::Tds *tds=*_buffers.begin(); + _pgp_driver->release(tds,true); + _buffers.pop_front(); + retval=0; + } + return retval; +} + + + + + diff --git a/rce/rcecalib/HW/RCDImaster.hh b/rce/rcecalib/HW/RCDImaster.hh new file mode 100644 index 0000000000000000000000000000000000000000..6e566f03bb9414a529f83f1f323e5dbb7db8171f --- /dev/null +++ b/rce/rcecalib/HW/RCDImaster.hh @@ -0,0 +1,72 @@ +// +// Implements the master RCDI interface +// +// Martin Kocian, SLAC, 6/6/2009 +// + +#ifndef RCDIMASTER_H +#define RCDIMASTER_H + +#include <omnithread.h> +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, pgp, Handler.hh) +#else +#include "rce/pgp/Handler.hh" +#endif +#include "rcecalib/profiler/Profiler.hh" +#include <list> +#include <vector> +#include <omnithread.h> + +#include "namespace_aliases.hh" + +namespace PgpTrans { + + class Receiver; + + class RCDImaster: public RcePgp::Handler { + public: + enum ERRCODES{SENDFAILED=666, RECEIVEFAILED=667}; + enum TIMEOUTS{RECEIVETIMEOUT=100000000}; //in ns + static RCDImaster* instance(); + void setPool(RcePic::Pool *p); + void setDriver(RcePgp::Driver *pgpd); + unsigned int writeRegister(unsigned address, unsigned value); + unsigned int readRegister(unsigned address, unsigned& value); + unsigned int blockWrite(unsigned* data, int size, bool handshake, bool byteswap); + unsigned int blockWrite(RcePic::Tds* tds); + unsigned int blockRead(unsigned* data, int size, std::vector<unsigned>& retvec); + unsigned int readBuffers(std::vector<unsigned char>& retvec); + unsigned int sendCommand(unsigned char opcode, unsigned context=0); + void setReceiver(Receiver* receiver); + Receiver* receiver(); + unsigned nBuffers(); + int currentBuffer(unsigned char*& header, unsigned &headerSize, unsigned char*&payload, unsigned &payloadSize); + int discardCurrentBuffer(); + protected: + RCDImaster(); + virtual void completed(RcePic::Tds *tds, RcePgp::Driver *pgpd); + virtual void received(RcePic::Tds *tds, RcePgp::Driver *pgpd); + unsigned transferred(RcePic::Tds* tds); + private: + RcePgp::Driver *_pgp_driver; + Receiver* _receiver; + RcePic::Pool * _pool; + unsigned int _tid; + omni_mutex _data_mutex; + omni_condition _data_cond; + unsigned _status; + unsigned _data; + std::list<RcePic::Tds*> _buffers; + bool _handshake; + bool _blockread; + Profiler::Timer m_timer; + int m_counter; + static omni_mutex _guard; + static RCDImaster* _instance; + }; + +}//namespace + +#endif diff --git a/rce/rcecalib/HW/Receiver.hh b/rce/rcecalib/HW/Receiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..e9f8cb5b63ef2ba09d2d05c6f0b5948461aa50de --- /dev/null +++ b/rce/rcecalib/HW/Receiver.hh @@ -0,0 +1,22 @@ +#ifndef PGPTRANS_RECEIVER_HH +#define PGPTRANS_RECEIVER_HH + +#include "namespace_aliases.hh" + +namespace PgpTrans { + + struct PgpData{ + unsigned char *header; + unsigned *payload; + unsigned payloadSize;}; + + class Receiver { + public: + Receiver() {} + virtual ~Receiver(){} + virtual void receive(PgpData* pgpdata)=0; + }; + +} + +#endif diff --git a/rce/rcecalib/HW/SerialHexdump.cc b/rce/rcecalib/HW/SerialHexdump.cc new file mode 100644 index 0000000000000000000000000000000000000000..82cf907eac9c26d872e9fff0fb498043ab1bee88 --- /dev/null +++ b/rce/rcecalib/HW/SerialHexdump.cc @@ -0,0 +1,71 @@ +#include "rcecalib/HW/SerialHexdump.hh" +#include "rcecalib/HW/BitStream.hh" +#include <stdio.h> +#include <iostream> + + + + +SerialHexdump::SerialHexdump(): SerialIF() { + m_flog=fopen("dbg.txt","w+"); +} + + +void SerialHexdump::Send(BitStream* bs, int opt){ + char txt[28]; + if(!m_flog) return; + // fprintf(m_flog,"sendWaitX\n"); + // std::cout<<"sendWaitX"<<std::endl; + for (unsigned int i=0;i<bs->size();i++){ + if(opt & SerialIF::BYTESWAP){ + unsigned tmp=(*bs)[i]; + unsigned tmp2 = ((tmp&0xff)<<24) | ((tmp&0xff00)<<8) | + ((tmp&0xff0000)>>8) | ((tmp&0xff000000)>>24); + sprintf(txt,"%x\n",tmp2); + } else{ + sprintf(txt,"%x\n",(*bs)[i]); + } + fprintf(m_flog,txt); + // std::cout<<txt; + } + if((opt&SerialIF::DONT_CLEAR)==0)bs->clear(); +} +void SerialHexdump::SetChannelInMask(unsigned linkmask){ +} +void SerialHexdump::SetChannelOutMask(unsigned linkmask){ +} +int SerialHexdump::EnableTrigger(bool on){ + return 0; +} +unsigned SerialHexdump::SendCommand(unsigned char opcode) { + if(opcode==77)fclose(m_flog); + std::cout<<"Opcode: "<<(unsigned)opcode<<std::endl; + return 0; +} +unsigned SerialHexdump::WriteRegister(unsigned addr, unsigned val){ + std::cout<<"Address: "<<addr<<" Value: "<<val<<std::endl; + return 0; +} +unsigned SerialHexdump::ReadRegister(unsigned addr, unsigned &val){ + std::cout<<"Address: "<<addr<<" setting to 55"<<std::endl; + val=55; + return 0; +} +unsigned SerialHexdump::WriteBlockData(std::vector<unsigned>& data){ + //std::cout<<"Block data"<<std::endl; + for (size_t i=0;i<data.size();i++){ + // std::cout<<"Word "<<i<<": "<<data[i]<<std::endl; + fprintf(m_flog, "%x\n", data[i]); + } + return 0; +} +unsigned SerialHexdump::ReadBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec){ + //std::cout<<"Block data"<<std::endl; + for (size_t i=0;i<data.size();i++){ + fprintf(m_flog, "%x\n", data[i]); + // std::cout<<"Word "<<i<<": "<<data[i]<<std::endl; + } + // for (int i=0;i<1000;i++)retvec.push_back(i); + return 0; +} + diff --git a/rce/rcecalib/HW/SerialHexdump.hh b/rce/rcecalib/HW/SerialHexdump.hh new file mode 100644 index 0000000000000000000000000000000000000000..b3f1feef6556f9688e59b0c6486e34b46c852b95 --- /dev/null +++ b/rce/rcecalib/HW/SerialHexdump.hh @@ -0,0 +1,25 @@ +#ifndef SERIALHEXDUMP_HH +#define SERIALHEXDUMP_HH + +#include "rcecalib/HW/SerialIF.hh" +#include <stdio.h> + +class SerialHexdump: public SerialIF { +public: + SerialHexdump(); + virtual ~SerialHexdump(){} +private: + void Send(BitStream* bs, int opt); + void SetChannelInMask(unsigned linkmask); + void SetChannelOutMask(unsigned linkmask); + int EnableTrigger(bool on); + unsigned SendCommand(unsigned char opcode); + unsigned WriteRegister(unsigned addr, unsigned val); + unsigned ReadRegister(unsigned addr, unsigned &val); + unsigned WriteBlockData(std::vector<unsigned>& data); + unsigned ReadBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec); + FILE* m_flog; +}; + + +#endif diff --git a/rce/rcecalib/HW/SerialIF.cc b/rce/rcecalib/HW/SerialIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..e3547696dd17be82483c10e98463480c88694b40 --- /dev/null +++ b/rce/rcecalib/HW/SerialIF.cc @@ -0,0 +1,67 @@ +#include "rcecalib/HW/SerialIF.hh" +#include "ers/ers.h" + +SerialIF* SerialIF::m_serial=0; + +SerialIF::SerialIF(){ + ERS_ASSERT_MSG(m_serial==0,"the interface exists already"); + m_serial=this; +} +void SerialIF::destroy(){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + delete m_serial; + m_serial=0; +} + +void SerialIF::send(BitStream *bs, int opt){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->Send(bs,opt); +} +void SerialIF::setChannelInMask(unsigned linkmask){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->SetChannelInMask(linkmask); +} +void SerialIF::setChannelOutMask(unsigned linkmask){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->SetChannelOutMask(linkmask); +} +int SerialIF::enableTrigger(bool on){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->EnableTrigger(on); +} +void SerialIF::disableOutput(){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->DisableOutput(); +} +void SerialIF::setOutputMode(unsigned mode){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->SetOutputMode(mode); +} +void SerialIF::setDataRate(Rate rate){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + m_serial->SetDataRate(rate); +} +unsigned SerialIF::sendCommand(unsigned char opcode){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->SendCommand(opcode); +} +unsigned SerialIF::writeRegister(unsigned addr, unsigned val){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->WriteRegister(addr,val); +} +unsigned SerialIF::readRegister(unsigned addr, unsigned &val){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->ReadRegister(addr, val); +} +unsigned SerialIF::writeBlockData(std::vector<unsigned>& data){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->WriteBlockData(data); +} +unsigned SerialIF::readBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->ReadBlockData(data, retvec); +} +unsigned SerialIF::readBuffers(std::vector<unsigned char>& retvec){ + ERS_ASSERT_MSG(m_serial!=0,"there is no serial interface defined"); + return m_serial->ReadBuffers(retvec); +} diff --git a/rce/rcecalib/HW/SerialIF.hh b/rce/rcecalib/HW/SerialIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..59cf2461f232c3c64675a768327da19d04e17a08 --- /dev/null +++ b/rce/rcecalib/HW/SerialIF.hh @@ -0,0 +1,45 @@ +#ifndef SERIALIF_HH +#define SERIALIF_HH +#include "rcecalib/HW/BitStream.hh" +#include <vector> + + +class SerialIF{ +public: + enum Options {DONT_CLEAR=1, BYTESWAP=4, WAITFORDATA=8}; + enum Rate {M40, M80, M160, M320}; + static void send(BitStream *bs, int opt=0); + static void setChannelInMask(unsigned linkmask); + static void setChannelOutMask(unsigned linkmask); + static void destroy(); + static int enableTrigger(bool on); + static void disableOutput(); + static void setOutputMode(unsigned mode); + static void setDataRate(Rate rate); + static unsigned sendCommand(unsigned char opcode); + static unsigned writeRegister(unsigned addr, unsigned val); + static unsigned readRegister(unsigned addr, unsigned& val); + static unsigned writeBlockData(std::vector<unsigned>& data); + static unsigned readBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec); + static unsigned readBuffers(std::vector<unsigned char>& retvec); +protected: + SerialIF(); + virtual ~SerialIF(){}; + virtual void Send(BitStream *bs, int opt )=0; + virtual void SetChannelInMask(unsigned linkmask)=0; + virtual void SetChannelOutMask(unsigned linkmask)=0; + virtual int EnableTrigger(bool on)=0; + virtual void DisableOutput(){} + virtual void SetOutputMode(unsigned mode){} + virtual void SetDataRate(Rate rate){}; + virtual unsigned SendCommand(unsigned char opcode){return (unsigned)-1;} + virtual unsigned WriteRegister(unsigned addr, unsigned val){return (unsigned)-1;} + virtual unsigned ReadRegister(unsigned addr, unsigned &val){return (unsigned)-1;} + virtual unsigned WriteBlockData(std::vector<unsigned>& data){return (unsigned)-1;} + virtual unsigned ReadBlockData(std::vector<unsigned>& data,std::vector<unsigned>& retvec ){return (unsigned)-1;} + virtual unsigned ReadBuffers(std::vector<unsigned char>& retvec){return(unsigned)-1;} + static SerialIF* m_serial; +}; + + +#endif diff --git a/rce/rcecalib/HW/SerialPgp.cc b/rce/rcecalib/HW/SerialPgp.cc new file mode 100644 index 0000000000000000000000000000000000000000..6a919e81c3ab0e852eee68b90b7b1e933f5e9501 --- /dev/null +++ b/rce/rcecalib/HW/SerialPgp.cc @@ -0,0 +1,50 @@ +#include "rcecalib/HW/SerialPgp.hh" +#include "rcecalib/HW/RCDImaster.hh" +#include "rcecalib/HW/BitStream.hh" +#include <iostream> +#include <assert.h> + + + + +SerialPgp::SerialPgp(): SerialIF() { +} + + +void SerialPgp::Send(BitStream* bs, int opt){ + /* + PgpTrans::RCDImaster* pgp= PgpTrans::RCDImaster::instance(); + // std::cout<<"sendWaitX"<<std::endl; + unsigned serstat; + if(opt&SerialIF::BYTESWAP){ + for (unsigned int i=0;i<bs->size();i++){ + unsigned tmp=(*bs)[i]; + unsigned tmp2 = ((tmp&0xff)<<24) | ((tmp&0xff00)<<8) | + ((tmp&0xff0000)>>8) | ((tmp&0xff000000)>>24); + serstat=pgp->writeRegister(0,tmp2); + assert(serstat==0); + } + }else{ + for (unsigned int i=0;i<bs->size();i++){ + serstat= pgp->writeRegister(0,(*bs)[i]); + assert(serstat==0); + } + } + if(opt&WAITFORDATA){ + serstat=pgp->sendCommand(3);// 3 is serialize and wait + }else{ + serstat=pgp->sendCommand(1);// 1 is serialize + } + assert(serstat==0); + pgp->semaphore()->take(); // wait for handshake + + if((opt&SerialIF::DONT_CLEAR)==0)bs->clear(); + */ +} +void SerialPgp::SetChannelInMask(unsigned linkmask){ +} +void SerialPgp::SetChannelOutMask(unsigned linkmask){ +} +int SerialPgp::EnableTrigger(bool on){ + return 0; +} diff --git a/rce/rcecalib/HW/SerialPgp.hh b/rce/rcecalib/HW/SerialPgp.hh new file mode 100644 index 0000000000000000000000000000000000000000..b71ff7c00de90d02f88a67685cd3969de7608058 --- /dev/null +++ b/rce/rcecalib/HW/SerialPgp.hh @@ -0,0 +1,19 @@ +#ifndef SERIALPGP_HH +#define SERIALPGP_HH + +#include "rcecalib/HW/SerialIF.hh" +#include <fstream> + +class SerialPgp: public SerialIF { +public: + SerialPgp(); +private: + void Send(BitStream* bs, int opt); + void SetChannelMask(unsigned linkmask); + void SetChannelInMask(unsigned linkmask); + void SetChannelOutMask(unsigned linkmask); + int EnableTrigger(bool on); +}; + + +#endif diff --git a/rce/rcecalib/HW/SerialPgpBw.cc b/rce/rcecalib/HW/SerialPgpBw.cc new file mode 100644 index 0000000000000000000000000000000000000000..5aa3021b1180d313417f0adf6a7ecd50ea1c59a6 --- /dev/null +++ b/rce/rcecalib/HW/SerialPgpBw.cc @@ -0,0 +1,67 @@ +#include "rcecalib/HW/SerialPgpBw.hh" +#include "rcecalib/HW/RCDImaster.hh" +#include "rcecalib/HW/BitStream.hh" +#include <iostream> +#include <assert.h> + + + + +SerialPgpBw::SerialPgpBw(): SerialIF() { +} + + +void SerialPgpBw::Send(BitStream* bs, int opt){ + PgpTrans::RCDImaster* pgp= PgpTrans::RCDImaster::instance(); + // std::cout<<"sendWaitX"<<std::endl; + unsigned serstat; + if(opt&WAITFORDATA){ + //std::cout<<"SerialPgpBw::Trigger"<<std::endl; + serstat=pgp->blockWrite(&((*bs)[0]),bs->size(),0,opt&SerialIF::BYTESWAP);// no handshake + }else{ + // std::cout<<"SerialPgpBw::handshake bitstream size is "<<bs->size()<<std::endl; + //pgp->blockWrite(buf,sz,1,opt&SerialIF::BYTESWAP);// handshake + serstat=pgp->blockWrite(&((*bs)[0]),bs->size(),1,opt&SerialIF::BYTESWAP);// handshake + } + assert(serstat==0); + + if((opt&SerialIF::DONT_CLEAR)==0)bs->clear(); +} +void SerialPgpBw::SetChannelInMask(unsigned linkmask){ + BitStream bs; + //bs.push_back(0); + //Send(&bs, 0); //clear FIFO + unsigned serstat=PgpTrans::RCDImaster::instance()->writeRegister(0,linkmask); + assert(serstat==0); +} +void SerialPgpBw::SetChannelOutMask(unsigned linkmask){ + unsigned serstat=PgpTrans::RCDImaster::instance()->writeRegister(13,linkmask); + assert(serstat==0); +} +int SerialPgpBw::EnableTrigger(bool on){ + unsigned serstat; + if(on) + serstat=PgpTrans::RCDImaster::instance()->sendCommand(3); + else + serstat=PgpTrans::RCDImaster::instance()->sendCommand(5); + assert(serstat==0); + return 0; +} +unsigned SerialPgpBw::SendCommand(unsigned char opcode){ + return PgpTrans::RCDImaster::instance()->sendCommand(opcode); +} +unsigned SerialPgpBw::WriteRegister(unsigned addr, unsigned val){ + return PgpTrans::RCDImaster::instance()->writeRegister(addr,val); +} +unsigned SerialPgpBw::ReadRegister(unsigned addr, unsigned& val){ + return PgpTrans::RCDImaster::instance()->readRegister(addr, val); +} +unsigned SerialPgpBw::WriteBlockData(std::vector<unsigned>& data){ + return PgpTrans::RCDImaster::instance()->blockWrite(&data[0],data.size(),1, 0);// handshake +} +unsigned SerialPgpBw::ReadBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec){ + return PgpTrans::RCDImaster::instance()->blockRead(&data[0],data.size(), retvec); +} +unsigned SerialPgpBw::ReadBuffers(std::vector<unsigned char>& retvec){ + return PgpTrans::RCDImaster::instance()->readBuffers(retvec); +} diff --git a/rce/rcecalib/HW/SerialPgpBw.hh b/rce/rcecalib/HW/SerialPgpBw.hh new file mode 100644 index 0000000000000000000000000000000000000000..1c58a9a34ea10a2aa9a5d50dfea28bca98e76631 --- /dev/null +++ b/rce/rcecalib/HW/SerialPgpBw.hh @@ -0,0 +1,25 @@ +#ifndef SERIALPGPBW_HH +#define SERIALPGPBW_HH + +#include "rcecalib/HW/SerialIF.hh" +#include <vector> + +class SerialPgpBw: public SerialIF { +public: + SerialPgpBw(); +protected: + void Send(BitStream* bs, int opt); + void SetChannelMask(unsigned linkmask); + void SetChannelInMask(unsigned linkmask); + void SetChannelOutMask(unsigned linkmask); + int EnableTrigger(bool on); + unsigned SendCommand(unsigned char opcode); + unsigned WriteRegister(unsigned addr, unsigned val); + unsigned ReadRegister(unsigned addr, unsigned &val); + unsigned WriteBlockData(std::vector<unsigned>& data); + unsigned ReadBlockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec); + unsigned ReadBuffers(std::vector<unsigned char>& retvec); +}; + + +#endif diff --git a/rce/rcecalib/HW/SerialPgpFei4.cc b/rce/rcecalib/HW/SerialPgpFei4.cc new file mode 100644 index 0000000000000000000000000000000000000000..59d472b3a942390e01ddeefd4ce5bc2192689e6d --- /dev/null +++ b/rce/rcecalib/HW/SerialPgpFei4.cc @@ -0,0 +1,18 @@ +#include "rcecalib/HW/SerialPgpFei4.hh" +#include <iostream> + +SerialPgpFei4::SerialPgpFei4(): SerialPgpBw(){} + +void SerialPgpFei4::DisableOutput(){ + WriteRegister(13,0); +} + +void SerialPgpFei4::SetOutputMode(unsigned mode){ + unsigned m= mode ? 0 : 1; + WriteRegister(16, m); +} +void SerialPgpFei4::SetDataRate(Rate rate){ + std::cout<<"Setting Data Rate (reg 10) to "<<rate<<std::endl; + WriteRegister(10,rate); +} + diff --git a/rce/rcecalib/HW/SerialPgpFei4.hh b/rce/rcecalib/HW/SerialPgpFei4.hh new file mode 100644 index 0000000000000000000000000000000000000000..38f19227a77839df1b3e1a2758f7bf72cf7bd792 --- /dev/null +++ b/rce/rcecalib/HW/SerialPgpFei4.hh @@ -0,0 +1,17 @@ +#ifndef SERIALPGPFEI4_HH +#define SERIALPGPFEI4_HH + +#include "rcecalib/HW/SerialPgpBw.hh" +#include <vector> + +class SerialPgpFei4: public SerialPgpBw { +public: + SerialPgpFei4(); +protected: + void DisableOutput(); + void SetOutputMode(unsigned mode); + virtual void SetDataRate(Rate rate); +}; + + +#endif diff --git a/rce/rcecalib/HW/constituents.mk b/rce/rcecalib/HW/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..03ba51cde2932e8c82aedb8e6198d3dd6a941009 --- /dev/null +++ b/rce/rcecalib/HW/constituents.mk @@ -0,0 +1,34 @@ + +ifdef SWAP_DATA +CPPFLAGS+= '-DSWAP_DATA' +endif + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +modlibnames := HW +libsrcs_HW := SerialIF.cc \ + RCDImaster.cc \ + SerialPgp.cc \ + SerialPgpBw.cc \ + SerialPgpFei4.cc \ + SerialHexdump.cc + +libincs_HW := rcecalib \ + rceowl/owl \ + rceers/ers \ + omniorb/include/$(tgt_arch) \ + boost +endif + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := HW + +libsrcs_HW := SerialIF.cc \ + SerialHexdump.cc + +libincs_HW := rcecalib \ + rceowl/owl \ + rceers/ers \ + omniorb/include/$(tgt_arch) \ + boost +endif + diff --git a/rce/rcecalib/Makefile b/rce/rcecalib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..bd8fffcb85eec9e196be993dd89e1b981169c01d --- /dev/null +++ b/rce/rcecalib/Makefile @@ -0,0 +1,17 @@ +# Project level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/.. +endif + +# Includes +# -------- +include $(RELEASE_DIR)/make/share/setup.mk +include flags.mk +include packages.mk +include $(RELEASE_DIR)/make/share/project.mk diff --git a/rce/rcecalib/analysis/AnalysisFactory.cc b/rce/rcecalib/analysis/AnalysisFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..f0832ff4ecb6eb198e4ffd750526caee3d74a4c1 --- /dev/null +++ b/rce/rcecalib/analysis/AnalysisFactory.cc @@ -0,0 +1,90 @@ +#include "analysis/AnalysisFactory.hh" +#include "analysis/NoiseAnalysis.hh" +#include "analysis/Iff_Analysis.hh" +#include "analysis/Fdac_Analysis.hh" +#include "analysis/StuckPixelAnalysis.hh" +#include "analysis/GdacAnalysis.hh" +#include "analysis/GdacFastAnalysis.hh" +#include "analysis/GdacCoarseFastAnalysis.hh" +#include "analysis/TdacAnalysis.hh" +#include "analysis/TdacFastAnalysis.hh" +#include "analysis/ThresholdAnalysis.hh" +#include "analysis/TotAnalysis.hh" +#include "analysis/TotCalibAnalysis.hh" +#include "analysis/DigitalTestAnalysis.hh" +#include "analysis/ModuleCrosstalkAnalysis.hh" +#include "analysis/OffsetAnalysis.hh" +#include "analysis/CrosstalkAnalysis.hh" +#include "analysis/T0Analysis.hh" +#include "analysis/TimeWalkAnalysis.hh" +#include "analysis/MultiTrigAnalysis.hh" +#include "analysis/MultiTrigNoiseAnalysis.hh" +#include "analysis/SerialNumberAnalysis.hh" +#include "analysis/TemperatureAnalysis.hh" +#include "analysis/RegisterTestAnalysis.hh" +#include "analysis/Fei3CfgFileWriter.hh" +#include "analysis/Fei4CfgFileWriter.hh" +#include <iostream> + +CalibAnalysis* AnalysisFactory::getAnalysis(std::string &type){ + CalibAnalysis* ana=0; + if(type=="Fei3Noise") + ana=new NoiseAnalysis(new Fei3CfgFileWriter); + if(type=="Fei4Noise") + ana=new NoiseAnalysis(new Fei4CfgFileWriter); + else if(type=="Fei3StuckPixel") + ana=new StuckPixelAnalysis(new Fei3CfgFileWriter); + else if(type=="Fei4StuckPixel") + ana=new StuckPixelAnalysis(new Fei4CfgFileWriter); + else if(type=="Gdac") + ana=new GdacAnalysis; + else if(type=="GdacFast") + ana=new GdacFastAnalysis; + else if(type=="GdacCoarseFast") + ana=new GdacCoarseFastAnalysis; + else if(type=="Fei3Tdac_tune") + ana=new TdacAnalysis(new Fei3CfgFileWriter); + else if(type=="Fei4Tdac_tune") + ana=new TdacAnalysis(new Fei4CfgFileWriter); + else if(type=="Fei4TdacFast_tune") + ana=new TdacFastAnalysis(new Fei4CfgFileWriter); + else if(type=="Threshold") + ana=new ThresholdAnalysis; + else if(type=="Iffanalysis") + ana=new IffAnalysis; + else if(type=="Fei3Fdacanalysis") + ana=new FdacAnalysis(new Fei3CfgFileWriter); + else if(type=="Fei4Fdacanalysis") + ana=new FdacAnalysis(new Fei4CfgFileWriter); + else if(type=="Fei3DigitalTest") + ana=new DigitalTestAnalysis(new Fei3CfgFileWriter); + else if(type=="Fei4DigitalTest") + ana=new DigitalTestAnalysis(new Fei4CfgFileWriter); + else if(type=="TOT") + ana=new TotAnalysis; + else if(type=="TOTCALIB") + ana=new TotCalibAnalysis; + else if(type=="Offset") + ana=new OffsetAnalysis; + else if(type=="ModuleCrosstalk") + ana=new ModuleCrosstalkAnalysis; + else if(type=="Crosstalk") + ana=new CrosstalkAnalysis; + else if(type=="T0") + ana=new T0Analysis; + else if(type=="TimeWalk") + ana=new TimeWalkAnalysis; + else if(type=="MultiTrig") + ana=new MultiTrigAnalysis; + else if(type=="MultiTrigNoise") + ana=new MultiTrigNoiseAnalysis; + else if(type=="SerialNumber") + ana=new SerialNumberAnalysis; + else if(type=="Temperature") + ana=new TemperatureAnalysis; + else if(type=="RegisterTest") + ana=new RegisterTestAnalysis; + else + std::cout<<"Analysis type "<<type<<" is not defined. "<<std::endl; + return ana; +} diff --git a/rce/rcecalib/analysis/AnalysisFactory.hh b/rce/rcecalib/analysis/AnalysisFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..1b32323881e3a666387f38770ed7dfe505f0c9f1 --- /dev/null +++ b/rce/rcecalib/analysis/AnalysisFactory.hh @@ -0,0 +1,15 @@ +#ifndef ANALYSISFACTORY_HH +#define ANALYSISFACTORY_HH + +#include <string> + +class CalibAnalysis; + +class AnalysisFactory{ +public: + AnalysisFactory(){}; + ~AnalysisFactory(){}; + CalibAnalysis* getAnalysis(std::string &type); +}; + +#endif diff --git a/rce/rcecalib/analysis/AnalysisGui.cc b/rce/rcecalib/analysis/AnalysisGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..a73e32499a3e10bce224354f93184b48fa64be54 --- /dev/null +++ b/rce/rcecalib/analysis/AnalysisGui.cc @@ -0,0 +1,205 @@ +#include "rcecalib/analysis/AnalysisGui.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/AnalysisFactory.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TH1.h" +#include "TKey.h" +#include "TGIcon.h" +#include "TGMenu.h" +#include "TCanvas.h" +#include "TGCanvas.h" +#include "TGListTree.h" +#include "TRootEmbeddedCanvas.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TStyle.h> +#include <assert.h> +#include <iostream> +#include <time.h> +#include <sys/stat.h> +#include <fstream> +#include <list> +#include <pthread.h> +#include <vector> +#include <stdlib.h> + +using namespace RCE; + +AnalysisGui::~AnalysisGui(){ + Cleanup(); +} + +AnalysisGui::AnalysisGui(const char* filename, int scantype, int flavor, const TGWindow *p,UInt_t w,UInt_t h) + : TGMainFrame(p,w,h) { + + // connect x icon on window manager + Connect("CloseWindow()","AnalysisGui",this,"quit()"); + + TGMenuBar *menubar=new TGMenuBar(this,1,1,kHorizontalFrame | kRaisedFrame); + TGLayoutHints *menubarlayout=new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + // menu "File" + TGPopupMenu* filepopup=new TGPopupMenu(gClient->GetRoot()); + //filepopup->AddEntry("&Load Config",LOAD); + //filepopup->AddEntry("&Save Config",SAVE); + filepopup->AddSeparator(); + filepopup->AddEntry("&Quit",QUIT); + menubar->AddPopup("&File",filepopup,menubarlayout); + + AddFrame(menubar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,2)); + + filepopup->Connect("Activated(Int_t)","AnalysisGui",this,"handleFileMenu(Int_t)"); + + TGVerticalFrame* datapanel=new TGVerticalFrame(this,1,1, kSunkenFrame); + // scan panel + TGHorizontalFrame *datapanel5 = new TGHorizontalFrame(datapanel, 2, 2, kSunkenFrame); + datapanel->AddFrame(datapanel5,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + AddFrame(datapanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + TGVerticalFrame *treepanel = new TGVerticalFrame(datapanel5, 150, 2, kSunkenFrame); + datapanel5->AddFrame(treepanel,new TGLayoutHints(kLHintsExpandY)); + TGVerticalFrame *plotpanel = new TGVerticalFrame(datapanel5, 2, 2, kSunkenFrame); + datapanel5->AddFrame(plotpanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + m_tgc=new TGCanvas(treepanel, 300,100); + //TGViewPort* vp=tgc->GetViewPort(); + m_tree=new TGListTree(m_tgc, kHorizontalFrame); + m_tree->Connect("Clicked(TGListTreeItem*, Int_t)","AnalysisGui", this, "displayHisto(TGListTreeItem*, Int_t)"); + //tree->AddItem(0,"/"); + treepanel->AddFrame(m_tgc,new TGLayoutHints(kLHintsExpandY)); + m_canvas=new TRootEmbeddedCanvas("Canvas",plotpanel,100,100); + m_canvas->GetCanvas()->GetPad(0)->SetRightMargin(0.15); + plotpanel->AddFrame(m_canvas,new TGLayoutHints(kLHintsExpandY|kLHintsExpandX)); + + SetWindowName("Analysis GUI"); + Resize(w,h); + Layout(); + MapSubwindows(); + MapWindow(); + m_file=new TFile(filename,""); + m_anfile=new TFile("analysis.root", "recreate"); + TGListTreeItem* root=m_tree->AddItem(0,"Histos"); + m_file->cd(); + fillHistoTree(root); + + // now run the analysis + std::cout<<"Analyzing"<<std::endl; + PixScan pixscan((PixScan::ScanType)scantype, (PixLib::EnumFEflavour::FEflavour) flavor); + std::string type=pixscan.getAnalysisType(); + std::cout<<"Analysis type is "<<type<<std::endl; + AnalysisFactory af; + CalibAnalysis* ana=af.getAnalysis(type); + if(ana){ + ana->analyze(m_file, m_anfile, &pixscan, 0, 0); + m_anfile->ReOpen("read"); //re-open file for reading + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + TGListTreeItem* anroot=m_tree->AddItem(root,"Analysis"); + const TGPicture *thp = gClient->GetPicture("h1_t.xpm"); + m_anfile->cd(); + TList* histos=gDirectory->GetListOfKeys(); + for(int i=0;i<histos->GetEntries();i++){ + TGListTreeItem* item=m_tree->AddItem(anroot,((TH1*)histos->At(i))->GetName()); + item->SetPictures(thp,thp); + } + updateTree(); + delete ana; + } +} + +void AnalysisGui::quit(){ + m_file->Close(); + m_anfile->Close(); + gApplication->Terminate(0); +} + + +void AnalysisGui::handleFileMenu(int item){ + if(item==QUIT)quit(); +} +void AnalysisGui::clearTree(){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + if(root) m_tree->DeleteChildren(root); + root->SetOpen(false); + updateTree(); +} +void AnalysisGui::updateTree(){ + int x=m_tgc->GetViewPort()->GetX(); + int y=m_tgc->GetViewPort()->GetY(); + int w=m_tgc->GetViewPort()->GetWidth(); + int h=m_tgc->GetViewPort()->GetHeight(); + m_tree->DrawRegion(x,y,w,h); +} + +void AnalysisGui::fillHistoTree(TGListTreeItem* branch){ + const TGPicture *thp = gClient->GetPicture("h1_t.xpm"); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + while ((key=(TKey*)nextkey())) { + TObject *obj = key->ReadObj(); + if(std::string(obj->ClassName())=="TDirectoryFile"){ + gDirectory->cd(key->GetName()); + TGListTreeItem* subdir=m_tree->AddItem(branch,key->GetName()); + fillHistoTree(subdir); + }else{ + TGListTreeItem* his=m_tree->AddItem(branch,key->GetName()); + his->SetPictures(thp, thp); + } + delete obj; + } + gDirectory->cd(".."); +} +void AnalysisGui::displayHisto(TGListTreeItem* item, int b){ + TGListTreeItem *parent=item->GetParent(); + if(parent==0)return; + const char* histoname=item->GetText(); + if(std::string(histoname).substr(0,4)=="loop")return; + if(std::string(histoname).substr(0,8)=="Analysis")return; + if(std::string(parent->GetText())=="Analysis"){ + m_anfile->cd(); + m_histo=(TH1*)gDirectory->Get(histoname); + assert(m_histo!=0); + }else{ + TGListTreeItem *parent1=parent->GetParent(); + if(parent1==0)m_file->cd(); + else{ + TGListTreeItem *parent2=parent1->GetParent(); + if(parent2==0)m_file->cd(parent->GetText()); + else{ + char dir[128]; + sprintf(dir, "%s/%s",parent1->GetText(), parent->GetText()); + m_file->cd(dir); + } + } + m_histo=(TH1*)gDirectory->Get(histoname); + assert(m_histo!=0); + } + m_histo->SetMinimum(0); + if(m_histo->GetDimension()==1)m_histo->Draw(); + else { + m_histo->Draw("colz"); + } + m_canvas->GetCanvas()->Update(); +} + + +//==================================================================== +int main(int argc, char **argv){ + if(argc!=4){ + std::cout<<"Usage: analysisGui filename scantype FE flavor"<<std::endl; + exit(0); + } + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + const char *filename=argv[1]; + std::cout<<"Filename "<<filename<<std::endl; + int scantype=atoi(argv[2]); + int flavor=atoi(argv[3]); + TApplication theapp("app",&argc,argv); + new AnalysisGui(filename, scantype, flavor, gClient->GetRoot(),800,600); + theapp.Run(); + return 0; +} + + diff --git a/rce/rcecalib/analysis/AnalysisGui.hh b/rce/rcecalib/analysis/AnalysisGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..8d39d44fe82cf54ae89f6f054cd8e3b4418af005 --- /dev/null +++ b/rce/rcecalib/analysis/AnalysisGui.hh @@ -0,0 +1,44 @@ +#ifndef ANALYSISGUI_HH +#define ANALYSISGUI_HH + +#include "TGMdiMainFrame.h" +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include "TFile.h" +#include "TH2F.h" +#include <string> + + +class TGListTree; +class TGListTreeItem; +class TH1; +class TRootEmbeddedCanvas; +class IPCGuiCallback; + +class AnalysisGui: public TGMainFrame { +public: + AnalysisGui(const char* filename, int scantype, int flavor, const TGWindow *p,UInt_t w,UInt_t h); + virtual ~AnalysisGui(); + void handleFileMenu(Int_t); + void quit(); + void clearTree(); + void updateTree(); + void displayHisto(TGListTreeItem* item, int b); +private: + + void fillHistoTree(TGListTreeItem* branch); + enum Filemenu {LOAD, SAVE, QUIT}; + TGTextButton* *m_quit; + TGListTree* m_tree; + TH1 *m_histo; + TRootEmbeddedCanvas *m_canvas; + TFile *m_file, *m_anfile; + std::string m_dir; + bool m_delhisto; + TGCanvas *m_tgc; + int m_indx; + +ClassDef (AnalysisGui,0) +}; +#endif diff --git a/rce/rcecalib/analysis/CalibAnalysis.cc b/rce/rcecalib/analysis/CalibAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..86d84107a0871767130e4f8ff00db5979af07b16 --- /dev/null +++ b/rce/rcecalib/analysis/CalibAnalysis.cc @@ -0,0 +1,147 @@ +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/server/TurboDaqFile.hh" + +#include <TFile.h> +#include <boost/regex.hpp> +#include <string> +#include <iostream> + +std::string CalibAnalysis::getPath(TFile* file){ + std::string fn(file->GetName()); + std::string name=""; + boost::regex re("[^/]*\\.root"); + std::string maskfilename = boost::regex_replace (fn, re, name); + return maskfilename; +} + +ipc::PixelFEI4AConfig* CalibAnalysis::findFEI4AConfig(ConfigGui* cfg[], int id){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg!=0 && cfg[i]->isIncluded() && cfg[i]->getType()=="FEI4A" && cfg[i]->getId()==id){ + cfg[i]->setConfig(); //restore config + m_cfg=cfg[i]; + m_channel=i; + return cfg[i]->getFEI4AConfig(); + } + } + return 0; +} + +const char* CalibAnalysis::findFieldName(ConfigGui* cfg[], int id){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg!=0 && cfg[i]->isIncluded() && cfg[i]->getId()==id){ + return cfg[i]->getName(); + } + } + return ""; +} + +const std::string CalibAnalysis::findFEType(ConfigGui* cfg[], int id){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg!=0 && cfg[i]->isIncluded() && cfg[i]->getId()==id){ + return cfg[i]->getType(); + } + } + return ""; +} + +ipc::PixelFEI4BConfig* CalibAnalysis::findFEI4BConfig(ConfigGui* cfg[], int id){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg!=0 && cfg[i]->isIncluded() && cfg[i]->getType()=="FEI4B" && cfg[i]->getId()==id){ + cfg[i]->setConfig(); //restore config + m_cfg=cfg[i]; + m_channel=i; + return cfg[i]->getFEI4BConfig(); + } + } + return 0; +} + +ipc::PixelModuleConfig* CalibAnalysis::findFEI3Config(ConfigGui* cfg[], int id){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg!=0 && cfg[i]->isIncluded() && cfg[i]->getType()=="FEI3" && cfg[i]->getId()==id){ + cfg[i]->setConfig(); //restore config + m_cfg=cfg[i]; + m_channel=i; + return cfg[i]->getModuleConfig(); + } + } + return 0; +} + +void CalibAnalysis::writeTopFile(ConfigGui* cfg[],TFile* anfile, int runno ){ + char key[16]; + sprintf(key, "%d", runno); + std::string path=getPath(anfile)+"configUpdate"; + //std::cout << path << std::endl; + std::ofstream topfile((path+"/top/config__"+key+".cfg").c_str()); + std::string name; + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg[i]->isIncluded()) + name=path+"/"+cfg[i]->getConfdir()+"/configs/"+cfg[i]->getConfigName()+"__"+key+".cfg"; + else + name=cfg[i]->getFilename(); + cfg[i]->copyConfig(topfile, name.c_str()); + } + topfile.close(); + m_update=true; +} + +void CalibAnalysis::writeFEI4Config(TFile* anfile, int runno){ + if(m_cfg!=0){ + char key[16]; + sprintf(key, "%d", runno); + std::string path=getPath(anfile)+"configUpdate"; + m_update=true; + if(m_cfg->getType()=="FEI4A"){ + FEI4AConfigFile cf; + cf.writeModuleConfig(m_cfg->getFEI4AConfig(), path.c_str(), m_cfg->getConfdir(), m_cfg->getConfigName(), key); + } else if(m_cfg->getType()=="FEI4B"){ + FEI4BConfigFile cf; + cf.writeModuleConfig(m_cfg->getFEI4BConfig(), path.c_str(), m_cfg->getConfdir(), m_cfg->getConfigName(), key); + } + m_cfg->setConfig(); //restore config + } +} + +void CalibAnalysis::writeFEI3Config(TFile* anfile, int runno){ + if(m_cfg!=0){ + char key[16]; + sprintf(key, "%d", runno); + std::string path=getPath(anfile)+"configUpdate"; + m_update=true; + if(m_cfg->getType()=="FEI3"){ + TurboDaqFile cf; + //cf.dump(* m_cfg->getFEI3Config()); + cf.writeModuleConfig(m_cfg->getModuleConfig(), path.c_str(), m_cfg->getConfdir(), m_cfg->getConfigName(), key); + } + m_cfg->setConfig(); //restore config + } +} + +void CalibAnalysis::clearFEI4Masks(unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]){ + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + masks[i][j]|=0x1; //set bit 0 (enable) + masks[i][j]&=0xf7; //reset bit 3 (hitbus) + } + } +} + +std::string CalibAnalysis::addPosition(const char* hname, ConfigGui* cfg[]){ + boost::cmatch matches; + boost::regex re("Mod_(\\d+)"); + if(boost::regex_search(hname, matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg[i]->isIncluded() && cfg[i]->getId()==id){ + return std::string(Form("%d", 1+i/(ConfigGui::MAX_MODULES/2)))+std::string(cfg[i]->getName())+":"+hname; + } + } + } + return hname; +} diff --git a/rce/rcecalib/analysis/CalibAnalysis.hh b/rce/rcecalib/analysis/CalibAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..4fd5bf3a2c6343bb4b8bd90aa2cbd49f47b8cdf8 --- /dev/null +++ b/rce/rcecalib/analysis/CalibAnalysis.hh @@ -0,0 +1,38 @@ +#ifndef CALIBANALYSIS_HH +#define CALIBANALYSIS_HH + +#include <string> +#include "PixelFEI4AConfig.hh" +#include "PixelFEI4BConfig.hh" +#include "PixelModuleConfig.hh" + +class TFile; +class ConfigGui; +namespace RCE{ + class PixScan; +} + +class CalibAnalysis{ +public: + CalibAnalysis(): m_cfg(0), m_update(false){} + virtual ~CalibAnalysis(){} + virtual void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[])=0; + std::string getPath(TFile* file); + ipc::PixelFEI4AConfig* findFEI4AConfig(ConfigGui* cfg[], int id); + ipc::PixelFEI4BConfig* findFEI4BConfig(ConfigGui* cfg[], int id); + ipc::PixelModuleConfig* findFEI3Config(ConfigGui* cfg[], int id); + void writeFEI4Config(TFile *anfile, int runno); + void writeFEI3Config(TFile *anfile, int runno); + bool configUpdate(){return m_update;} + void writeTopFile(ConfigGui* cfg[], TFile* anfile, int runno); + const char* findFieldName(ConfigGui* cfg[], int id); + const std::string findFEType(ConfigGui* cfg[], int id); + void clearFEI4Masks(unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]); + static std::string addPosition(const char* hname, ConfigGui* cfg[]); +private: + ConfigGui* m_cfg; + int m_channel; + bool m_update; +}; + +#endif diff --git a/rce/rcecalib/analysis/CfgFileWriter.cc b/rce/rcecalib/analysis/CfgFileWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..f8c9af76a7d9446dbbed196bad6c40eb4967ce02 --- /dev/null +++ b/rce/rcecalib/analysis/CfgFileWriter.cc @@ -0,0 +1,13 @@ +#include "rcecalib/analysis/CfgFileWriter.hh" +#include <TFile.h> +#include <boost/regex.hpp> +#include <string> +#include <iostream> + +std::string CfgFileWriter::getPath(TFile* file){ + std::string fn(file->GetName()); + std::string name=""; + boost::regex re("[^/]*\\.root"); + std::string maskfilename = boost::regex_replace (fn, re, name); + return maskfilename; +} diff --git a/rce/rcecalib/analysis/CfgFileWriter.hh b/rce/rcecalib/analysis/CfgFileWriter.hh new file mode 100644 index 0000000000000000000000000000000000000000..4fa14d72a2899b60bb02f986fe8ca0a03308ae31 --- /dev/null +++ b/rce/rcecalib/analysis/CfgFileWriter.hh @@ -0,0 +1,17 @@ +#ifndef CFGFILEWRITER_HH +#define CFGFILEWRITER_HH + +class TH2; +class TFile; +#include <string> + +class CfgFileWriter{ +public: + CfgFileWriter(){} + virtual ~CfgFileWriter(){} + virtual void writeDacFile(const char* filename, TH2* his)=0; + virtual void writeMaskFile(const char* filename, TH2* his)=0; + std::string getPath(TFile*); +}; + +#endif diff --git a/rce/rcecalib/analysis/CrosstalkAnalysis.cc b/rce/rcecalib/analysis/CrosstalkAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..32ef138526549d1ffceb7bd9cb61d1804e3dae13 --- /dev/null +++ b/rce/rcecalib/analysis/CrosstalkAnalysis.cc @@ -0,0 +1,168 @@ +#include "rcecalib/analysis/CrosstalkAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + + +void CrosstalkAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Crosstalk analysis"<<std::endl; + unsigned int numval=scan->getLoopVarValues(0).size(); + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + std::map<int, TH1D*> histmap; + TIter nextkey(gDirectory->GetListOfKeys()); // histograms + TKey *key; + while ((key=(TKey*)nextkey())) { + file->cd(); + std::string hname(key->GetName()); + boost::cmatch matches; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + char name[128]; + char title[128]; + if(boost::regex_search(hname.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string chi2HistoName = boost::regex_replace (hname, re2, "ChiSquare"); + std::string sigmaHistoName = boost::regex_replace (hname, re2, "Sigma"); + TH2* histo = (TH2*)key->ReadObj(); + TH2* chi2Histo=(TH2*)gDirectory->Get(chi2HistoName.c_str()); + TH2* sigmahisto=(TH2*)gDirectory->Get(sigmaHistoName.c_str()); + assert(chi2Histo!=0); + assert(sigmahisto!=0); + int binsx=histo->GetNbinsX(); + int binsy=histo->GetNbinsY(); + sprintf(name, "thresh2d_Mod_%d", id); + sprintf(title, "Thresholds Module %d at %s", id, findFieldName(cfg, id)); + TH2F* thresh2d=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + thresh2d->GetXaxis()->SetTitle("Column"); + thresh2d->GetYaxis()->SetTitle("Row"); + sprintf(name, "thresh1d_Mod_%d", id); + sprintf(title, "Thresholds Module %d at %s", id, findFieldName(cfg, id)); + int nbins=binsx*binsy; + TH1F* thresh1d=new TH1F(name, title, nbins, 0, (float)nbins); + thresh1d->GetXaxis()->SetTitle("Channel"); + thresh1d->SetOption("p9"); + sprintf(name, "sigma1d_Mod_%d", id); + sprintf(title, "Sigma Module %d at %s", id, findFieldName(cfg, id)); + TH1F* sigma1d=new TH1F(name, title, nbins, 0, (float)nbins); + sigma1d->GetXaxis()->SetTitle("Channel"); + sigma1d->SetOption("p9"); + sprintf(name, "threshdist_Mod_%d", id); + sprintf(title, "Threshold distribution Module %d at %s", id, findFieldName(cfg, id)); + TH1F* threshdist=new TH1F(name, title, 500, 20000, 60000); + threshdist->GetXaxis()->SetTitle("Threshold"); + sprintf(name, "sigmadist_Mod_%d", id); + sprintf(title, "Sigma distribution Module %d at %s", id, findFieldName(cfg, id)); + TH1F* sigmadist=new TH1F(name, title, 100, 0, 12000); + sigmadist->GetXaxis()->SetTitle("Sigma"); + sprintf(name, "crosstalk2d_Mod_%d", id); + sprintf(title, "Crosstalk for Last Scan Point, Module %d at %s", id, findFieldName(cfg, id)); + TH2F* crosstalk2d=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + crosstalk2d->GetXaxis()->SetTitle("Column"); + crosstalk2d->GetYaxis()->SetTitle("Row"); + sprintf(name, "crosstalk1d_Mod_%d", id); + sprintf(title, "Crosstalk for Last Scan Point, Module %d at %s", id, findFieldName(cfg, id)); + TH1F* crosstalk1d=new TH1F(name, title, nbins, 0, (float)nbins); + crosstalk1d->GetXaxis()->SetTitle("Channel"); + crosstalk1d->SetOption("p9"); + + TH1D* hits1d=new TH1D(Form("HitsPerBin_Mod_%d", id), + Form("Hits per bin Mod %d at %s", id, findFieldName(cfg, id)), + numval, -.5, (float)numval-.5) ; + hits1d->GetXaxis()->SetTitle("Scan Point"); + + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + thresh2d->SetBinContent(i,j,histo->GetBinContent(i,j)); + thresh1d->SetBinContent((i-1)*histo->GetNbinsY()+j, histo->GetBinContent(i,j)); + threshdist->Fill(histo->GetBinContent(i,j)); + sigma1d->SetBinContent((i-1)*histo->GetNbinsY()+j, sigmahisto->GetBinContent(i,j)); + sigmadist->Fill(sigmahisto->GetBinContent(i,j)); + } + } + + TF1 gauss("gauss", "gaus"); + gauss.SetParameter(0, threshdist->GetMaximum()); + gauss.SetParameter(1, threshdist->GetMaximumBin()*threshdist->GetBinWidth(1)); + threshdist->Fit(&gauss,"q", ""); + + + + int numdistbins=100; + + std::string finalhistoName = boost::regex_replace (hname, re2, Form("Occupancy_Point_%03d", numval-1)); + TH2* finalOccHisto=(TH2*)gDirectory->Get(finalhistoName.c_str()); + if(finalOccHisto!=0){ + numdistbins = finalOccHisto->GetMaximum(); + } + + sprintf(name, "crosstalkdist_Mod_%d", id); + sprintf(title, "Occupancy distribution for highest Scan Point, Module %d at %s", id, findFieldName(cfg, id)); + TH1F* crosstalkdist=new TH1F(name, title, numdistbins, -0.5, (float)numdistbins - 0.5); + crosstalkdist->GetXaxis()->SetTitle("Occupancy for highest Scan Point"); + + if(finalOccHisto==0){ + std::cout<<"Final Occupancy histogram not found. Won't fill crosstalk histos."<<std::endl; + } + else{ + + for (int i=1;i<=finalOccHisto->GetNbinsX();i++){ + for(int j=1;j<=finalOccHisto->GetNbinsY();j++){ + crosstalk2d->SetBinContent(i,j,finalOccHisto->GetBinContent(i,j)); + crosstalk1d->SetBinContent((i-1)*finalOccHisto->GetNbinsY()+j, finalOccHisto->GetBinContent(i,j)); + crosstalkdist->Fill(finalOccHisto->GetBinContent(i,j)); + } + } + + } + + + for(unsigned int k=0;k<numval;k++){ + + std::string histoName = boost::regex_replace (hname, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } + + anfile->cd(); + thresh2d->Write(); + thresh2d->SetDirectory(gDirectory); + thresh1d->Write(); + thresh1d->SetDirectory(gDirectory); + threshdist->Write(); + threshdist->SetDirectory(gDirectory); + sigma1d->Write(); + sigma1d->SetDirectory(gDirectory); + sigmadist->Write(); + sigmadist->SetDirectory(gDirectory); + + crosstalk2d->Write(); + crosstalk2d->SetDirectory(gDirectory); + crosstalk1d->Write(); + crosstalk1d->SetDirectory(gDirectory); + crosstalkdist->Write(); + crosstalkdist->SetDirectory(gDirectory); + + hits1d->Write(); + hits1d->SetDirectory(gDirectory); + } + } + +} diff --git a/rce/rcecalib/analysis/CrosstalkAnalysis.hh b/rce/rcecalib/analysis/CrosstalkAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..b5e52fa4795c2bf75f4c7bd875cd0767d5ee8510 --- /dev/null +++ b/rce/rcecalib/analysis/CrosstalkAnalysis.hh @@ -0,0 +1,24 @@ +#ifndef CROSSTALKANALYSIS_HH +#define CROSSTALKANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} + +class CrosstalkAnalysis: public CalibAnalysis{ +public: + CrosstalkAnalysis(): CalibAnalysis(){} + ~CrosstalkAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/DigitalTestAnalysis.cc b/rce/rcecalib/analysis/DigitalTestAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..7cdaeed28b81645b94ca3ec00f3e57a8b3f3b1f4 --- /dev/null +++ b/rce/rcecalib/analysis/DigitalTestAnalysis.cc @@ -0,0 +1,111 @@ +#include "rcecalib/analysis/DigitalTestAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void DigitalTestAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Digital test analysis"<<std::endl; + if(file->Get("loop1_0"))file->cd("loop1_0"); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + std::vector<float> masks; + std::vector<float> digimaskdistros; + std::vector<std::string> pos; + boost::regex re("_(\\d+)_Occupancy"); + double nHits=(double)scan->getRepetitions(); + + + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string match2=addPosition(name.c_str(), cfg).substr(0,5); + pos.push_back(match2); + + TH2* histo = (TH2*)key->ReadObj(); + TH2D* mhis=new TH2D(Form("Mask_Mod_%d",id), Form("Mask Mod %d at %s", id, findFieldName(cfg, id)), + histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax(), + histo->GetNbinsY(), histo->GetYaxis()->GetXmin(), histo->GetYaxis()->GetXmax()); + mhis->GetXaxis()->SetTitle("Column"); + mhis->GetYaxis()->SetTitle("Row"); + unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]=0; + ipc::PixelFEI4AConfig* conf=findFEI4AConfig(cfg, id); + if(conf)masks=conf->FEMasks; + else { + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)masks=confb->FEMasks; + } + if(masks && scan->clearMasks()==true)clearFEI4Masks(masks); + for (int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + if(histo->GetBinContent(i+1, j+1)!=nHits){ + mhis->SetBinContent(i+1,j+1,1); + if(masks){ + masks[i][j]&=0xfe; //reset bit 0 (enable) + masks[i][j]|=0x8; //reset bit 3 (hitbus) + } + } + } + } + digimaskdistros.push_back(mhis->Integral()); + if(masks) writeFEI4Config(anfile, runno); + m_fw->writeMaskFile(Form("%sMask_Mod_%d", m_fw->getPath(anfile).c_str(), id), mhis); + delete histo; + anfile->cd(); + mhis->Write(); + mhis->SetDirectory(gDirectory); + } + } + + TH1I* mask_distro[2]; + mask_distro[0]=new TH1I(Form("1-Mask"), Form("Mask Distribution 1st stave"), 32, 0, 32); + mask_distro[1]=new TH1I(Form("2-Mask"), Form("Mask Distribution 2nd stave"), 32, 0, 32); + char position[10]; + + for(int i=0;i<4;i++){ //half stave + if(i%2==0)position[0]='A'; + else position[0]='C'; + //mhis[i]->GetYaxis()->SetTitle("Threshold (e)"); + for(int j=1;j<=8;j++){ //module + for(int k=1;k<=2;k++){ //FE + sprintf(&position[1], "%d-%d", j,k); + int bin=0; + if(i%2==0)bin=17-((j-1)*2+k); // A side + else bin=16+(j-1)*2+k; + mask_distro[i/2]->GetXaxis()->SetBinLabel(bin,position); + for(size_t l=0;l<pos.size();l++){ + if(std::string(position)==pos[l].substr(1,4) && + pos[l].substr(0,1)==Form("%d", i/2+1)){ + mask_distro[i/2]->SetBinContent(bin, digimaskdistros[l]); + } + } + } + + } + if(i%2==1){ + //anfile->cd(); + mask_distro[i/2]->SetFillColor(kRed); + mask_distro[i/2]->Write(); + mask_distro[i/2]->SetDirectory(gDirectory); + } + + } + + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + diff --git a/rce/rcecalib/analysis/DigitalTestAnalysis.hh b/rce/rcecalib/analysis/DigitalTestAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..d80dd817f44816e14a7e0b6800ecca4a87cd018f --- /dev/null +++ b/rce/rcecalib/analysis/DigitalTestAnalysis.hh @@ -0,0 +1,25 @@ +#ifndef DIGITALTESTANALYSIS_HH +#define DIGITALTESTANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class DigitalTestAnalysis: public CalibAnalysis{ +public: + DigitalTestAnalysis(CfgFileWriter* fw): CalibAnalysis(), m_fw(fw){} + ~DigitalTestAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void writeMaskFile(TH2D* his, TFile* anfile); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/Fdac_Analysis.cc b/rce/rcecalib/analysis/Fdac_Analysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..e979458f68477da1ad1e3afdf997f926530e6cf1 --- /dev/null +++ b/rce/rcecalib/analysis/Fdac_Analysis.cc @@ -0,0 +1,218 @@ +#include "rcecalib/analysis/Fdac_Analysis.hh" +#include "rcecalib/config/FEI3/Frontend.hh" +#include <boost/regex.hpp> + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1D.h> +#include <TKey.h> +#include <TStyle.h> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <cmath> + +void FdacAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + gStyle->SetOptFit(111); + printf("Begin FDAC Analysis\n"); + float target = float(scan->getTotTargetValue()); + printf("Target Tot Value: %2.1f\n",target); + std::vector<float> loopVar=scan->getLoopVarValues(0); + size_t numvals=loopVar.size(); + //TH1F* iffhis = new TH1F("iff_v_module","Best IF Setting",128,0,127); + //iffhis->GetXaxis()->SetTitle("Module"); + //iffhis->GetYaxis()->SetTitle("IF Setting"); + std::map<int, odata> *histomap=new std::map<int, odata>[numvals]; + TKey *key; + int binsx=0, binsy=0; + for (size_t i=0;i<numvals;i++){ + TIter nextkey(gDirectory->GetListOfKeys()); // FDAC settings + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::regex re(Form("_(\\d+)_Occupancy_Point_%03d", i)); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int lnm=strtol(match.c_str(),0,10); + histomap[i][lnm].occ = (TH2*)key->ReadObj(); + boost::regex re2("Occupancy"); + std::string totHistoName = boost::regex_replace (name, re2, "ToT"); + histomap[i][lnm].tot=(TH2*)gDirectory->Get(totHistoName.c_str()); + std::string tot2HistoName = boost::regex_replace (name, re2, "ToT2"); + histomap[i][lnm].tot2=(TH2*)gDirectory->Get(tot2HistoName.c_str()); + assert(histomap[i][lnm].tot2); + binsx=histomap[i][lnm].tot2->GetNbinsX(); + binsy=histomap[i][lnm].tot2->GetNbinsY(); + } + } + } + for(std::map<int, odata>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + int max=16; + if(findFEType(cfg, id)=="FEI3")max=64; + struct ipc::PixelFEI4Trims *trims=0; + struct ipc::PixelModuleConfig *conf3=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)trims=&confa->FETrims; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)trims=&confb->FETrims; + else conf3=findFEI3Config(cfg, id); + } + TH2D* fdachis = new TH2D(Form("FDAC_Mod_%i", id), + Form("Best FDAC Settings Mod %d at %s", id, findFieldName(cfg, id)), + binsx,0,binsx,binsy,0,binsy); + fdachis->GetXaxis()->SetTitle("Column"); + fdachis->GetYaxis()->SetTitle("Row"); + TH2D* ahis = new TH2D(Form("ToT_MinDiff_Mod_%i", id), + Form("min(ToT - Target ToT) Mod %d at %s", id, findFieldName(cfg, id)), + binsx,0,binsx,binsy,0,binsy); + ahis->GetXaxis()->SetTitle("Column"); + ahis->GetYaxis()->SetTitle("Row"); + TH2D* badpix = new TH2D(Form("BadPixels_Mod_%i", id), + Form("Bad Pixel Map Mod %d at %s", id, findFieldName(cfg, id)), + binsx,0,binsx,binsy,0,binsy); + badpix->GetXaxis()->SetTitle("Column"); + badpix->GetYaxis()->SetTitle("Row"); + TH1D* channel = new TH1D(Form("ToT_MinDiff_Channel_Mod_%i", id), + Form("min(ToT - Target ToT) Mod %d at %s", id, findFieldName(cfg, id)), + binsx*binsy,0,binsx*binsy); + channel->GetXaxis()->SetTitle("Channel"); + channel->SetOption("p9"); + TH1D* dist = new TH1D(Form("ToT_MinDiff_Dist_Mod_%i", id), + Form("ToT - Target Mod %d at %s", id, findFieldName(cfg, id)), + 100, -2, 2); + dist->GetXaxis()->SetTitle("ToT"); + TH1D* totdist; + if(findFEType(cfg, id)=="FEI3"){ + totdist = new TH1D(Form("ToT_Dist_Mod_%i", id), + Form("ToT Mod %d at %s", id, findFieldName(cfg, id)), + 641, -.05, 64.05); + }else{ + totdist = new TH1D(Form("ToT_Dist_Mod_%i", id), + Form("ToT Mod %d at %s", id, findFieldName(cfg, id)), + 161, -.05, 16.05); + } + totdist->GetXaxis()->SetTitle("ToT"); + TH1F* tot1d=new TH1F(Form("tot1d_Mod_%d", id), + Form("ToT Module %d at %s", id, findFieldName(cfg, id)), + binsx*binsy, 0, (float)binsx*binsy); + tot1d->GetXaxis()->SetTitle("Channel"); + tot1d->SetMinimum(0); + tot1d->SetMaximum(max); + tot1d->SetOption("p9"); + TH2F* tot2d=new TH2F(Form("tot2d_Mod_%d", id), + Form("ToT Module %d at %s", id, findFieldName(cfg, id)), + binsx, 0, binsx, binsy, 0, binsy); + tot2d->GetXaxis()->SetTitle("Column"); + tot2d->GetYaxis()->SetTitle("Row"); + tot2d->SetMinimum(0); + tot2d->SetMaximum(max); + int chan; + for(int c = 1; c <= binsx; c++){ + for(int r = 1; r <= binsy ; r++){ + ahis->SetBinContent(c,r,-1.0); + chan = r + (c-1)*binsy; + channel->SetBinContent(chan,-1.0); + } + } + for(int j = 1; j <= fdachis->GetNbinsX(); j++){ + for(int k = 1; k <= fdachis->GetNbinsY(); k++){ + int value = 0; + float min = 999999.9; + float diff= 999999.9; + std::vector<float> vals; + for(unsigned i = 0; i < numvals; i++){ + //printf("Point %3i\n",i); + TH2* occ_histo=histomap[i][id].occ; + TH2* tot_histo=histomap[i][id].tot; + float nhits = occ_histo->GetBinContent(j,k); + float tot=0; + if(nhits != 0){ + tot = float(tot_histo->GetBinContent(j,k)) / nhits; + if(fabs(tot - target) < min){ + min = fabs(tot - target); + diff = (tot-target); + value = i; + } + } + vals.push_back(tot); + } + // interpolate + int intval=int(loopVar[value]+.1); + /* + //below found value + if(value!=0 && vals[value-1]!=vals[value] && loopVar[value]!=loopVar[value-1]){ + float m=(vals[value]-vals[value-1])/(loopVar[value]-loopVar[value-1]); + float n=vals[value]-m*loopVar[value]; + for (int i=int(loopVar[value-1]+1.1);i<int(loopVar[value]+0.1);i++){ + if(fabs(m*i+n-target)<min){ + min=fabs(m*i+n-target); + diff=m*i+n-target; + intval=i; + } + } + } + //above found value + if((unsigned)value!=numvals-1 && vals[value+1]!=vals[value] && loopVar[value]!=loopVar[value+1]){ + float m=(vals[value]-vals[value+1])/(loopVar[value]-loopVar[value+1]); + float n=vals[value]-m*loopVar[value]; + for (int i=int(loopVar[value]+1.1);i<int(loopVar[value+1]+0.1);i++){ + if(fabs(m*i+n-target)<min){ + min=fabs(m*i+n-target); + diff=m*i+n-target; + intval=i; + } + } + } + */ + if(min < 1000){ + ahis->SetBinContent(j,k,min); + fdachis->SetBinContent(j,k,intval); + if(trims)trims->dacFeedbackTrim[j-1][k-1]=intval; + else if (conf3){ + int chip=(j-1)/FEI3::Frontend::N_COLS; + int col=(j-1)%FEI3::Frontend::N_COLS; + int row=k-1; + conf3->FEConfig[chip].FETrims.dacFeedbackTrim[row][col]=intval; + } + chan = k + (j-1)*binsy; + if(min<max)channel->SetBinContent(chan,min); + dist->Fill(diff); + totdist->Fill(diff+target); + tot1d->SetBinContent(chan, diff+target); + tot2d->SetBinContent(j, k, diff+target); + if(min>1)badpix->SetBinContent(j,k,1); + } + else badpix->SetBinContent(j,k,1); + } + } + dist->Fit("gaus"); + anfile->cd(); + fdachis->Write(); + fdachis->SetDirectory(gDirectory); + ahis->Write(); + ahis->SetDirectory(gDirectory); + badpix->Write(); + badpix->SetDirectory(gDirectory); + channel->Write(); + channel->SetDirectory(gDirectory); + dist->Write(); + dist->SetDirectory(gDirectory); + totdist->Write(); + totdist->SetDirectory(gDirectory); + tot1d->Write(); + tot1d->SetDirectory(gDirectory); + tot2d->Write(); + tot2d->SetDirectory(gDirectory); + m_fw->writeDacFile(Form("%sFdacs_Mod_%d", m_fw->getPath(anfile).c_str(), id), fdachis); + if(trims) writeFEI4Config(anfile, runno); + if(conf3) writeFEI3Config(anfile, runno); + } + if(configUpdate())writeTopFile(cfg, anfile, runno); + delete [] histomap; + printf("Done Analysis\n"); +} + diff --git a/rce/rcecalib/analysis/Fdac_Analysis.hh b/rce/rcecalib/analysis/Fdac_Analysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..d6a53bf3cf70edf2e1532e3a2d90c0ffc49ec842 --- /dev/null +++ b/rce/rcecalib/analysis/Fdac_Analysis.hh @@ -0,0 +1,30 @@ +#ifndef FDAC_ANALYSIS_HH +#define FDAC_ANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" +#include "rcecalib/server/PixScan.hh" + +class ConfigGui; +class TFile; +class TH2; +namespace RCE{ + class PixScan; +} + +class FdacAnalysis: public CalibAnalysis{ +public: + struct odata{ + TH2* occ; + TH2* tot; + TH2* tot2; + }; + FdacAnalysis(CfgFileWriter* fw): CalibAnalysis(), m_fw(fw){} + ~FdacAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/Fei3CfgFileWriter.cc b/rce/rcecalib/analysis/Fei3CfgFileWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..458ee8ca7e23048e06038102dbc7e62ac8b4265d --- /dev/null +++ b/rce/rcecalib/analysis/Fei3CfgFileWriter.cc @@ -0,0 +1,52 @@ +#include "rcecalib/analysis/Fei3CfgFileWriter.hh" + +#include <iostream> +#include <fstream> +#include <boost/regex.hpp> +#include <TFile.h> +#include <TH2.h> + + +void Fei3CfgFileWriter::writeDacFile(const char* filename, TH2* tdac){ + int ncol=18; + int nrow=160; + std::cout<<std::dec; + for (int i=0;i<16;i++){ + std::string name(filename); + name+=Form("_FE_%d.dat",i); + std::ofstream maskfile(name.c_str()); + for (int col=1;col<=ncol;col++){ + for (int row=1;row<=nrow;row++){ + maskfile<<int(tdac->GetBinContent(i*ncol+col, row)+0.1)<<" "; + } + maskfile<<std::endl; + } + maskfile.close(); + } +} + + +void Fei3CfgFileWriter::writeMaskFile(const char* filename, TH2* histo){ + int ncol=18; + std::cout<<std::dec; + for (int i=0;i<16;i++){ + std::string name(filename); + name+=Form("_FE_%d.dat",i); + std::ofstream maskfile(name.c_str()); + for (int l=0;l<ncol;l++){ + std::cout<<Form("%-6d", l); + for(int j=4;j>=0;j--){ + unsigned mask=0; + std::cout<<" "; + for(int k=31;k>=0;k--){ + if(histo->GetBinContent(i*ncol+l+1, j*32+k+1)!=0)mask|=1; + mask<<=1; + } + std::cout<<std::hex<<mask<<std::dec; + } + std::cout<<std::endl; + } + maskfile<<std::endl; + maskfile.close(); + } +} diff --git a/rce/rcecalib/analysis/Fei3CfgFileWriter.hh b/rce/rcecalib/analysis/Fei3CfgFileWriter.hh new file mode 100644 index 0000000000000000000000000000000000000000..7c0381dedf118ddf2339a15633316962b78db12c --- /dev/null +++ b/rce/rcecalib/analysis/Fei3CfgFileWriter.hh @@ -0,0 +1,14 @@ +#ifndef FEI3CFGFILEWRITER_HH +#define FEI3CFGFILEWRITER_HH + +#include "rcecalib/analysis/CfgFileWriter.hh" + +class Fei3CfgFileWriter: public CfgFileWriter{ +public: + Fei3CfgFileWriter(){} + ~Fei3CfgFileWriter(){} + void writeDacFile(const char* filename, TH2* his); + void writeMaskFile(const char* filename, TH2* his); +}; + +#endif diff --git a/rce/rcecalib/analysis/Fei4CfgFileWriter.cc b/rce/rcecalib/analysis/Fei4CfgFileWriter.cc new file mode 100644 index 0000000000000000000000000000000000000000..8342ff516931cc66d42a7fa565442395804c3d1c --- /dev/null +++ b/rce/rcecalib/analysis/Fei4CfgFileWriter.cc @@ -0,0 +1,51 @@ +#include "rcecalib/analysis/Fei4CfgFileWriter.hh" + +#include <iostream> +#include <fstream> +#include <boost/regex.hpp> +#include <TFile.h> +#include <TH2.h> + +void Fei4CfgFileWriter::writeDacFile(const char* filename, TH2* tdac){ + std::ofstream maskfile(Form("%s.dat",filename)); + char line[512]; + for (int i=0;i<674;i++){ + if(i>1){ + sprintf(line, "%3d",i/2); + maskfile<<line; + if(i%2==0)maskfile<<"a "; + else maskfile<<"b "; + }else{ + maskfile<<"### "; + } + for (int j=1;j<=40;j++){ + if(i==0)sprintf(line, "%2d ",j); + else if(i==1)sprintf(line, "%2d ",j+40); + else { + int val = int(tdac->GetBinContent((i%2)*40+j, (i-2)/2+1)+0.1); + sprintf(line, "%2d ",val); + } + maskfile<<line; + if(j%10==0)maskfile<<" "; + } + maskfile<<std::endl; + } +} + + +void Fei4CfgFileWriter::writeMaskFile(const char* filename, TH2* histo){ + std::ofstream maskfile(Form("%s.dat",filename)); + maskfile<<"### 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76"<<std::endl; + char linenr[128]; + for(int i=1;i<=336;i++){ + sprintf(linenr,"%3d ", i); + maskfile<<linenr; + for (int j=1;j<=80;j++){ + if(histo->GetBinContent(j,i)==1)maskfile<<0; + else maskfile<<1; + if(j%10==0)maskfile<<" "; + else if(j%5==0)maskfile<<"-"; + } + maskfile<<std::endl; + } +} diff --git a/rce/rcecalib/analysis/Fei4CfgFileWriter.hh b/rce/rcecalib/analysis/Fei4CfgFileWriter.hh new file mode 100644 index 0000000000000000000000000000000000000000..972ba9a634724e4fead5a5222acebbab681dbd5a --- /dev/null +++ b/rce/rcecalib/analysis/Fei4CfgFileWriter.hh @@ -0,0 +1,14 @@ +#ifndef FEI4CFGFILEWRITER_HH +#define FEI4CFGFILEWRITER_HH + +#include "rcecalib/analysis/CfgFileWriter.hh" + +class Fei4CfgFileWriter: public CfgFileWriter{ +public: + Fei4CfgFileWriter(){} + ~Fei4CfgFileWriter(){} + void writeDacFile(const char* filename, TH2* his); + void writeMaskFile(const char* filename, TH2* his); +}; + +#endif diff --git a/rce/rcecalib/analysis/GdacAnalysis.cc b/rce/rcecalib/analysis/GdacAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c3a94dde5e3fac40198172a17de0be43e61219d --- /dev/null +++ b/rce/rcecalib/analysis/GdacAnalysis.cc @@ -0,0 +1,199 @@ +#include "rcecalib/analysis/GdacAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI4/Module.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + +void GdacAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + gStyle->SetOptFit(111); + std::map<int, std::vector<TH1D*> > histmap; + file->cd("loop2_0"); + TIter nextkey(gDirectory->GetListOfKeys()); // GDAC settings + TKey *key; + int index=0; + while ((key=(TKey*)nextkey())) { + gDirectory->cd(key->GetName()); + + + TIter snextkey(gDirectory->GetListOfKeys()); // histograms + TKey *skey; + while ((skey=(TKey*)snextkey())) { + std::string name(skey->GetName()); + boost::cmatch matches; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string chi2HistoName = boost::regex_replace (name, re2, "ChiSquare"); + TH2* histo = (TH2*)skey->ReadObj(); + TH1* chi2Histo=(TH1*)gDirectory->Get(chi2HistoName.c_str()); + assert(chi2Histo!=0); + TH1* gdacValHisto=(TH1*)gDirectory->Get(Form("GDAC_settings_Mod_%d_it_%d", id, index)); + int numfrontend=0; + if(findFEType(cfg, id)=="FEI3") numfrontend = FEI3::Module::N_FRONTENDS; + else numfrontend = FEI4::Module::N_FRONTENDS; + + char name[128]; + char title[128]; + int gdac=0; + if(histmap.find(id)==histmap.end()){ + for (int k=0;k<numfrontend;k++){ + if(numfrontend==1){ + sprintf(name, "GDAC_mod_%d", id); + sprintf(title, "GDAC vs charge module %d at %s", id, findFieldName(cfg, id)); + }else{ + sprintf(name, "GDAC_mod_%d_frontent_%i", id, k); + sprintf(title, "GDAC vs charge module %d frontend %i at %s", id, k, findFieldName(cfg, id)); + } + TH1D *hold =new TH1D (name, title, 256, -.5, 255.5); + histmap[id].push_back(hold); + } + } + for (int k=0;k<numfrontend;k++){ + + if(gdacValHisto!=0)gdac=gdacValHisto->GetBinContent(k+1); + else gdac=int(scan->getLoopVarValues(1)[index]); + + if(numfrontend==1){ + sprintf(name, "threshold_id_%d_step_%d_gdac_%d", id, index, gdac); + sprintf(title, "Threshold id=%d at %s step=%d gdac=%d", id, findFieldName(cfg, id), index, gdac); + }else{ + sprintf(name, "threshold_id_%d_frontend_%d_step_%d_gdac_%d", id, k, index, gdac); + sprintf(title, "Threshold id=%d at %s frontend=%d step=%d gdac=%d", id, findFieldName(cfg, id), k, index, gdac); + } + TH1D *fithist = new TH1D(name, title, 100, 0, 10000); + + int histnum = histo->GetNbinsX()/numfrontend; + for (int i=histnum*k+1;i<=histnum*(k+1);i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + if(chi2Histo->GetBinContent(i,j)!=0&&chi2Histo->GetBinContent(i,j)<5){ + fithist->Fill(histo->GetBinContent(i,j)); + } + } + } + fithist->Fit("gaus","lq"); + double val=fithist->GetFunction("gaus")->GetParameter(1); + double err=fithist->GetFunction("gaus")->GetParError(1); + if(val>100 && val<30000 && err>0 && err<5000 && fithist->GetEntries()>100){ //arbitrary criteria + histmap[id][k]->SetBinContent(gdac+1, val); + histmap[id][k]->SetBinError(gdac+1, err); + } + anfile->cd(); + fithist->Write(); + fithist->SetDirectory(gDirectory); + file->cd("loop2_0"); + gDirectory->cd(key->GetName()); + } + } + } + file->cd("loop2_0"); + index++; + } + anfile->cd(); + for(std::map<int, std::vector<TH1D*> >::iterator it=histmap.begin();it!=histmap.end();it++){ + int id=it->first; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + ipc::PixelModuleConfig* conf3=findFEI3Config(cfg, id); + int numfrontend=0; + if(findFEType(cfg, id)=="FEI3") numfrontend = FEI3::Module::N_FRONTENDS; + else numfrontend = FEI4::Module::N_FRONTENDS; + for (int k=0;k<numfrontend;k++){ + unsigned short confval=interpolate(id, scan->getThresholdTargetValue(), histmap[id][k]); + if(confa)confa->FEGlobal.Vthin_AltFine=confval; + if(confb)confb->FEGlobal.Vthin_AltFine=confval; + if(conf3)conf3->FEConfig[k].FEGlobal.gdac=confval; + histmap[id][k]->Write(); + histmap[id][k]->SetDirectory(gDirectory); + } + if(scan->getScanType()==RCE::PixScan::GDAC_TUNE){ + std::vector<float> varValues=scan->getLoopVarValues(2); + if(varValues.size()>=1){ + int val=(int)varValues[0]; + int ncol, nrow, nchip; + if(conf3){ + ncol=18; + nrow=160; + nchip=16; + }else{ + ncol=80; + nrow=336; + nchip=1; + } + for (int chip=0;chip<nchip;chip++){ + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + if(confa)confa->FETrims.dacThresholdTrim[col][row]=val; + else if(confb)confb->FETrims.dacThresholdTrim[col][row]=val; + else conf3->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=val; + } + } + } + + }else{ + std::cout<<"No outer loop for GDAC tuning. Not setting up TDAC values"<<std::endl; + } + } + if(confa || confb) writeFEI4Config(anfile, runno); + if (conf3) writeFEI3Config(anfile,runno); + } + + if(configUpdate()){ + writeTopFile(cfg, anfile, runno); + } +} + +unsigned short GdacAnalysis::interpolate(int id, int target, TH1D* histo){ + double lower=-1,higher=-1; + int lowerbin=0, higherbin=0; + int firstbin=-1, lastbin=-1; + for(int i=1;i<=histo->GetNbinsX();i++){ + if(histo->GetBinContent(i)!=0){ + if(firstbin==-1)firstbin=i-1; + lastbin=i-1; + if(target>=histo->GetBinContent(i)){ + lower=histo->GetBinContent(i); + lowerbin=i-1; + }else{ + higher=histo->GetBinContent(i); + higherbin=i-1; + break; + } + } + } + unsigned short confval=0; + if(lower==-1){ + std::cout<<"Target is lower than lowest scan point "<<firstbin<<" for module id="<<id<<std::endl; + confval=firstbin; + }else if (higher==-1){ + std::cout<<"Target is larger than highest scan point "<<lastbin<<" for module id="<<id<<std::endl; + confval=lastbin; + }else{ + double m=(higher-lower)/(higherbin-lowerbin); + if(m==0){ + std::cout<<"Slope is 0, no interpolation possible for module id="<<id<<std::endl; + confval=lowerbin; + }else{ + double n=higher-m*higherbin; + double x=(target-n)/m; + std::cout<<"vthin_altFine for module id="<<id<<" at a target threshold of "<<target<<" electrons is "<<x<<std::endl; + confval=x; + } + } + return confval; +} diff --git a/rce/rcecalib/analysis/GdacAnalysis.hh b/rce/rcecalib/analysis/GdacAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..3802146a1f7642b36e5496271642ed6f62de07df --- /dev/null +++ b/rce/rcecalib/analysis/GdacAnalysis.hh @@ -0,0 +1,33 @@ +#ifndef GDACANALYSIS_HH +#define GDACANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> +#include <vector> + +class ConfigGui; +class TFile; +class TH2D; +class TH1D; + +namespace RCE{ + class PixScan; +} +namespace{ + struct fitval{ + double val; + double err; + }; +} + +class GdacAnalysis: public CalibAnalysis{ +public: + GdacAnalysis(): CalibAnalysis(){} + ~GdacAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void findThreshold(TFile *anfile, int gdac, std::map<int, std::vector<fitval> > & ret, ConfigGui* cfg[]); + unsigned short interpolate(int id, int target, TH1D* histo); +}; + + +#endif diff --git a/rce/rcecalib/analysis/GdacCoarseFastAnalysis.cc b/rce/rcecalib/analysis/GdacCoarseFastAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..60d7b60a3662388fda26ddef25024d4836fbbee2 --- /dev/null +++ b/rce/rcecalib/analysis/GdacCoarseFastAnalysis.cc @@ -0,0 +1,127 @@ +#include "rcecalib/analysis/GdacCoarseFastAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI4/Module.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TStyle.h" + +void GdacCoarseFastAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + int repetitions = scan->getRepetitions(); + double targetEff = 0.5; + TKey* key; + char subdir[128]; + char name[128]; + char title[128]; + int binsx=0; + size_t numvals=scan->getLoopVarValues(1).size(); + std::map<int, hdatagdaccoarsefast> *histomap=new std::map<int, hdatagdaccoarsefast>[numvals]; + double *val=new double[numvals]; + for (size_t i=0;i<numvals;i++){ + sprintf(subdir, "/loop2_0/loop1_%d", i); + file->cd(subdir); // GDAC steps + TIter nextkey(gDirectory->GetListOfKeys()); // histos + while ((key=(TKey*)nextkey())) { + boost::cmatch matches; + boost::regex re("_(\\d+)_Occupancy_Point_000"); + if(boost::regex_search(key->GetName(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + TH2* histo = (TH2*)key->ReadObj(); + histo->SetMinimum(0); histo->SetMaximum(repetitions); + TH1* gdachisto=(TH1*)gDirectory->Get(Form("GDACCoarse_settings_Mod_%d_it_%d", id, i)); + assert(gdachisto); + histomap[i][id].occupancy=histo; + histomap[i][id].gdac=gdachisto; + binsx=gdachisto->GetNbinsX(); + } + } + } + for(std::map<int, hdatagdaccoarsefast>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + float pct = 100; + sprintf(name, "BestOcc_Mod_%d", id); + sprintf(title, "Best Occupancy Module %d at %s", id, findFieldName(cfg, id)); + TH1F* occBest=new TH1F(name, title, binsx, 0, binsx); + occBest->SetMinimum(0); occBest->SetMaximum(pct); + occBest->GetXaxis()->SetTitle("Chip"); + occBest->GetYaxis()->SetTitle("Occupancy[%]"); + + sprintf(name, "BestGdacCoarse_Mod_%d", id); + sprintf(title, "Best GdacCoarse Module %d at %s", id, findFieldName(cfg, id)); + TH1F* gdac=new TH1F(name, title, binsx, 0, binsx); + gdac->GetXaxis()->SetTitle("Chip"); + gdac->GetYaxis()->SetTitle("GdacCoarse"); + + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + + int ncol, nrow, nchip, maxval, maxstage; + if (confa) { + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=120; + } + else { + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=24; + } + + int nstages = scan->getMaskStageSteps(); + int npixtotal = nchip*ncol*nrow; + float npixused=float(nstages)/float(maxstage)*npixtotal; + + int nfe = binsx; + for (int i = 0; i < nfe; i++){ + int index = 0; + for (size_t k = 0; k < numvals; k++) { + int histfebins = (histomap[k][id].occupancy->GetNbinsX())/nfe; + int nbinsy = histomap[k][id].occupancy->GetNbinsY(); + float meanEff = 0.0; + for (int binx = histfebins*i+1; binx <= histfebins*(i+1); binx++) { + for (int biny = 1; biny <= nbinsy; biny++) { + meanEff += histomap[k][id].occupancy->GetBinContent(binx, biny) / repetitions; + } + } + val[k] = meanEff/npixused; + if (val[k] < targetEff) { + index = k; + break; + } + } + occBest->SetBinContent(i+1, pct*val[index]); + gdac->SetBinContent(i+1, histomap[index][id].gdac->GetBinContent(i+1)); + std::cout<<"Best GDACCoarse for module " << id << " is " << histomap[index][id].gdac->GetBinContent(i+1) << std::endl; + if(confa)confa->FEGlobal.Vthin_AltCoarse = histomap[index][id].gdac->GetBinContent(i+1); + if(confb)confb->FEGlobal.Vthin_AltCoarse = histomap[index][id].gdac->GetBinContent(i+1); + } + + anfile->cd(); + + occBest->Write(); + occBest->SetDirectory(gDirectory); + + gdac->Write(); + gdac->SetDirectory(gDirectory); + + if(confa || confb) writeFEI4Config(anfile, runno); + } + if (configUpdate()) writeTopFile(cfg, anfile, runno); + delete [] histomap; + delete [] val; +} diff --git a/rce/rcecalib/analysis/GdacCoarseFastAnalysis.hh b/rce/rcecalib/analysis/GdacCoarseFastAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..ab2380de59aae8ef2a67e1ba1a9703fe2f8259dd --- /dev/null +++ b/rce/rcecalib/analysis/GdacCoarseFastAnalysis.hh @@ -0,0 +1,31 @@ +#ifndef GDACCOARSEFASTANALYSIS_HH +#define GDACCOARSEFASTANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> +#include <vector> + +class ConfigGui; +class TFile; +class TH2; +class TH1; + +namespace RCE{ + class PixScan; +} +namespace{ + struct hdatagdaccoarsefast{ + TH2* occupancy; + TH1* gdac; + }; +} + +class GdacCoarseFastAnalysis: public CalibAnalysis{ +public: + GdacCoarseFastAnalysis(): CalibAnalysis(){} + ~GdacCoarseFastAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/GdacFastAnalysis.cc b/rce/rcecalib/analysis/GdacFastAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..dc9e0f7747a068098648e480f9473fe181ff93a0 --- /dev/null +++ b/rce/rcecalib/analysis/GdacFastAnalysis.cc @@ -0,0 +1,155 @@ +#include "rcecalib/analysis/GdacFastAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI4/Module.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TStyle.h" + +void GdacFastAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + int repetitions = scan->getRepetitions(); + double targetEff = 0.5; + TKey* key; + char subdir[128]; + char name[128]; + char title[128]; + int binsx=0; + size_t numvals=scan->getLoopVarValues(1).size(); + std::map<int, hdatagdacfast> *histomap=new std::map<int, hdatagdacfast>[numvals]; + double *val=new double[numvals]; + for (size_t i=0;i<numvals;i++){ + sprintf(subdir, "/loop2_0/loop1_%d", i); + file->cd(subdir); // GDAC steps + TIter nextkey(gDirectory->GetListOfKeys()); // histos + while ((key=(TKey*)nextkey())) { + boost::cmatch matches; + boost::regex re("_(\\d+)_Occupancy_Point_000"); + if(boost::regex_search(key->GetName(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + TH2* histo = (TH2*)key->ReadObj(); + histo->SetMinimum(0); histo->SetMaximum(repetitions); + TH1* gdachisto=(TH1*)gDirectory->Get(Form("GDAC_settings_Mod_%d_it_%d", id, i)); + assert(gdachisto); + histomap[i][id].occupancy=histo; + histomap[i][id].gdac=gdachisto; + binsx=gdachisto->GetNbinsX(); + } + } + } + for(std::map<int, hdatagdacfast>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + float pct = 100; + sprintf(name, "BestOcc_Mod_%d", id); + sprintf(title, "Best Occupancy Module %d at %s", id, findFieldName(cfg, id)); + TH1F* occBest=new TH1F(name, title, binsx, 0, binsx); + occBest->SetMinimum(0); occBest->SetMaximum(pct); + occBest->GetXaxis()->SetTitle("Chip"); + occBest->GetYaxis()->SetTitle("Occupancy[%]"); + + sprintf(name, "BestGdac_Mod_%d", id); + sprintf(title, "Best Gdacs Module %d at %s", id, findFieldName(cfg, id)); + TH1F* gdac=new TH1F(name, title, binsx, 0, binsx); + gdac->GetXaxis()->SetTitle("Chip"); + gdac->GetYaxis()->SetTitle("Gdac"); + + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + ipc::PixelModuleConfig* conf3=findFEI3Config(cfg, id); + + int ncol, nrow, nchip, maxval, maxstage; + if (confa) { + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=120; + } + else if (confb) { + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=24; + } + else { + ncol=18; + nrow=160; + nchip=16; + maxval=32; + maxstage=32; + } + int nstages = scan->getMaskStageSteps(); + int npixtotal = nchip*ncol*nrow; + float npixused=float(nstages)/float(maxstage)*npixtotal; + + int nfe = binsx; + for (int i = 0; i < nfe; i++){ + double bestval = 10*targetEff; // must be larger than 1 (with possibilty of double hit) + int index = 0; + for (size_t k = 0; k < numvals; k++) { + int histfebins = (histomap[k][id].occupancy->GetNbinsX())/nfe; + int nbinsy = histomap[k][id].occupancy->GetNbinsY(); + float meanEff = 0.0; + for (int binx = histfebins*i+1; binx <= histfebins*(i+1); binx++) { + for (int biny = 1; biny <= nbinsy; biny++) { + meanEff += histomap[k][id].occupancy->GetBinContent(binx, biny) / repetitions; + } + } + val[k] = meanEff/npixused; + if (fabs(val[k]-targetEff) < bestval) { + index = k; + bestval = fabs(val[k]-targetEff); + } + } + occBest->SetBinContent(i+1, pct*val[index]); + gdac->SetBinContent(i+1, histomap[index][id].gdac->GetBinContent(i+1)); + std::cout<<"Best GDAC for module " << id << " is " << histomap[index][id].gdac->GetBinContent(i+1) << std::endl; + if(confa)confa->FEGlobal.Vthin_AltFine = histomap[index][id].gdac->GetBinContent(i+1); + if(confb)confb->FEGlobal.Vthin_AltFine = histomap[index][id].gdac->GetBinContent(i+1); + if(conf3)conf3->FEConfig[i].FEGlobal.gdac = histomap[index][id].gdac->GetBinContent(i+1); + } + + anfile->cd(); + + occBest->Write(); + occBest->SetDirectory(gDirectory); + + gdac->Write(); + gdac->SetDirectory(gDirectory); + + if(scan->getScanType()==RCE::PixScan::GDAC_FAST_TUNE){ + std::vector<float> varValues=scan->getLoopVarValues(2); + if(varValues.size()>=1){ + int val=(int)varValues[0]; + for (int chip=0;chip<nchip;chip++){ + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + if(confa)confa->FETrims.dacThresholdTrim[col][row]=val; + else if(confb)confb->FETrims.dacThresholdTrim[col][row]=val; + else conf3->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=val; + } + } + } + + }else{ + std::cout<<"No outer loop for GDAC tuning. Not setting up TDAC values"<<std::endl; + } + } + if(confa || confb) writeFEI4Config(anfile, runno); + if (conf3) writeFEI3Config(anfile,runno); + } + if (configUpdate()) writeTopFile(cfg, anfile, runno); + delete [] histomap; + delete [] val; +} diff --git a/rce/rcecalib/analysis/GdacFastAnalysis.hh b/rce/rcecalib/analysis/GdacFastAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..da831bf2207d01ca9d4f49ec25484d722e3b7bd4 --- /dev/null +++ b/rce/rcecalib/analysis/GdacFastAnalysis.hh @@ -0,0 +1,31 @@ +#ifndef GDACFASTANALYSIS_HH +#define GDACFASTANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> +#include <vector> + +class ConfigGui; +class TFile; +class TH2; +class TH1; + +namespace RCE{ + class PixScan; +} +namespace{ + struct hdatagdacfast{ + TH2* occupancy; + TH1* gdac; + }; +} + +class GdacFastAnalysis: public CalibAnalysis{ +public: + GdacFastAnalysis(): CalibAnalysis(){} + ~GdacFastAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/HistoViewerGui.cc b/rce/rcecalib/analysis/HistoViewerGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..d3aa73cd2457b60d56e73e93fc7db0935ae99402 --- /dev/null +++ b/rce/rcecalib/analysis/HistoViewerGui.cc @@ -0,0 +1,194 @@ +#include "rcecalib/analysis/HistoViewerGui.hh" +#include "rcecalib/server/PixScan.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TH1.h" +#include "TKey.h" +#include "TGIcon.h" +#include "TGMenu.h" +#include "TCanvas.h" +#include "TGCanvas.h" +#include "TGListTree.h" +#include "TRootEmbeddedCanvas.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TStyle.h> +#include <boost/regex.hpp> +#include <assert.h> +#include <iostream> +#include <time.h> +#include <sys/stat.h> +#include <fstream> +#include <list> +#include <pthread.h> +#include <vector> +#include <stdlib.h> + +using namespace RCE; + +HistoViewerGui::~HistoViewerGui(){ + Cleanup(); +} + +HistoViewerGui::HistoViewerGui(const char* filename, const TGWindow *p,UInt_t w,UInt_t h) + : TGMainFrame(p,w,h) { + + // connect x icon on window manager + Connect("CloseWindow()","HistoViewerGui",this,"quit()"); + + TGMenuBar *menubar=new TGMenuBar(this,1,1,kHorizontalFrame | kRaisedFrame); + TGLayoutHints *menubarlayout=new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + // menu "File" + TGPopupMenu* filepopup=new TGPopupMenu(gClient->GetRoot()); + //filepopup->AddEntry("&Load Config",LOAD); + //filepopup->AddEntry("&Save Config",SAVE); + filepopup->AddSeparator(); + filepopup->AddEntry("&Quit",QUIT); + menubar->AddPopup("&File",filepopup,menubarlayout); + TGPopupMenu* plotpopup=new TGPopupMenu(gClient->GetRoot()); + plotpopup->AddEntry("&Save as png",PNG); + plotpopup->AddEntry("&Savefd as pdf",PDF); + menubar->AddPopup("&Plot",plotpopup,menubarlayout); + plotpopup->Connect("Activated(Int_t)","HistoViewerGui",this,"handlePlotMenu(Int_t)"); + + AddFrame(menubar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,2)); + + filepopup->Connect("Activated(Int_t)","HistoViewerGui",this,"handleFileMenu(Int_t)"); + + TGVerticalFrame* datapanel=new TGVerticalFrame(this,1,1, kSunkenFrame); + // scan panel + TGHorizontalFrame *datapanel5 = new TGHorizontalFrame(datapanel, 2, 2, kSunkenFrame); + datapanel->AddFrame(datapanel5,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + AddFrame(datapanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + TGVerticalFrame *treepanel = new TGVerticalFrame(datapanel5, 150, 2, kSunkenFrame); + datapanel5->AddFrame(treepanel,new TGLayoutHints(kLHintsExpandY)); + TGVerticalFrame *plotpanel = new TGVerticalFrame(datapanel5, 2, 2, kSunkenFrame); + datapanel5->AddFrame(plotpanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + m_tgc=new TGCanvas(treepanel, 300,100); + //TGViewPort* vp=tgc->GetViewPort(); + m_tree=new TGListTree(m_tgc, kHorizontalFrame); + m_tree->Connect("Clicked(TGListTreeItem*, Int_t)","HistoViewerGui", this, "displayHisto(TGListTreeItem*, Int_t)"); + //tree->AddItem(0,"/"); + treepanel->AddFrame(m_tgc,new TGLayoutHints(kLHintsExpandY)); + m_canvas=new TRootEmbeddedCanvas("Canvas",plotpanel,100,100); + m_canvas->GetCanvas()->GetPad(0)->SetRightMargin(0.15); + plotpanel->AddFrame(m_canvas,new TGLayoutHints(kLHintsExpandY|kLHintsExpandX)); + + SetWindowName("HistoViewer GUI"); + Resize(w,h); + Layout(); + MapSubwindows(); + MapWindow(); + m_file=new TFile(filename,""); + TGListTreeItem* root=m_tree->AddItem(0,"Histos"); + m_file->cd(); + fillHistoTree(root); + updateTree(); +} + +void HistoViewerGui::quit(){ + m_file->Close(); + gApplication->Terminate(0); +} + +void HistoViewerGui::handlePlotMenu(int item){ + if(item==PNG){ + m_canvas->GetCanvas()->SaveAs("c1.png"); + }else if(item==PDF){ + m_canvas->GetCanvas()->SaveAs("c1.pdf"); + } +} + +void HistoViewerGui::handleFileMenu(int item){ + if(item==QUIT)quit(); +} +void HistoViewerGui::clearTree(){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + if(root) m_tree->DeleteChildren(root); + root->SetOpen(false); + updateTree(); +} +void HistoViewerGui::updateTree(){ + int x=m_tgc->GetViewPort()->GetX(); + int y=m_tgc->GetViewPort()->GetY(); + int w=m_tgc->GetViewPort()->GetWidth(); + int h=m_tgc->GetViewPort()->GetHeight(); + m_tree->DrawRegion(x,y,w,h); +} + +void HistoViewerGui::fillHistoTree(TGListTreeItem* branch){ + const TGPicture *thp = gClient->GetPicture("h1_t.xpm"); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + while ((key=(TKey*)nextkey())) { + TObject *obj = key->ReadObj(); + if(std::string(obj->ClassName())=="TDirectoryFile"){ + gDirectory->cd(key->GetName()); + TGListTreeItem* subdir=m_tree->AddItem(branch,key->GetName()); + fillHistoTree(subdir); + }else{ + std::string hisname(key->GetName()); + boost::regex re("at ([AC]\\d+-\\d+)"); + boost::cmatch matches; + if(boost::regex_search(key->GetTitle(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + hisname=match+":"+hisname; + } + TGListTreeItem* his=m_tree->AddItem(branch,hisname.c_str()); + his->SetPictures(thp, thp); + } + delete obj; + } + gDirectory->cd(".."); +} +void HistoViewerGui::displayHisto(TGListTreeItem* item, int b){ + TGListTreeItem *parent=item->GetParent(); + if(parent==0)return; + std::string histonames=item->GetText(); + if(histonames[4]==':')histonames=histonames.substr(5); + const char* histoname=histonames.c_str(); + if(std::string(histoname).substr(0,4)=="loop")return; + if(std::string(histoname).substr(0,8)=="Analysis")return; + TGListTreeItem *parent1=parent->GetParent(); + if(parent1==0)m_file->cd(); + else{ + TGListTreeItem *parent2=parent1->GetParent(); + if(parent2==0)m_file->cd(parent->GetText()); + else{ + char dir[128]; + sprintf(dir, "%s/%s",parent1->GetText(), parent->GetText()); + m_file->cd(dir); + } + } + m_histo=(TH1*)gDirectory->Get(histoname); + assert(m_histo!=0); + m_histo->SetMinimum(0); + if(m_histo->GetDimension()==1)m_histo->Draw(); + else { + m_histo->Draw("colz"); + } + m_canvas->GetCanvas()->Update(); +} + + +//==================================================================== +int main(int argc, char **argv){ + if(argc!=2){ + std::cout<<"Usage: histoViewer rootfile_name"<<std::endl; + exit(0); + } + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + const char *filename=argv[1]; + std::cout<<"Filename "<<filename<<std::endl; + TApplication theapp("app",&argc,argv); + new HistoViewerGui(filename, gClient->GetRoot(),800,600); + theapp.Run(); + return 0; +} + + diff --git a/rce/rcecalib/analysis/HistoViewerGui.hh b/rce/rcecalib/analysis/HistoViewerGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..82065a078eb1b67881ea1db17f66819b5eff8bab --- /dev/null +++ b/rce/rcecalib/analysis/HistoViewerGui.hh @@ -0,0 +1,45 @@ +#ifndef HISTOVIEWERGUI_HH +#define HISTOVIEWERGUI_HH + +#include "TGMdiMainFrame.h" +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include "TFile.h" +#include "TH2F.h" +#include <string> + + +class TGListTree; +class TGListTreeItem; +class TH1; +class TRootEmbeddedCanvas; + +class HistoViewerGui: public TGMainFrame { +public: + HistoViewerGui(const char* filename, const TGWindow *p,UInt_t w,UInt_t h); + virtual ~HistoViewerGui(); + void handleFileMenu(Int_t); + void handlePlotMenu(Int_t); + void quit(); + void clearTree(); + void updateTree(); + void displayHisto(TGListTreeItem* item, int b); +private: + + void fillHistoTree(TGListTreeItem* branch); + enum Filemenu {LOAD, SAVE, QUIT}; + enum Plotmenu {PNG, PDF}; + TGTextButton* *m_quit; + TGListTree* m_tree; + TH1 *m_histo; + TRootEmbeddedCanvas *m_canvas; + TFile *m_file, *m_anfile; + std::string m_dir; + bool m_delhisto; + TGCanvas *m_tgc; + int m_indx; + +ClassDef (HistoViewerGui,0) +}; +#endif diff --git a/rce/rcecalib/analysis/Iff_Analysis.cc b/rce/rcecalib/analysis/Iff_Analysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..62cd9cc51d5c5c9de0a94e26e8fe0db2ea4e3ce1 --- /dev/null +++ b/rce/rcecalib/analysis/Iff_Analysis.cc @@ -0,0 +1,169 @@ +#include "rcecalib/analysis/Iff_Analysis.hh" +#include "rcecalib/config/FEI4/Module.hh" +#include "rcecalib/config/FEI3/Module.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TH1F.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include <math.h> + +using namespace RCE; + +void IffAnalysis::analyze(TFile* file, TFile *anfile, PixScan* scan, int runno, ConfigGui* cfg[]){ + printf("Begin IFF Analysis\n"); + float target = float(scan->getTotTargetValue()); + printf("Target Tot Value: %2.1f\n",target); + std::vector<float> loopVar=scan->getLoopVarValues(0); + size_t numvals=loopVar.size(); + //TH1F* iffhis = new TH1F("iff_v_module","Best IF Setting",128,0,127); + //iffhis->GetXaxis()->SetTitle("Module"); + //iffhis->GetYaxis()->SetTitle("IF Setting"); + std::map<int, odata> *histomap=new std::map<int, odata>[numvals]; + TKey *key; + for (size_t i=0;i<numvals;i++){ + file->cd("loop1_0"); + TIter nextkey(gDirectory->GetListOfKeys()); + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::regex re(Form("_(\\d+)_Occupancy_Point_%03d", i)); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int lnm=strtol(match.c_str(),0,10); + histomap[i][lnm].occ = (TH2*)key->ReadObj(); + boost::regex re2("Occupancy"); + std::string totHistoName = boost::regex_replace (name, re2, "ToT"); + histomap[i][lnm].tot=(TH2*)gDirectory->Get(totHistoName.c_str()); + } + } + } + // write out results in a file + std::string fn(anfile->GetName()); + std::string name="IFscan_results.dat"; + boost::regex re("[^/]*\\.root"); + std::string maskfilename = boost::regex_replace (fn, re, name); + std::ofstream maskfile(maskfilename.c_str()); + for(std::map<int, odata>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + ipc::PixelModuleConfig* confm=findFEI3Config(cfg, id); + int nchip; + int nrow; + int ncol; + int fei; + if(findFEType(cfg, id)=="FEI3"){ + nchip=FEI3::Module::N_FRONTENDS; + nrow=FEI3::Frontend::N_ROWS; + ncol=FEI3::Frontend::N_COLS; + fei=3; + }else{ + nchip=FEI4::Module::N_FRONTENDS; + nrow=FEI4::PixelRegister::N_ROWS; + ncol=FEI4::PixelRegister::N_COLS; + fei=4; + } + for(int chip=0;chip<nchip;chip++){ + TH1F* ahis; + if(findFEType(cfg, id)=="FEI3"){ + ahis = new TH1F(Form("Mod_%i_FE_%i_ToT_v_IFF",id, chip), + Form("ToT vs. IFF Mod %d FE %d at %s", id, chip, findFieldName(cfg, id)), + 256,-.5,255.5); + }else{ + ahis = new TH1F(Form("Mod_%i_ToT_v_IFF",id), + Form("ToT vs. IFF Mod %d at %s", id, findFieldName(cfg, id)), + 256,-.5,255.5); + } + ahis->GetXaxis()->SetTitle("IF Setting"); + ahis->GetYaxis()->SetTitle("Time over Threshold"); + int value = 0; + float min = 999999.9; + std::vector<float> vals; + for(unsigned i = 0; i < numvals; i++){ + double tot = 0.0; + double tot2 = 0.0; + float numBadPixels = 0.0; + for(int j = chip*ncol+1; j <= (chip+1)*ncol; j++){ + //for(int j = 1; j <= histomap[i][id].occ->GetNbinsX(); j++){ + for(int k = 1; k <= nrow; k++){ + int nhits = int(histomap[i][id].occ->GetBinContent(j,k)); + if(nhits == scan->getRepetitions()) { + double totval=histomap[i][id].tot->GetBinContent(j,k) / nhits; + tot += totval; + tot2 += totval*totval; + } else numBadPixels++; + } + } + float norm= float(nrow*ncol - numBadPixels); + if(norm!=0){ + tot/=norm; + tot2=sqrt(tot2/norm-tot*tot); + }else{ + tot=0; + tot2=0; + } + int bin=ahis->FindBin(loopVar[i]); + ahis->SetBinContent(bin,tot); + vals.push_back(tot); + ahis->SetBinError(bin,tot2); + if(fabs(tot - target) < min){ + min = fabs(tot - target); + value = i; + } + } + // interpolate + int intval=int(loopVar[value]+.1); + //below found value + if(value!=0 && vals[value-1]!=vals[value] && loopVar[value]!=loopVar[value-1]){ + float m=(vals[value]-vals[value-1])/(loopVar[value]-loopVar[value-1]); + float n=vals[value]-m*loopVar[value]; + for (int i=int(loopVar[value-1]+1.1);i<int(loopVar[value]+0.1);i++){ + if(fabs(m*i+n-target)<min){ + min=fabs(m*i+n-target); + intval=i; + } + } + } + //above found value + if((unsigned)value!=numvals-1 && vals[value+1]!=vals[value] && loopVar[value]!=loopVar[value+1]){ + float m=(vals[value]-vals[value+1])/(loopVar[value]-loopVar[value+1]); + float n=vals[value]-m*loopVar[value]; + for (int i=int(loopVar[value]+1.1);i<int(loopVar[value+1]+0.1);i++){ + if(fabs(m*i+n-target)<min){ + min=fabs(m*i+n-target); + intval=i; + } + } + } + printf("Module ID: %d Closest Setting: %d \nDistance From Target: %4.3f\n",id, intval,min); + char line[512]; + if(fei==4) sprintf(line, "Module ID: %d Best setting: %d\n", id, intval); + else sprintf(line, "Module ID: %d Chip: %d Best setting: %d\n", id, chip, intval); + maskfile<<line; + anfile->cd(); + ahis->Write(); + ahis->SetDirectory(gDirectory); + if(confa) confa->FEGlobal.PrmpVbpf=intval; + if(confb) confb->FEGlobal.PrmpVbpf=intval; + if(confm) confm->FEConfig[chip].FEGlobal.dacIF=intval; + } + for(unsigned i = 0; i < numvals; i++){ + delete histomap[i][id].occ; + delete histomap[i][id].tot; + delete histomap[i][id].tot2; + } + if(confa || confb) writeFEI4Config(anfile, runno); + if(confm)writeFEI3Config(anfile, runno); + } + if(configUpdate())writeTopFile(cfg, anfile, runno); + printf("Done Analysis\n"); + delete [] histomap; +} + diff --git a/rce/rcecalib/analysis/Iff_Analysis.hh b/rce/rcecalib/analysis/Iff_Analysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..516be9a7d6cb76f85f59aee353c0a2ea49215f8d --- /dev/null +++ b/rce/rcecalib/analysis/Iff_Analysis.hh @@ -0,0 +1,26 @@ +#ifndef IFFANALYSIS2_HH +#define IFFANALYSIS2_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +class TFile; +class TH2; +namespace RCE{ + class PixScan; +} + +class IffAnalysis: public CalibAnalysis{ +public: + struct odata{ + TH2* occ; + TH2* tot; + TH2* tot2; + }; + IffAnalysis(): CalibAnalysis(){} + ~IffAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/Makefile b/rce/rcecalib/analysis/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3cd076af001b27a1deb669dc2c604a7bd6326844 --- /dev/null +++ b/rce/rcecalib/analysis/Makefile @@ -0,0 +1,21 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +include $(RELEASE_DIR)/make/sw/rootcint.mk +endif diff --git a/rce/rcecalib/analysis/MergeMaskFilesFei4.cc b/rce/rcecalib/analysis/MergeMaskFilesFei4.cc new file mode 100644 index 0000000000000000000000000000000000000000..f26133f7cfbd33675fb95e2e8c2453a0b827dc6f --- /dev/null +++ b/rce/rcecalib/analysis/MergeMaskFilesFei4.cc @@ -0,0 +1,50 @@ +#include <iostream> +#include <fstream> +#include <TH2D.h> +#include "rcecalib/analysis/Fei4CfgFileWriter.hh" +#include <boost/algorithm/string.hpp> + +const unsigned int NROWS=336; +const unsigned int NCOLS=80; + +void fillMask(TH2D& histo, const char* filename){ + std::string inpline; + unsigned short row=0; + std::ifstream maskfile(filename); + while(true){ + getline(maskfile, inpline); + if(maskfile.eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" -"), boost::token_compress_on ); + if(splitVec.size()!=17){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + int r=strtol(splitVec[0].c_str(),0,10); + assert(r==++row);//check and increment row number + std::string oneline; + for(int i=1;i<17;i++)oneline+=splitVec[i]; //concatenate everyting. + assert(oneline.size()==NCOLS); + for(unsigned int i=0;i<NCOLS;i++){ + if(oneline[i]=='0')histo.SetBinContent(i+1, row, 1); + } + } + } + assert(row==NROWS); +} + + +int main(int argc, char **argv){ + if(argc<4){ + std::cout<<"Usage: mergeMasksFei4 outfile maskfile1 maskfile2 ..."<<std::endl; + exit(0); + } + TH2D mask("mask","mask", NCOLS, 0, NCOLS, NROWS, 0, NROWS); + for(int i=2;i<argc;i++){ + fillMask(mask, argv[i]); + } + Fei4CfgFileWriter fw; + fw.writeMaskFile(argv[1], &mask); +} diff --git a/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.cc b/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..a7b9e08568a113fc341b3815590554757f5814a6 --- /dev/null +++ b/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.cc @@ -0,0 +1,70 @@ +#include "rcecalib/analysis/ModuleCrosstalkAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/ConfigGui.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +using namespace RCE; + +void ModuleCrosstalkAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Module crosstalk analysis"<<std::endl; + unsigned int numval=scan->getLoopVarValues(0).size(); + unsigned short trgmask=scan->getModuleTrgMask(); + file->cd(); + TIter nextkey(gDirectory->GetListOfKeys()); + + TKey *key; + boost::regex re("_(\\d+)_Mean"); + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + + int outlink = 99; + for(int i_conf=0;i_conf<ConfigGui::MAX_MODULES;i_conf++){ + if(cfg[i_conf]->isIncluded() && cfg[i_conf]->getId()==id){ + outlink = cfg[i_conf]->getOutLink(); + } + } + + if(((1<<outlink)&trgmask)==0)continue; + TH2* histo = (TH2*)key->ReadObj(); + TH2D* mhis=new TH2D(Form("Hits_Mod_%d",id), Form("All Hits Mod %d at %s", id, findFieldName(cfg, id)), + histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax(), + histo->GetNbinsY(), histo->GetYaxis()->GetXmin(), histo->GetYaxis()->GetXmax()); + mhis->GetXaxis()->SetTitle("Column"); + mhis->GetYaxis()->SetTitle("Row"); + TH1D* hits1d=new TH1D(Form("HitsPerBin_Mod_%d", id), + Form("Hits per bin Mod %d at %s", id, findFieldName(cfg, id)), + numval, -.5, (float)numval-.5) ; + hits1d->GetXaxis()->SetTitle("Scan Point"); + + for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (name, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + assert(occHisto); + mhis->Add(occHisto); + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } + anfile->cd(); + mhis->Write(); + mhis->SetDirectory(gDirectory); + hits1d->Write(); + hits1d->SetDirectory(gDirectory); + delete histo; + file->cd(); //change back to this directory, because will need to access its histograms later + } + } +} + diff --git a/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.hh b/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..2032e40b4da1e7b26c4f0e5a6c4f1fc9846288bf --- /dev/null +++ b/rce/rcecalib/analysis/ModuleCrosstalkAnalysis.hh @@ -0,0 +1,21 @@ +#ifndef MODULECROSSTALKANALYSIS_HH +#define MODULECROSSTALKANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class ModuleCrosstalkAnalysis: public CalibAnalysis{ +public: + ModuleCrosstalkAnalysis(): CalibAnalysis(){} + ~ModuleCrosstalkAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/MultiTrigAnalysis.cc b/rce/rcecalib/analysis/MultiTrigAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..0570e134733daf7578de9986c938ac4b9b5f35df --- /dev/null +++ b/rce/rcecalib/analysis/MultiTrigAnalysis.cc @@ -0,0 +1,263 @@ +#include "rcecalib/analysis/MultiTrigAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + + +void MultiTrigAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"MultiTrig analysis"<<std::endl; + unsigned int numval=scan->getLoopVarValues(0).size(); + const int totalScans=scan->getLoopVarValues(1).size(); + + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + + float xVals[totalScans]; + + std::map<int, std::vector<TH1D*> > histoMeanScan; + std::map<int, std::vector<TH1D*> > histoSigmaScan; + std::map<int, std::vector<float> > meanVals; + std::map<int, std::vector<float> > sigmaVals; + + // float meanVals[totalScans][2]; + // float sigmaVals[totalScans][2]; + + + float xMin = scan->getLoopVarValues(1).at(0); + float xMax = scan->getLoopVarValues(1).at(totalScans-1); + if(xMax<xMin){ + float xtemp = xMax; + xMax = xMin; + xMin = xtemp; + } + + int nScanBins = (xMax - xMin + 3); + + + //loop over the different values of multitrig_interval + for(int iScan = 0; iScan<totalScans; iScan++){ + file->cd(Form("loop1_%d",iScan)); + + std::map<int, TH1D*> histmap; + boost::regex re0("_(\\d+)_Trig0_Mean"); + boost::regex re1("_(\\d+)_Trig1_Mean"); + boost::regex re2("Mean"); + + int trigId=-1; + TIter nextkey(gDirectory->GetListOfKeys()); // histograms + TKey *key; + + while ((key=(TKey*)nextkey())) { + std::string hname(key->GetName()); + boost::cmatch matches; + + char name[128]; + char title[128]; + + bool foundMatch=false; + if(boost::regex_search(hname.c_str(), matches, re0)){ + trigId=0; + foundMatch=true; + } + else if(boost::regex_search(hname.c_str(), matches, re1)){ + trigId=1; + foundMatch=true; + } + + if(foundMatch){ + + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + // std::cout<<"Match = "<<match.c_str()<<std::endl; + // std::cout<<"name = "<<hname.c_str()<<std::endl; + + int id=strtol(match.c_str(),0,10); + std::string chi2HistoName = boost::regex_replace (hname, re2, "ChiSquare"); + std::string sigmaHistoName = boost::regex_replace (hname, re2, "Sigma"); + TH2* histo = (TH2*)key->ReadObj(); + //std::cout<<"Looking for "<<chi2HistoName.c_str()<<std::endl; + + TH2* chi2Histo=(TH2*)gDirectory->Get(chi2HistoName.c_str()); + TH2* sigmahisto=(TH2*)gDirectory->Get(sigmaHistoName.c_str()); + assert(chi2Histo!=0); + assert(sigmahisto!=0); + int binsx=histo->GetNbinsX(); + int binsy=histo->GetNbinsY(); + sprintf(name, "thresh2d_%d_Mod_%d_Trig%d", iScan,id,trigId); + sprintf(title, "Thresholds Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + TH2F* thresh2d=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + thresh2d->GetXaxis()->SetTitle("Column"); + thresh2d->GetYaxis()->SetTitle("Row"); + sprintf(name, "thresh1d_%d_Mod_%d_Trig%d", iScan, id, trigId); + sprintf(title, "Thresholds 2D Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + int nbins=binsx*binsy; + TH1F* thresh1d=new TH1F(name, title, nbins, 0, (float)nbins); + thresh1d->GetXaxis()->SetTitle("Channel"); + thresh1d->SetOption("p9"); + sprintf(name, "sigma1d_%d_Mod_%d_Trig%d", iScan, id, trigId); + sprintf(title, "Sigma Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + TH1F* sigma1d=new TH1F(name, title, nbins, 0, (float)nbins); + sigma1d->GetXaxis()->SetTitle("Channel"); + sigma1d->SetOption("p9"); + sprintf(name, "threshdist_%d_Mod_%d_Trig%d", iScan, id, trigId); + sprintf(title, "Threshold distribution Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + TH1F* threshdist=new TH1F(name, title, 500, 1000, 6000); + threshdist->GetXaxis()->SetTitle("Threshold"); + sprintf(name, "sigmadist_%d_Mod_%d_Trig%d", iScan, id, trigId); + sprintf(title, "Sigma distribution Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + TH1F* sigmadist=new TH1F(name, title, 100, 0, 500); + sigmadist->GetXaxis()->SetTitle("Sigma"); + sprintf(name, "BadPixels_%d_Mod_%d_Trig%d", iScan, id, trigId); + sprintf(title, "Bad Pixels Module %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan); + TH2F* bad=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + bad->GetXaxis()->SetTitle("Column"); + bad->GetYaxis()->SetTitle("Row"); + TH1D* hits1d=new TH1D(Form("HitsPerBin_%d_Mod_%d_Trig%d", iScan, id, trigId), Form("Hits per bin Mod %d at %s Trig %d, Scan %d", id, findFieldName(cfg,id), trigId, iScan), numval, -.5, (float)numval-.5) ; + hits1d->GetXaxis()->SetTitle("Scan Point"); + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + thresh2d->SetBinContent(i,j,histo->GetBinContent(i,j)); + thresh1d->SetBinContent((i-1)*histo->GetNbinsY()+j, histo->GetBinContent(i,j)); + threshdist->Fill(histo->GetBinContent(i,j)); + sigma1d->SetBinContent((i-1)*histo->GetNbinsY()+j, sigmahisto->GetBinContent(i,j)); + sigmadist->Fill(sigmahisto->GetBinContent(i,j)); + if(chi2Histo->GetBinContent(i,j)==0)bad->SetBinContent(i,j,1); + } + } + TF1 gauss("gauss", "gaus", 100, 10000); + gauss.SetParameter(0, threshdist->GetMaximum()); + gauss.SetParameter(1, threshdist->GetMaximumBin()*threshdist->GetBinWidth(1)); + threshdist->Fit(&gauss,"q", "", 100, 10000); + sigmadist->Fit("gaus","q"); + + for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (hname, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"Looking for "<<histoName.c_str()<<std::endl; + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } + + xVals[iScan] = scan->getLoopVarValues(1).at(iScan); + + + if(histoMeanScan.find(id)==histoMeanScan.end()){ + + std::vector<TH1D*> temphistMean(2); + std::vector<TH1D*> temphistSigma(2); + + for(int iTrig=0; iTrig<2; iTrig++){ + temphistMean[iTrig] = new TH1D(Form("MeanScan_Mod%d_Trig%d",id,iTrig),Form("Threshold Mean versus Interval for Module %d, Trigger %d",id,iTrig+1), nScanBins,xMin-1,xMax+1); + temphistMean[iTrig]->GetXaxis()->SetTitle("Interval between 1st and 2nd inject"); + temphistMean[iTrig]->GetYaxis()->SetTitle("Threshold Mean, Ne^{-}"); + temphistMean[iTrig]->SetOption("P"); + temphistMean[iTrig]->SetMarkerStyle(2); + temphistMean[iTrig]->SetMarkerSize(2); + + temphistSigma[iTrig] = new TH1D(Form("SigmaScan_Mod%d_Trig%d",id,iTrig),Form("Threshold Sigma versus Interval for Module %d, Trigger %d",id,iTrig+1), nScanBins,xMin-1,xMax+1); + temphistSigma[iTrig]->GetXaxis()->SetTitle("Interval between 1st and 2nd inject"); + temphistSigma[iTrig]->GetYaxis()->SetTitle("Threshold Sigma, Ne^{-}"); + temphistSigma[iTrig]->SetOption("P"); + temphistSigma[iTrig]->SetMarkerStyle(2); + temphistSigma[iTrig]->SetMarkerSize(2); + + } + + histoMeanScan[id] = temphistMean; + histoSigmaScan[id] = temphistSigma; + std::vector<float> tempMeans(2*totalScans,0); + std::vector<float> tempSigmas(2*totalScans,0); + meanVals[id] = tempMeans; + sigmaVals[id] = tempSigmas; + + }//end if id not in histoSigmaScan map + + + TF1* meanGauss = threshdist->GetFunction("gauss"); + TF1* sigmaGauss = sigmadist->GetFunction("gaus"); + + int myIndex = 2*iScan + trigId; + if(meanGauss){ + meanVals[id].at(myIndex) = meanGauss->GetParameter(1); + } + else{ + meanVals[id].at(myIndex) = -1; + } + if(sigmaGauss){ + sigmaVals[id].at(myIndex) = sigmaGauss->GetParameter(1); + } + else{ + sigmaVals[id].at(myIndex) = -1; + } + + std::cout<<"Trigger "<<trigId+1<<" , interval "<<xVals[iScan]<<" : threshold mean = " + <<meanVals[id].at(myIndex)<<" ; sigma = "<<sigmaVals[id].at(myIndex)<<std::endl; + + + anfile->cd(); + thresh2d->Write(); + thresh2d->SetDirectory(gDirectory); + //thresh1d->Write(); + //thresh1d->SetDirectory(gDirectory); + threshdist->Write(); + threshdist->SetDirectory(gDirectory); + //sigma1d->Write(); + //sigma1d->SetDirectory(gDirectory); + sigmadist->Write(); + sigmadist->SetDirectory(gDirectory); + //bad->Write(); + //bad->SetDirectory(gDirectory); + hits1d->Write(); + hits1d->SetDirectory(gDirectory); + + file->cd(Form("loop1_%d",iScan)); + + }//if foundmatch + + }//end loop over keys + + } //end loop over iScan + + for(std::map<int, std::vector<TH1D*> >::iterator it=histoMeanScan.begin();it!=histoMeanScan.end();it++){ + int id=it->first; + + for(int iScan = 0; iScan<totalScans; iScan++){ + + int myIndex = 2*iScan; + histoMeanScan[id].at(0)->Fill(xVals[iScan], meanVals[id].at(myIndex+0) ); + histoSigmaScan[id].at(0)->Fill(xVals[iScan], sigmaVals[id].at(myIndex+0) ); + histoMeanScan[id].at(1)->Fill(xVals[iScan], meanVals[id].at(myIndex+1) ); + histoSigmaScan[id].at(1)->Fill(xVals[iScan], sigmaVals[id].at(myIndex+1) ); + + } + + anfile->cd(); + + for(int iTrig=0; iTrig<2; iTrig++){ + histoMeanScan[id].at(iTrig)->Write(); + histoMeanScan[id].at(iTrig)->SetDirectory(gDirectory); + histoSigmaScan[id].at(iTrig)->Write(); + histoSigmaScan[id].at(iTrig)->SetDirectory(gDirectory); + } + + } //end iterate over histoMeanScan + +} + + + diff --git a/rce/rcecalib/analysis/MultiTrigAnalysis.hh b/rce/rcecalib/analysis/MultiTrigAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..7cd76ec8814d34680a496fdc511512a90eedfb12 --- /dev/null +++ b/rce/rcecalib/analysis/MultiTrigAnalysis.hh @@ -0,0 +1,24 @@ +#ifndef MULTITRIGANALYSIS_HH +#define MULTITRIGANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} + +class MultiTrigAnalysis: public CalibAnalysis{ +public: + MultiTrigAnalysis(): CalibAnalysis(){} + ~MultiTrigAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.cc b/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..822d8d2b779704e2d1af5ae716f58619f02487bd --- /dev/null +++ b/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.cc @@ -0,0 +1,144 @@ +#include "rcecalib/analysis/MultiTrigNoiseAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + + +void MultiTrigNoiseAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"MultiTrigNoise analysis"<<std::endl; + + const int totalScans=scan->getLoopVarValues(1).size(); + + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + + float xVals[totalScans]; + + std::map<int, std::vector<TH1D*> > histoNumhitsScan; + std::map<int, std::vector<float> > numhitsVals; + + float xMin = scan->getLoopVarValues(1).at(0); + float xMax = scan->getLoopVarValues(1).at(totalScans-1); + if(xMax<xMin){ + float xtemp = xMax; + xMax = xMin; + xMin = xtemp; + } + + int nScanBins = (xMax - xMin + 3); + + + //loop over the different values of multitrig_interval + for(int iScan = 0; iScan<totalScans; iScan++){ + file->cd(Form("loop1_%d",iScan)); + + std::map<int, TH1D*> histmap; + boost::regex re0("_(\\d+)_Trig0_Occupancy_Point_000"); + boost::regex re1("_(\\d+)_Trig1_Occupancy_Point_000"); + boost::regex re2("Mean"); + + int trigId=-1; + TIter nextkey(gDirectory->GetListOfKeys()); // histograms + TKey *key; + + while ((key=(TKey*)nextkey())) { + std::string hname(key->GetName()); + boost::cmatch matches; + + bool foundMatch=false; + if(boost::regex_search(hname.c_str(), matches, re0)){ + trigId=0; + foundMatch=true; + } + else if(boost::regex_search(hname.c_str(), matches, re1)){ + trigId=1; + foundMatch=true; + } + + if(foundMatch){ + + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + // std::cout<<"Match = "<<match.c_str()<<std::endl; + // std::cout<<"name = "<<hname.c_str()<<std::endl; + + int id=strtol(match.c_str(),0,10); + + TH2* occHisto = (TH2*)key->ReadObj(); + + double totalNumHits = occHisto->GetSumOfWeights(); + + xVals[iScan] = scan->getLoopVarValues(1).at(iScan); + + + //check if the hits vs. interval histos have already been initialized for this Module ID + if(histoNumhitsScan.find(id)==histoNumhitsScan.end()){ + + std::vector<TH1D*> temphistHits(2); + + for(int iTrig=0; iTrig<2; iTrig++){ + temphistHits[iTrig] = new TH1D(Form("HitsScan_Mod%d_Trig%d",id,iTrig),Form("Total Hits versus Interval for Module %d, Trigger %d",id,iTrig+1), nScanBins,xMin-1,xMax+1); + temphistHits[iTrig]->GetXaxis()->SetTitle("Interval between 1st and 2nd inject"); + temphistHits[iTrig]->GetYaxis()->SetTitle("Total Hits"); + temphistHits[iTrig]->SetOption("P"); + temphistHits[iTrig]->SetMarkerStyle(2); + temphistHits[iTrig]->SetMarkerSize(2); + + } + + histoNumhitsScan[id] = temphistHits; + std::vector<float> tempVecHits(2*totalScans,0); + numhitsVals[id] = tempVecHits; + + }//end if id not in histoNumhitsScan map + + + int myIndex = 2*iScan + trigId; + numhitsVals[id].at(myIndex) = totalNumHits; + + std::cout<<"Trigger "<<trigId+1<<" , interval "<<xVals[iScan]<<" : Total hits = " + <<numhitsVals[id].at(myIndex)<<std::endl; + + + file->cd(Form("loop1_%d",iScan)); + + }//if foundmatch + + }//end loop over keys + + } //end loop over iScan + + for(std::map<int, std::vector<TH1D*> >::iterator it=histoNumhitsScan.begin();it!=histoNumhitsScan.end();it++){ + int id=it->first; + + for(int iScan = 0; iScan<totalScans; iScan++){ + + int myIndex = 2*iScan; + histoNumhitsScan[id].at(0)->Fill(xVals[iScan], numhitsVals[id].at(myIndex+0) ); + histoNumhitsScan[id].at(1)->Fill(xVals[iScan], numhitsVals[id].at(myIndex+1) ); + + } + + anfile->cd(); + + for(int iTrig=0; iTrig<2; iTrig++){ + histoNumhitsScan[id].at(iTrig)->Write(); + histoNumhitsScan[id].at(iTrig)->SetDirectory(gDirectory); + } + + } //end iterate over histoNumhitsScan + +} + + + diff --git a/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.hh b/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..b06ce1902d06189f8479d46cced1a4346ed4850c --- /dev/null +++ b/rce/rcecalib/analysis/MultiTrigNoiseAnalysis.hh @@ -0,0 +1,24 @@ +#ifndef MULTITRIGNOISEANALYSIS_HH +#define MULTITRIGNOISEANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} + +class MultiTrigNoiseAnalysis: public CalibAnalysis{ +public: + MultiTrigNoiseAnalysis(): CalibAnalysis(){} + ~MultiTrigNoiseAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/NoiseAnalysis.cc b/rce/rcecalib/analysis/NoiseAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..620134041da919a6d2138cfdd5ad17acf7c5ca68 --- /dev/null +++ b/rce/rcecalib/analysis/NoiseAnalysis.cc @@ -0,0 +1,85 @@ +#include "rcecalib/analysis/NoiseAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void NoiseAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scn, int runno, ConfigGui* cfg[]){ + TIter nextkey(file->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_NoiseOccupancy"); + boost::regex re2("NoiseOccupancy"); + while ((key=(TKey*)nextkey())) { + file->cd(); + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string neHistoName = boost::regex_replace (name, re2, "nEvents"); + TH2* histo = (TH2*)key->ReadObj(); + TH1* neHisto=(TH1*)gDirectory->Get(neHistoName.c_str()); + assert(neHisto!=0); + double nev=(double)neHisto->GetBinContent(1); + if(nev==0){ + std::cout<<"Number of events in "<<neHistoName<<" is 0"<<std::endl; + continue; + } + TH2D* ahis=new TH2D(Form("norm_occ_mod_%d",id), Form("Occupancy Mod %d at %s",id, findFieldName(cfg, id)), + histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax(), + histo->GetNbinsY(), histo->GetYaxis()->GetXmin(), histo->GetYaxis()->GetXmax()); + ahis->GetXaxis()->SetTitle("Column"); + ahis->GetYaxis()->SetTitle("Row"); + TH2D* mhis=new TH2D(Form("mask_mod_%d",id), Form("Mask Mod %d at %s", id, findFieldName(cfg, id)), + histo->GetNbinsX(), histo->GetXaxis()->GetXmin(), histo->GetXaxis()->GetXmax(), + histo->GetNbinsY(), histo->GetYaxis()->GetXmin(), histo->GetYaxis()->GetXmax()); + mhis->GetXaxis()->SetTitle("Column"); + mhis->GetYaxis()->SetTitle("Row"); + unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]=0; + ipc::PixelFEI4AConfig* conf=findFEI4AConfig(cfg, id); + if(conf)masks=conf->FEMasks; + else { + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)masks=confb->FEMasks; + } + if(masks && scn->clearMasks()==true)clearFEI4Masks(masks); + for (int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + if(nev>0){ + ahis->SetBinContent(i+1,j+1,(double)histo->GetBinContent(i+1, j+1)/nev); + if((scn->useAbsoluteNoiseThreshold()==true && (double)histo->GetBinContent(i+1, j+1)>scn->getNoiseThreshold()) + || (scn->useAbsoluteNoiseThreshold()==false && ahis->GetBinContent(i+1, j+1)>scn->getNoiseThreshold())){ + mhis->SetBinContent(i+1,j+1,1); + if(masks){ + masks[i][j]&=0xfe; //reset bit 0 (enable) + masks[i][j]|=0x8; //reset bit 3 (hitbus) + } + } + } + } + } + if(masks) writeFEI4Config(anfile, runno); + m_fw->writeMaskFile(Form("%sNoiseMask_Mod_%d", m_fw->getPath(anfile).c_str(), id), mhis); + delete histo; + anfile->cd(); + ahis->Write(); + ahis->SetDirectory(gDirectory); + mhis->Write(); + mhis->SetDirectory(gDirectory); + } + } + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + diff --git a/rce/rcecalib/analysis/NoiseAnalysis.hh b/rce/rcecalib/analysis/NoiseAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..b39e89647a90387a62d8598ce7136dbc45894b16 --- /dev/null +++ b/rce/rcecalib/analysis/NoiseAnalysis.hh @@ -0,0 +1,25 @@ +#ifndef NOISEANALYSIS_HH +#define NOISEANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class NoiseAnalysis: public CalibAnalysis{ +public: + NoiseAnalysis(CfgFileWriter* fw): CalibAnalysis(), m_fw(fw){} + ~NoiseAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void writeMaskFile(TH2D* his, TFile* anfile); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/OffsetAnalysis.cc b/rce/rcecalib/analysis/OffsetAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..457e088c189ff2ba68fd03307e29f32d22ee1860 --- /dev/null +++ b/rce/rcecalib/analysis/OffsetAnalysis.cc @@ -0,0 +1,132 @@ +#include "rcecalib/analysis/OffsetAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TStyle.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TF1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void OffsetAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + unsigned int numval=scan->getLoopVarValues(0).size(); + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + std::cout<<"Offset analysis"<<std::endl; + file->cd("loop1_0"); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + while ((key=(TKey*)nextkey())) { + file->cd("loop1_0"); + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string chi2HistoName = boost::regex_replace (name, re2, "ChiSquare"); + TH2* histo = (TH2*)key->ReadObj(); + TH2* chi2Histo=(TH2*)gDirectory->Get(chi2HistoName.c_str()); + assert(chi2Histo); + TH1D* hits1d[2]; + for (int i=0;i<2;i++){ + hits1d[i]=new TH1D(Form("HitsPerBin_%d__Mod_%d", i, id), + Form("Hits per bin %d Mod %d at %s", i, id, findFieldName(cfg, id)), + numval, -.5, (float)numval-.5) ; + hits1d[i]->GetXaxis()->SetTitle("Scan Point"); + } + fillHit1d(name, hits1d[0], numval); + file->cd("loop1_1"); + fillHit1d(name, hits1d[1], numval); + TH2* histo2 = (TH2*)gDirectory->Get(name.c_str()); + TH2* chi2Histo2 = (TH2*)gDirectory->Get(chi2HistoName.c_str()); + TH1D* offset=new TH1D(Form("Offset_Mod_%d",id), + Form("Offset Mod %d at %s", id, findFieldName(cfg, id)), 50, 0, 0.05); + offset->GetXaxis()->SetTitle("Offset (mV)"); + float clo=1.9; + float chi=3.9; + float m=1.4e-3; + struct ipc::PixelFECalibFEI4 *fecalib=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)fecalib=&confa->FECalib; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)fecalib=&confb->FECalib; + } + if(fecalib){ + clo=fecalib->cinjLo; + chi=fecalib->cinjHi; + m=fecalib->vcalCoeff[1]; + if(clo==0){ + std::cout<<"Cannot determine alpha because clo is 0 for module "<<id<<std::endl; + continue; + } + }else{ + std::cout<<"No configuration available. Using default values."<<std::endl; + } + float alpha=(clo+chi)/clo; + if(alpha==1){ + std::cout<<"Cannot determine offset because alpha is 1 for module "<<id<<std::endl; + continue; + } + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + if(chi2Histo->GetBinContent(i, j)!=0 && chi2Histo2->GetBinContent(i, j)!=0) { + float v1=histo->GetBinContent(i, j); + float v2=histo2->GetBinContent(i, j); + float n=m*(v1-alpha*v2)/(alpha-1); + offset->Fill(n); + } + } + } + offset->Fit("gaus"); + TF1* gaus=offset->GetFunction("gaus"); + double off=0; + if(gaus)off=gaus->GetParameter(1); + else std::cout<<"Warning: Fit for offset failed. Using default value of 0"<<std::endl; + std::cout<<"Offset for module "<<id<<" is "<<off<<std::endl; + if(off<0 || off>0.06){ + std::cout<<"Offset out of range (0..50). Setting to 0"<<std::endl; + off=0; + } + if(fecalib){ + m=fecalib->vcalCoeff[0]=off; + writeFEI4Config(anfile, runno); + } + + delete histo; + anfile->cd(); + offset->Write(); + offset->SetDirectory(gDirectory); + hits1d[0]->Write(); + hits1d[0]->SetDirectory(gDirectory); + hits1d[1]->Write(); + hits1d[1]->SetDirectory(gDirectory); + } + } + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + +void OffsetAnalysis::fillHit1d(std::string &name, TH1* hits1d, unsigned numval){ +for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (name, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } +} diff --git a/rce/rcecalib/analysis/OffsetAnalysis.hh b/rce/rcecalib/analysis/OffsetAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..8f809f81c3943bd1759d8913b5b0a435a08a91dd --- /dev/null +++ b/rce/rcecalib/analysis/OffsetAnalysis.hh @@ -0,0 +1,23 @@ +#ifndef OFFSETANALYSIS_HH +#define OFFSETANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +class TH1; +namespace RCE{ + class PixScan; +} + +class OffsetAnalysis: public CalibAnalysis{ +public: + OffsetAnalysis(): CalibAnalysis(){} + ~OffsetAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void fillHit1d(std::string &name, TH1* hits1d, unsigned numval); +}; + + +#endif diff --git a/rce/rcecalib/analysis/RegisterTestAnalysis.cc b/rce/rcecalib/analysis/RegisterTestAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..c9540fa0e191fdfcec59318a6d85f38f32aaf62a --- /dev/null +++ b/rce/rcecalib/analysis/RegisterTestAnalysis.cc @@ -0,0 +1,168 @@ +#include "rcecalib/analysis/RegisterTestAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/config/FEI4/Utils.hh" + +#include <TFile.h> +#include <TStyle.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TF1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void RegisterTestAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + gStyle->SetOptStat(0); + std::cout<<"Register Test Analysis"<<std::endl; + file->cd(); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Pixel_Reg"); + boost::regex re2("Pixel"); + while ((key=(TKey*)nextkey())) { + file->cd(); + std::string hname(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(hname.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string globHistoName = boost::regex_replace (hname, re2, "Global"); + TH2* histo = (TH2*)key->ReadObj(); + TH1* globHisto=(TH2*)gDirectory->Get(globHistoName.c_str()); + assert(globHisto); + int binsx=histo->GetNbinsX(); + int binsy=histo->GetNbinsY(); + char name[128]; + char title[128]; + sprintf(name, "Mod_%d_Enable", id); + sprintf(title, "Enable Bit Module %d at %s", id, findFieldName(cfg, id)); + TH2F* enable=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + enable->GetXaxis()->SetTitle("Column"); + enable->GetYaxis()->SetTitle("Row"); + sprintf(name, "Mod_%d_TDAC", id); + sprintf(title, "TDAC Bits Module %d at %s", id, findFieldName(cfg, id)); + TH2F* tdac=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + tdac->GetXaxis()->SetTitle("Column"); + tdac->GetYaxis()->SetTitle("Row"); + sprintf(name, "Mod_%d_LargeCap", id); + sprintf(title, "Large Cap Bit Module %d at %s", id, findFieldName(cfg, id)); + TH2F* largeCap=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + largeCap->GetXaxis()->SetTitle("Column"); + largeCap->GetYaxis()->SetTitle("Row"); + sprintf(name, "Mod_%d_SmallCap", id); + sprintf(title, "Small Cap Bit Module %d at %s", id, findFieldName(cfg, id)); + TH2F* smallCap=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + smallCap->GetXaxis()->SetTitle("Column"); + smallCap->GetYaxis()->SetTitle("Row"); + sprintf(name, "Mod_%d_Hitbus", id); + sprintf(title, "Hitbus Bit Module %d at %s", id, findFieldName(cfg, id)); + TH2F* hitbus=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + hitbus->GetXaxis()->SetTitle("Column"); + hitbus->GetYaxis()->SetTitle("Row"); + sprintf(name, "Mod_%d_FDAC", id); + sprintf(title, "FDAC Bits Module %d at %s", id, findFieldName(cfg, id)); + TH2F* fdac=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + fdac->GetXaxis()->SetTitle("Column"); + fdac->GetYaxis()->SetTitle("Row"); + + for (int i=0;i<binsx;i++){ + for (int j=0;j<binsy;j++){ + int val=histo->GetBinContent(i+1, j+1); + for (int k=0;k<13;k++){ + int bit=val&(1<<k); + if(bit){ + std::cout<<"FE "<<id<<": Pixel Register Problem."<<std::endl; + if(k==0)enable->Fill(i,j); + else if(k>=1 && k<=5)tdac->Fill(i,j); + else if(k==6)largeCap->Fill(i,j); + else if(k==7)smallCap->Fill(i,j); + else if(k==8)hitbus->Fill(i,j); + else if(k>=9)fdac->Fill(i,j); + } + } + } + } + delete histo; + anfile->cd(); + enable->Write(); + enable->SetDirectory(gDirectory); + tdac->Write(); + tdac->SetDirectory(gDirectory); + largeCap->Write(); + largeCap->SetDirectory(gDirectory); + smallCap->Write(); + smallCap->SetDirectory(gDirectory); + hitbus->Write(); + hitbus->SetDirectory(gDirectory); + fdac->Write(); + fdac->SetDirectory(gDirectory); + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb){ + sprintf(name, "Mod_%d_Global_Register_Diff", id); + sprintf(title, "Diff of Global Reg Module %d at %s", id, findFieldName(cfg, id)); + TH1F* glob=new TH1F(name, title, 36, -0.5, 35.5); + glob->GetXaxis()->SetTitle("Register"); + unsigned short reg[36]; + reg[0]=0; + reg[1]=(confb->FEGlobal.SmallHitErase<<8) | flipBits(8,confb->FEGlobal.Eventlimit); + reg[2]=0xffff & ((42<<12) | (1<<11)); //ConfAddrEnable was explicitely turned on, TrigCnt was 42 + reg[3]=confb->FEGlobal.ErrMask0; + reg[4]=confb->FEGlobal.ErrMask1; + reg[5]=(flipBits(8, confb->FEGlobal.PrmpVbpRight)<<8)| flipBits(8, confb->FEGlobal.BufVgOpAmp); + reg[6]=flipBits(8, confb->FEGlobal.PrmpVbp); + reg[7]=(flipBits(8, confb->FEGlobal.TdacVbp)<<8)| flipBits(8, confb->FEGlobal.DisVbn); + reg[8]=(flipBits(8, confb->FEGlobal.Amp2Vbn)<<8)| flipBits(8, confb->FEGlobal.Amp2VbpFol); + reg[9]=flipBits(8, confb->FEGlobal.Amp2Vbp); + reg[10]=(flipBits(8, confb->FEGlobal.FdacVbn)<<8)| flipBits(8, confb->FEGlobal.Amp2Vbpf); + reg[11]=(flipBits(8, confb->FEGlobal.PrmpVbnFol)<<8)| flipBits(8, confb->FEGlobal.PrmpVbpLeft); + reg[12]=(flipBits(8, confb->FEGlobal.PrmpVbpf)<<8)| flipBits(8, confb->FEGlobal.PrmpVbnLcc); + reg[13]=0; + reg[14]=(flipBits(8, confb->FEGlobal.LVDSDrvIref)<<8)| flipBits(8, confb->FEGlobal.GADCOpAmp); + reg[15]=(flipBits(8, confb->FEGlobal.PllIbias)<<8)| flipBits(8, confb->FEGlobal.LVDSDrvVos); + reg[16]=(flipBits(8, confb->FEGlobal.TempSensBias)<<8)| flipBits(8, confb->FEGlobal.PllIcp); + reg[17]=flipBits(8, confb->FEGlobal.PlsrIdacRamp); + reg[18]=(flipBits(8, confb->FEGlobal.VrefDigTune)<<8)| flipBits(8, confb->FEGlobal.PlsrVgOPamp); + reg[19]=(flipBits(8, confb->FEGlobal.PlsrDacBias)<<8)| flipBits(8, confb->FEGlobal.VrefAnTune); + reg[20]=(flipBits(8, confb->FEGlobal.Vthin_AltCoarse)<<8)| flipBits(8, confb->FEGlobal.Vthin_AltFine); + reg[21]=(confb->FEGlobal.HITLD_In<<12)| (confb->FEGlobal.DINJ_Override<<11) | (confb->FEGlobal.DIGHITIN_Sel<<10) | flipBits(10, 341); + reg[22]=768; + reg[23]=confb->FEGlobal.DisableColumnCnfg0; + reg[24]=confb->FEGlobal.DisableColumnCnfg1; + reg[25]=(100<<8)| confb->FEGlobal.DisableColumnCnfg2; + reg[26]=(12<<3)| (confb->FEGlobal.StopModeCnfg<<2) | (confb->FEGlobal.HitDiscCnfg); + reg[27]=(confb->FEGlobal.EN_PLL<<15); + reg[28]=(confb->FEGlobal.LVDSDrvSet06<<15)| (confb->FEGlobal.EN40M<<9) | (confb->FEGlobal.EN80M<<8) + |(confb->FEGlobal.CLK1<<5)|(confb->FEGlobal.CLK0<<2) | (confb->FEGlobal.EN160M<<1) | confb->FEGlobal.EN320M; + reg[29]=(confb->FEGlobal.no8b10b<<13) |(flipBits(8, confb->FEGlobal.EmptyRecord)<<4) + | (confb->FEGlobal.LVDSDrvEn<<2) |(confb->FEGlobal.LVDSDrvSet30<<1) | confb->FEGlobal.LVDSDrvSet12; + reg[30]=(flipBits(2, confb->FEGlobal.TempSensDiodeSel)<<14) | (confb->FEGlobal.TempSensDisable<<13) | (confb->FEGlobal.IleakRange<<12); + reg[31]=(confb->FEGlobal.PlsrRiseUpTau<<13)| (confb->FEGlobal.PlsrPwr<<12) |(flipBits(6, confb->FEGlobal.PlsrDelay)<<6)| (confb->FEGlobal.EN80M<<8) + | (confb->FEGlobal.ExtDigCalSW<<5) | (confb->FEGlobal.ExtAnaCalSW<<4) | confb->FEGlobal.GADCSel; + reg[32]=confb->FEGlobal.SELB0; + reg[33]=confb->FEGlobal.SELB1; + reg[34]=(confb->FEGlobal.SELB2<<8)|(confb->FEGlobal.PrmpVbpMsnEn<<4); + reg[35]=confb->FEGlobal.Chip_SN; + for(int i=0;i<36;i++){ + if(globHisto->GetBinContent(i+1)!=reg[i]){ + std::cout<<"Frontend "<<id<<" global register "<<i<<" content differs: "; + std::cout<<"Setting= 0x"<<std::hex<<reg[i]<<" readback= 0x"<<(unsigned)globHisto->GetBinContent(i+1)<<std::dec<<std::endl; + glob->SetBinContent(i+1, unsigned(globHisto->GetBinContent(i+1))^reg[i]); + } + } + glob->Write(); + glob->SetDirectory(gDirectory); + }else{ + std::cout<<"Not an FEI4B chip. Not checking global register"<<std::endl; + } + } + } +} + diff --git a/rce/rcecalib/analysis/RegisterTestAnalysis.hh b/rce/rcecalib/analysis/RegisterTestAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..79bc6a6bb73d0cdcaf453ab410588bb8fd609a1a --- /dev/null +++ b/rce/rcecalib/analysis/RegisterTestAnalysis.hh @@ -0,0 +1,22 @@ +#ifndef REGISTERTESTANALYSIS_HH +#define REGISTERTESTANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +class TH1; +namespace RCE{ + class PixScan; +} + +class RegisterTestAnalysis: public CalibAnalysis{ +public: + RegisterTestAnalysis(): CalibAnalysis(){} + ~RegisterTestAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/SerialNumberAnalysis.cc b/rce/rcecalib/analysis/SerialNumberAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..c3fb38ae740f2b95f4894d763fc8eaacfa8137e8 --- /dev/null +++ b/rce/rcecalib/analysis/SerialNumberAnalysis.cc @@ -0,0 +1,53 @@ +#include "rcecalib/analysis/SerialNumberAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +using namespace RCE; + +void SerialNumberAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Serial number analysis"<<std::endl; + TIter nextkey(file->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_SN"); + boost::regex re2("at ([AC][1-8]-[12]) "); + int sn=0; + int allmatch=true; + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + std::string title(key->GetTitle()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + boost::regex_search(title.c_str(), matches, re2); + assert(matches.size()>1); + std::string match2(matches[1].first, matches[1].second); + TH1* histo = (TH1*)key->ReadObj(); + int sn_read=histo->GetBinContent(1); + ipc::PixelFEI4BConfig* conf=findFEI4BConfig(cfg, id); + if(conf){ + sn=conf->FEGlobal.Chip_SN; + if(sn!=sn_read){ + std::cout<<"FE at "<<match2<<": Readback of serial number ("<<sn_read<<") does not match serial number in config file ("<<sn<<")."<<std::endl; + allmatch=false; + }else{ + std::cout<<"FE at "<<match2<<": Readback of serial number ("<<sn_read<<") identical as in config file."<<std::endl; + } + conf->FEGlobal.Chip_SN=sn_read; + writeFEI4Config(anfile, runno); + } + delete histo; + } + } + if(allmatch)std::cout<<"The configurations for all frontends match between EFUSE and config file."<<std::endl; + else std::cout<<"!!!!!!! There are mismatches between read back values and config files."<<std::endl; + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + diff --git a/rce/rcecalib/analysis/SerialNumberAnalysis.hh b/rce/rcecalib/analysis/SerialNumberAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..ade2c92d9fe1d058e015517117b2d068a49204db --- /dev/null +++ b/rce/rcecalib/analysis/SerialNumberAnalysis.hh @@ -0,0 +1,21 @@ +#ifndef SERIALNUMBERANALYSIS_HH +#define SERIALNUMBERANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class SerialNumberAnalysis: public CalibAnalysis{ +public: + SerialNumberAnalysis(): CalibAnalysis(){} + ~SerialNumberAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/StuckPixelAnalysis.cc b/rce/rcecalib/analysis/StuckPixelAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..b0556443b2054f4f37572fc92725e0589e47751c --- /dev/null +++ b/rce/rcecalib/analysis/StuckPixelAnalysis.cc @@ -0,0 +1,52 @@ +#include "rcecalib/analysis/StuckPixelAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +using namespace RCE; + +void StuckPixelAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + TIter nextkey(file->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Hitor"); + while ((key=(TKey*)nextkey())) { + file->cd(); + std::string name(key->GetName()); + std::cout<<name<<std::endl; + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + TH2* histo = (TH2*)key->ReadObj(); + m_fw->writeMaskFile(Form("%sStuckPixelMask_Mod_%d", m_fw->getPath(anfile).c_str(), id), histo); + unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]=0; + ipc::PixelFEI4AConfig* conf=findFEI4AConfig(cfg, id); + if(conf)masks=conf->FEMasks; + else { + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)masks=confb->FEMasks; + } + if(masks){ + if(scan->clearMasks()==true)clearFEI4Masks(masks); + for (int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + if(histo->GetBinContent(i+1, j+1)==1){ + masks[i][j]&=0xfe; //reset bit 0 (enable) + masks[i][j]|=0x8; //reset bit 3 (hitbus) + } + } + } + writeFEI4Config(anfile, runno); + } + delete histo; + } + } + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + diff --git a/rce/rcecalib/analysis/StuckPixelAnalysis.hh b/rce/rcecalib/analysis/StuckPixelAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..b302bc0466875f0a07b1a8c116c6e58025994e8f --- /dev/null +++ b/rce/rcecalib/analysis/StuckPixelAnalysis.hh @@ -0,0 +1,25 @@ +#ifndef STUCKPIXELANALYSIS_HH +#define STUCKPIXELANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" + +class ConfigGui; +class TFile; +class TH2; +namespace RCE{ + class PixScan; +} + +class StuckPixelAnalysis: public CalibAnalysis{ +public: + StuckPixelAnalysis(CfgFileWriter *fw): CalibAnalysis(), m_fw(fw){} + ~StuckPixelAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void writeMaskFile(TH2* his, TFile* anfile); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/T0Analysis.cc b/rce/rcecalib/analysis/T0Analysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..4a54723ed6ff6b956158bd19d72910a08a749b52 --- /dev/null +++ b/rce/rcecalib/analysis/T0Analysis.cc @@ -0,0 +1,311 @@ +#include "rcecalib/analysis/T0Analysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TStyle.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TF1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void T0Analysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + unsigned int numval=scan->getLoopVarValues(0).size(); + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + std::cout<<"T0 analysis"<<std::endl; + file->cd("loop1_0"); + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + while ((key=(TKey*)nextkey())) { + file->cd("loop1_0"); + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + + + // std::cout<<"match = "<<match.c_str()<<std::endl; + int id=strtol(match.c_str(),0,10); + + // std::cout<<"id = "<<id<<std::endl; + + std::string sigmaHistoName = boost::regex_replace (name, re2, "Sigma"); + + struct ipc::PixelFEI4AGlobal *feglobalA=0; + struct ipc::PixelFEI4BGlobal *feglobalB=0; + + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)feglobalA=&confa->FEGlobal; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)feglobalB=&confb->FEGlobal; + } + + TH2* histo = (TH2*)key->ReadObj(); + TH2* sigmaHisto=(TH2*)gDirectory->Get(sigmaHistoName.c_str()); + assert(sigmaHisto); + TH1D* hits1d[2]; + + for (int iScan=0;iScan<2;iScan++){ + hits1d[iScan]=new TH1D(Form("HitsPerBin_%d_Mod_%d", iScan, id), + Form("Hits per bin Mod %d at %s (Scan %d)" + , id, findFieldName(cfg, id), iScan), + numval, -.5, (float)numval-.5) ; + hits1d[iScan]->GetXaxis()->SetTitle("Scan Point"); + } + + fillHit1d(name, hits1d[0], numval); + file->cd("loop1_1"); + fillHit1d(name, hits1d[1], numval); + + TH2* histo2 = (TH2*)gDirectory->Get(name.c_str()); + TH2* sigmaHisto2 = (TH2*)gDirectory->Get(sigmaHistoName.c_str()); + + + + //Get histogram ranges + float maxval[2] = {0,0}; + float minval[2] = {1e8, 1e8}; + float vals[4] = {0,0,0,0}; + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + + vals[0] = histo->GetBinContent(i, j); + vals[1] = histo2->GetBinContent(i, j); + vals[2] = sigmaHisto->GetBinContent(i, j); + vals[3] = sigmaHisto2->GetBinContent(i, j); + + for(int kpar = 0; kpar<2; kpar++){ + if(vals[kpar]>maxval[0]){ + maxval[0] = vals[kpar]; + } + if(vals[kpar]<minval[0]&&vals[kpar]>0){ + minval[0] = vals[kpar]; + } + } + + for(int kpar = 2; kpar<4; kpar++){ + if(vals[kpar]>maxval[1]){ + maxval[1] = vals[kpar]; + } + if(vals[kpar]<minval[1]&&vals[kpar]>0){ + minval[1] = vals[kpar]; + } + } + + } + } + + TH1D* t0mean[2]; + TH1D* t0sigma[2]; + + int nGoodPixels = 0; + float sumT0Diffs = 0; + + for(int iScan=0; iScan<2; iScan++){ + + t0mean[iScan] =new TH1D(Form("T0_%d_Mod_%d",iScan,id), + Form("T0 for each pixel in Mod %d at %s (Scan %d)", + id, findFieldName(cfg, id), iScan), 50, minval[0]-1, maxval[0]+1); + t0sigma[iScan] =new TH1D(Form("Sigma_%d_Mod_%d",iScan,id), + Form("T0 S-CURVE sigma for each pixel in Mod %d at %s (Scan %d)", + id, findFieldName(cfg, id), iScan), 50, minval[1]-1, maxval[1]+1); + + + t0mean[iScan]->GetXaxis()->SetTitle("t0 (strobe delay counts)"); + t0sigma[iScan]->GetXaxis()->SetTitle("t0 S-Curve sigma (strobe delay counts)"); + + } + + + + + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + + float val=0; + + if(histo->GetBinContent(i, j)!=0 ){ + val = histo->GetBinContent(i, j); + t0mean[0]->Fill(val); + + if(histo2->GetBinContent(i, j)!=0 ){ + nGoodPixels++; + float val2 = histo2->GetBinContent(i, j); + sumT0Diffs += (val2 - val); + } + + } + if(histo2->GetBinContent(i, j)!=0 ){ + val = histo2->GetBinContent(i, j); + t0mean[1]->Fill(val); + } + + if(sigmaHisto->GetBinContent(i, j)!=0 ){ + val = sigmaHisto->GetBinContent(i, j); + t0sigma[0]->Fill(val); + } + if(sigmaHisto2->GetBinContent(i, j)!=0 ){ + val = sigmaHisto2->GetBinContent(i, j); + t0sigma[1]->Fill(val); + } + + } + + } + float avgt0diff = sumT0Diffs/nGoodPixels; + + float t0[2]; + for(int iScan=0; iScan<2; iScan++){ + + t0mean[iScan]->Fit("gaus"); + t0[iScan] = t0mean[iScan]->GetFunction("gaus")->GetParameter(1); + std::cout<<"T0 for module "<<id<<" for scan "<<iScan<<" is "<<t0[iScan]<<std::endl; + + } + + assert(t0[1] > t0[0]); + + float convFactor = 25.6/(avgt0diff); //one clock tick=25.6 ns + + std::cout<<"delay/(strobe-delay count) = "<<convFactor<<" (ns/count)"<<std::endl; + + + TH1D* t0mean_ns[2]; + TH1D* t0sigma_ns[2]; + TH1D* t0diff_ns; + + + for(int iScan=0; iScan<2; iScan++){ + + t0mean_ns[iScan] = new TH1D(Form("T0_%d_Mod_%d_ns",iScan,id), + Form("T0 (in ns) for each pixel in Mod %d at %s (Scan %d)", + id, findFieldName(cfg, id), iScan), 50, minval[0]-1, maxval[0]+1); + t0sigma_ns[iScan] = new TH1D(Form("Sigma_%d_Mod_%d_ns",iScan,id), + Form("T0 S-CURVE sigma (in ns) for each pixel in Mod %d at %s (Scan %d)", + id, findFieldName(cfg, id), iScan), 50, minval[1]-1, maxval[1]+1); + + t0mean_ns[iScan]->GetXaxis()->SetTitle("t0 (ns)"); + t0sigma_ns[iScan]->GetXaxis()->SetTitle("t0 S-Curve sigma (ns)"); + + } + + t0diff_ns =new TH1D(Form("T0_Diff_%d",id), + Form("T0 difference (in ns) for each pixel in Mod %d at %s", + id, findFieldName(cfg, id)), 50, 20., 30.); + t0diff_ns->GetXaxis()->SetTitle("t0_2 - t0_1 (ns)"); + + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + + float val=0; + + if(histo->GetBinContent(i, j)!=0 ){ + val = histo->GetBinContent(i, j)*convFactor; + t0mean_ns[0]->Fill(val); + + if(histo2->GetBinContent(i, j)!=0){ + float val2 = histo2->GetBinContent(i, j)*convFactor; + t0diff_ns->Fill(val2 - val); + } + + } + if(histo2->GetBinContent(i, j)!=0 ){ + val = histo2->GetBinContent(i, j)*convFactor; + t0mean_ns[1]->Fill(val); + } + + if(sigmaHisto->GetBinContent(i, j)!=0 ){ + val = sigmaHisto->GetBinContent(i, j)*convFactor; + t0sigma_ns[0]->Fill(val); + } + if(sigmaHisto2->GetBinContent(i, j)!=0 ){ + val = sigmaHisto2->GetBinContent(i, j)*convFactor; + t0sigma_ns[1]->Fill(val); + } + + } + + } + + + float t0_ns[2]; + + for(int iScan=0; iScan<2; iScan++){ + t0mean_ns[iScan]->Fit("gaus"); + t0_ns[iScan] = t0mean_ns[iScan]->GetFunction("gaus")->GetParameter(1); + } + + float strobeDel = (t0_ns[1] + 5.0)/convFactor; + int strobeDelInt = (int)(strobeDel+0.5); + std::cout<<"t0 = "<<t0_ns[1]<<" ; strobe delay = "<<strobeDel<<" = "<<strobeDelInt<<std::endl; + + int trigLat = scan->getLoopVarValues(1).at(1); + + if(feglobalA){ + feglobalA->PlsrDelay=strobeDelInt; + feglobalA->TrigLat=trigLat; + writeFEI4Config(anfile, runno); + } + if(feglobalB){ + feglobalB->PlsrDelay=strobeDelInt; + feglobalB->TrigLat=trigLat; + writeFEI4Config(anfile, runno); + } + + + delete histo; + anfile->cd(); + + for(int iScan=0; iScan<2; iScan++){ + + t0mean[iScan]->Write(); + t0mean[iScan]->SetDirectory(gDirectory); + t0sigma[iScan]->Write(); + t0sigma[iScan]->SetDirectory(gDirectory); + + t0mean_ns[iScan]->Write(); + t0mean_ns[iScan]->SetDirectory(gDirectory); + t0sigma_ns[iScan]->Write(); + t0sigma_ns[iScan]->SetDirectory(gDirectory); + + hits1d[iScan]->Write(); + hits1d[iScan]->SetDirectory(gDirectory); + + } + t0diff_ns->Write(); + t0diff_ns->SetDirectory(gDirectory); + + + } + } + if(configUpdate())writeTopFile(cfg, anfile, runno); +} + +void T0Analysis::fillHit1d(std::string &name, TH1* hits1d, unsigned numval){ +for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (name, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } +} diff --git a/rce/rcecalib/analysis/T0Analysis.hh b/rce/rcecalib/analysis/T0Analysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..c72e9d827f002e168974824ba6a6b8729eccd64f --- /dev/null +++ b/rce/rcecalib/analysis/T0Analysis.hh @@ -0,0 +1,23 @@ +#ifndef T0ANALYSIS_HH +#define T0ANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +class TH1; +namespace RCE{ + class PixScan; +} + +class T0Analysis: public CalibAnalysis{ +public: + T0Analysis(): CalibAnalysis(){} + ~T0Analysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void fillHit1d(std::string &name, TH1* hits1d, unsigned numval); +}; + + +#endif diff --git a/rce/rcecalib/analysis/TdacAnalysis.cc b/rce/rcecalib/analysis/TdacAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..b0a10e41177058add8e261d73e30ef5b05e7dbce --- /dev/null +++ b/rce/rcecalib/analysis/TdacAnalysis.cc @@ -0,0 +1,157 @@ +#include "rcecalib/analysis/TdacAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/config/FEI3/Frontend.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + +namespace{ + const double BAD_THRESHOLD=150; +} + + +void TdacAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + //gStyle->SetOptStat(1110); + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + file->cd(); + TKey *key; + char subdir[128]; + char name[128]; + char title[128]; + int binsx=0, binsy=0; + size_t numvals=scan->getLoopVarValues(1).size(); + std::map<int, hdata> *histomap=new std::map<int, hdata>[numvals]; + double *val=new double[numvals]; + for (size_t i=0;i<numvals;i++){ + sprintf(subdir, "loop1_%d", i); + file->cd(subdir); + TIter nextkey(gDirectory->GetListOfKeys()); // TDAC settings + while ((key=(TKey*)nextkey())) { + boost::regex re("_(\\d+)_Mean"); + boost::cmatch matches; + if(boost::regex_search(key->GetName(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int lnm=strtol(match.c_str(),0,10); + char tdachistoname[128]; + sprintf (tdachistoname, "TDAC_settings_Mod_%d_it_%d", lnm, i); + TH2* histo = (TH2*)key->ReadObj(); + TH2* tdachisto=(TH2*)gDirectory->Get(tdachistoname); + assert(tdachisto); + histomap[i][lnm].mean=histo; + histomap[i][lnm].tdac=tdachisto; + binsx=histo->GetNbinsX(); + binsy=histo->GetNbinsY(); + } + } + } + int target=scan->getThresholdTargetValue(); + for(std::map<int, hdata>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + sprintf(name, "threshdist_Mod_%d", id); + sprintf(title, "Threshold distribution Module %d at %s", id, findFieldName(cfg, id)); + TH1F* thresh1d=new TH1F(name, title, 400, 1000, 5000); + thresh1d->GetXaxis()->SetTitle("Threshold"); + sprintf(name, "BestMean_Mod_%d", id); + sprintf(title, "Best Mean Module %d at %s", id, findFieldName(cfg, id)); + TH2F* mean=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + mean->GetXaxis()->SetTitle("Column"); + mean->GetYaxis()->SetTitle("Row"); + sprintf(name, "diff2d_Mod_%d", id); + sprintf(title, "Distance wrt %d electrons Module %d at %s", target, id, findFieldName(cfg, id)); + TH2F* diff2d=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + diff2d->GetXaxis()->SetTitle("Column"); + diff2d->GetYaxis()->SetTitle("Row"); + sprintf(name, "thresh1d_Mod_%d", id); + sprintf(title, "Thresholds Module %d at %s", id, findFieldName(cfg, id)); + int nbins=binsx*binsy; + TH1F* diff1d=new TH1F(name, title, nbins, 0, (float)nbins); + diff1d->GetXaxis()->SetTitle("Channel"); + diff1d->SetOption("p9"); + sprintf(name, "BestTdac_Mod_%d", id); + sprintf(title, "Best Tdacs Module %d at %s", id, findFieldName(cfg, id)); + TH2F* tdac=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + tdac->GetXaxis()->SetTitle("Column"); + tdac->GetYaxis()->SetTitle("Row"); + sprintf(name, "BadPixels_Mod_%d", id); + sprintf(title, "Bad Pixels Module %d at %s", id, findFieldName(cfg, id)); + TH2F* bad=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + bad->GetXaxis()->SetTitle("Column"); + bad->GetYaxis()->SetTitle("Row"); + sprintf(name, "threshdiff_Mod_%d", id); + sprintf(title, "Threshold distribution around target value Module %d at %s", id, findFieldName(cfg, id)); + TH1F* threshdist=new TH1F(name, title, 200, -500, 500); + threshdist->GetXaxis()->SetTitle("Threshold"); + struct ipc::PixelFEI4Trims *trims=0; + struct ipc::PixelModuleConfig *conf3=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)trims=&confa->FETrims; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)trims=&confb->FETrims; + else conf3=findFEI3Config(cfg, id); + } + for (int i=1;i<=mean->GetNbinsX();i++){ + for(int j=1;j<=mean->GetNbinsY();j++){ + double bestval=10000; + int index=0; + for(size_t k=0;k<numvals;k++){ + val[k]=histomap[k][id].mean->GetBinContent(i,j); + if(fabs(val[k]-target)<bestval){ + index=k; + bestval=fabs(val[k]-target); + } + } + mean->SetBinContent(i,j,val[index]); + diff2d->SetBinContent(i,j,fabs(val[index]-target)); + diff1d->SetBinContent((i-1)*mean->GetNbinsY()+j, val[index]); + thresh1d->Fill(val[index]); + threshdist->Fill(val[index]-target); + tdac->SetBinContent(i,j,histomap[index][id].tdac->GetBinContent(i,j)); + if(trims)trims->dacThresholdTrim[i-1][j-1]=histomap[index][id].tdac->GetBinContent(i,j); + else if (conf3){ + int chip=(i-1)/FEI3::Frontend::N_COLS; + int col=(i-1)%FEI3::Frontend::N_COLS; + int row=j-1; + conf3->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=histomap[index][id].tdac->GetBinContent(i,j); + } + if(fabs(val[index]-target)>BAD_THRESHOLD)bad->SetBinContent(i,j,1); + } + } + TF1 gauss("gauss", "gaus", 100, 10000); + gauss.SetParameter(0, threshdist->GetMaximum()); + gauss.SetParameter(1, threshdist->GetMaximumBin()*threshdist->GetBinWidth(1)); + thresh1d->Fit(&gauss,"q", "", 100, 10000); + anfile->cd(); + mean->Write(); + mean->SetDirectory(gDirectory); + diff2d->Write(); + diff2d->SetDirectory(gDirectory); + diff1d->Write(); + diff1d->SetDirectory(gDirectory); + tdac->Write(); + tdac->SetDirectory(gDirectory); + bad->Write(); + bad->SetDirectory(gDirectory); + threshdist->Write(); + threshdist->SetDirectory(gDirectory); + thresh1d->Write(); + thresh1d->SetDirectory(gDirectory); + m_fw->writeDacFile(Form("%sTdacs_Mod_%d", m_fw->getPath(anfile).c_str(), id), tdac); + if(trims) writeFEI4Config(anfile, runno); + if(conf3) writeFEI3Config(anfile, runno); + } + if(configUpdate())writeTopFile(cfg, anfile, runno); + delete [] histomap; + delete [] val; +} + diff --git a/rce/rcecalib/analysis/TdacAnalysis.hh b/rce/rcecalib/analysis/TdacAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..0c8ec2286d54c87614479a94a3c7a213931d9bc0 --- /dev/null +++ b/rce/rcecalib/analysis/TdacAnalysis.hh @@ -0,0 +1,33 @@ +#ifndef TDACANALYSIS_HH +#define TDACANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} +namespace{ + struct hdata{ + TH2* mean; + TH2* tdac; + }; +} + +class TdacAnalysis: public CalibAnalysis{ +public: + TdacAnalysis(CfgFileWriter* fw): CalibAnalysis(), m_fw(fw){} + ~TdacAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/TdacFastAnalysis.cc b/rce/rcecalib/analysis/TdacFastAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c7b74ea3fa9a29685aa0366f40ad2603e0f869d --- /dev/null +++ b/rce/rcecalib/analysis/TdacFastAnalysis.cc @@ -0,0 +1,124 @@ +#include "rcecalib/analysis/TdacFastAnalysis.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/config/FEI3/Frontend.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <string> +#include <sstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + +namespace{ + const double BAD_THRESHOLD=150; +} + + +void TdacFastAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + int repetitions = scan->getRepetitions(); + double targetEff = 0.5; + file->cd(); + TKey *key; + char subdir[128]; + char name[128]; + char title[128]; + int binsx=0, binsy=0; + size_t numvals=scan->getLoopVarValues(1).size(); + std::map<int, hdatafast> *histomap=new std::map<int, hdatafast>[numvals]; + double *val=new double[numvals]; + for (size_t i=0;i<numvals;i++){ + sprintf(subdir, "loop1_%d", i); + file->cd(subdir); // TDAC steps + TIter nextkey(gDirectory->GetListOfKeys()); // histos + while ((key=(TKey*)nextkey())) { + boost::regex re("_(\\d+)_Occupancy_Point_000"); + boost::cmatch matches; + if(boost::regex_search(key->GetName(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int lnm=strtol(match.c_str(),0,10); + char tdachistoname[128]; + sprintf (tdachistoname, "TDAC_settings_Mod_%d_it_%d", lnm, i); + TH2* histo = (TH2*)key->ReadObj(); + histo->SetMinimum(0); histo->SetMaximum(repetitions); + TH2* tdachisto=(TH2*)gDirectory->Get(tdachistoname); + assert(tdachisto); + histomap[i][lnm].occupancy=histo; + histomap[i][lnm].tdac=tdachisto; + binsx=histo->GetNbinsX(); + binsy=histo->GetNbinsY(); + } + } + } + for(std::map<int, hdatafast>::iterator it=histomap[0].begin();it!=histomap[0].end();it++){ + int id=it->first; + float pct = 100; + sprintf(name, "BestOcc_Mod_%d", id); + sprintf(title, "Best Occupancy Module %d at %s", id, findFieldName(cfg, id)); + TH2F* occBest=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + occBest->SetMinimum(0); occBest->SetMaximum(pct); + occBest->GetXaxis()->SetTitle("Column"); + occBest->GetYaxis()->SetTitle("Row"); + occBest->GetZaxis()->SetTitle("Occupancy[%]"); + + sprintf(name, "BestTdac_Mod_%d", id); + sprintf(title, "Best Tdacs Module %d at %s", id, findFieldName(cfg, id)); + TH2F* tdac=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + tdac->GetXaxis()->SetTitle("Column"); + tdac->GetYaxis()->SetTitle("Row"); + tdac->GetZaxis()->SetTitle("Tdac"); + + struct ipc::PixelFEI4Trims *trims=0; + struct ipc::PixelModuleConfig *conf3=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)trims=&confa->FETrims; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)trims=&confb->FETrims; + else conf3=findFEI3Config(cfg, id); + } + for (int i=1;i<=occBest->GetNbinsX();i++){ + for(int j=1;j<=occBest->GetNbinsY();j++){ + double bestval = 10*targetEff; // must be larger than 1 (with possibilty of double hit) + int index=0; + for(size_t k=0;k<numvals;k++){ + val[k] = histomap[k][id].occupancy->GetBinContent(i,j) / repetitions; + if(fabs(val[k]-targetEff)<bestval){ + index=k; + bestval=fabs(val[k]-targetEff); + } + } + occBest->SetBinContent(i,j,pct*val[index]); + tdac->SetBinContent(i,j,histomap[index][id].tdac->GetBinContent(i,j)); + if(trims)trims->dacThresholdTrim[i-1][j-1]=histomap[index][id].tdac->GetBinContent(i,j); + else if (conf3){ + int chip=(i-1)/FEI3::Frontend::N_COLS; + int col=(i-1)%FEI3::Frontend::N_COLS; + int row=j-1; + conf3->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=histomap[index][id].tdac->GetBinContent(i,j); + } + } + } + + anfile->cd(); + occBest->Write(); + occBest->SetDirectory(gDirectory); + + tdac->Write(); + tdac->SetDirectory(gDirectory); + + m_fw->writeDacFile(Form("%sTdacs_Mod_%d", m_fw->getPath(anfile).c_str(), id), tdac); + if(trims) writeFEI4Config(anfile, runno); + if(conf3) writeFEI3Config(anfile, runno); + } + if(configUpdate())writeTopFile(cfg, anfile, runno); + delete [] histomap; + delete [] val; +} + diff --git a/rce/rcecalib/analysis/TdacFastAnalysis.hh b/rce/rcecalib/analysis/TdacFastAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..08d8d5e522a6664fc399db4b6093790e0ecbd85b --- /dev/null +++ b/rce/rcecalib/analysis/TdacFastAnalysis.hh @@ -0,0 +1,33 @@ +#ifndef TDACFASTANALYSIS_HH +#define TDACFASTANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} +namespace{ + struct hdatafast{ + TH2* occupancy; + TH2* tdac; + }; +} + +class TdacFastAnalysis: public CalibAnalysis{ +public: + TdacFastAnalysis(CfgFileWriter* fw): CalibAnalysis(), m_fw(fw){} + ~TdacFastAnalysis(){delete m_fw;} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +private: + CfgFileWriter* m_fw; +}; + + +#endif diff --git a/rce/rcecalib/analysis/TemperatureAnalysis.cc b/rce/rcecalib/analysis/TemperatureAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..e98ae2538defb1c41016792f2252c37bbc958261 --- /dev/null +++ b/rce/rcecalib/analysis/TemperatureAnalysis.cc @@ -0,0 +1,106 @@ +#include "rcecalib/analysis/TemperatureAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include <math.h> + +using namespace RCE; + +void TemperatureAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Temperature analysis"<<std::endl; + std::vector<float> loopVar=scan->getLoopVarValues(0); + size_t numvals=loopVar.size(); + if(numvals<2){ + std::cout<<"Need at least two values instead of "<<numvals<<std::endl; + return; + } + float a[2]; + for(int i=0;i<2;i++){ + if(loopVar[i]==1)a[i]=1; + else if(loopVar[i]==2)a[i]=10; + else if(loopVar[i]==3)a[i]=1000; + else{ + a[i]=-1; + std::cout<<"Bad setup for temperature scan"<<std::endl; + } + } + float m=a[1]/a[0]; + if(m<1)m=1./m; + std::cout<<"Factor is "<<m<<std::endl; + TIter nextkey(file->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Voltage"); + std::vector<std::string> pos; + std::vector<float> temps; + std::vector<float> errs; + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + std::string title(key->GetTitle()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string match2=addPosition(name.c_str(), cfg).substr(0,5); + pos.push_back(match2); + TH1D* mhis=new TH1D(Form("Temperature_Mod_%d",id), Form("Temperature Mod %d at %s", id, findFieldName(cfg, id)), 1,0,1); + mhis->GetYaxis()->SetTitle("Temperature (C)"); + TH1* histo = (TH1*)key->ReadObj(); + float val1=histo->GetBinContent(1); + float err1=sqrt(histo->GetBinError(1)); + float val2=histo->GetBinContent(2); + float err2=sqrt(histo->GetBinError(2)); + float volttoadc=1.013; + float fact=1.6e-19/1.38e-23/logf(m)/1000./volttoadc; + float temp=(val2-val1)*fact; + if(temp<0)temp=-temp; + temp-=273.15; + float err=sqrt(err1*err1+err2*err2)*fact; + mhis->SetBinContent(1,temp); + mhis->SetBinError(1,err); + std::cout<<"FE at "<<match2<<" has a temperature of "<<temp<<"+-"<<err<<" degrees Celsius."<<std::endl; + temps.push_back(temp); + errs.push_back(err); + anfile->cd(); + mhis->Write(); + mhis->SetDirectory(gDirectory); + delete histo; + } + } + TH1D* mhis[4]; + mhis[0]=new TH1D(Form("1-StavetempsA"), Form("Frontend Temperatures A side"), 16, 0, 16); + mhis[1]=new TH1D(Form("1-StavetempsC"), Form("Frontend Temperatures C side"), 16, 0, 16); + mhis[2]=new TH1D(Form("2-StavetempsA"), Form("Frontend Temperatures A side (2)"), 16, 0, 16); + mhis[3]=new TH1D(Form("2-StavetempsC"), Form("Frontend Temperatures C side (2)"), 16, 0, 16); + char position[10]; + for(int i=0;i<4;i++){ //half stave + if(i%2==0)position[0]='A'; + else position[0]='C'; + mhis[i]->GetYaxis()->SetTitle("Temperature (C)"); + for(int j=1;j<=8;j++){ //module + for(int k=1;k<=2;k++){ //FE + sprintf(&position[1], "%d-%d", j,k); + int bin=(j-1)*2+k; + mhis[i]->GetXaxis()->SetBinLabel(bin,position); + for(size_t l=0;l<pos.size();l++){ + if(std::string(position)==pos[l].substr(1,4) && + pos[l].substr(0,1)==Form("%d", i/2+1)){ + mhis[i]->SetBinContent(bin, temps[l]); + mhis[i]->SetBinError(bin, errs[l]); + } + } + } + } + anfile->cd(); + mhis[i]->Write(); + mhis[i]->SetDirectory(gDirectory); + } +} + diff --git a/rce/rcecalib/analysis/TemperatureAnalysis.hh b/rce/rcecalib/analysis/TemperatureAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..94482b3432a7e20afa805cbeb333ca62ba3cf5f1 --- /dev/null +++ b/rce/rcecalib/analysis/TemperatureAnalysis.hh @@ -0,0 +1,21 @@ +#ifndef TEMPERATUREANALYSIS_HH +#define TEMPERATUREANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class TemperatureAnalysis: public CalibAnalysis{ +public: + TemperatureAnalysis(): CalibAnalysis(){} + ~TemperatureAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/ThresholdAnalysis.cc b/rce/rcecalib/analysis/ThresholdAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..6a1e230ba7a9767229f126c2e1a5d378e742e75e --- /dev/null +++ b/rce/rcecalib/analysis/ThresholdAnalysis.cc @@ -0,0 +1,191 @@ +#include "rcecalib/analysis/ThresholdAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TF1.h" +#include "TStyle.h" + + +void ThresholdAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"Threshold analysis"<<std::endl; + unsigned int numval=scan->getLoopVarValues(0).size(); + gStyle->SetOptFit(10); + //gStyle->SetOptStat(0); + std::map<int, TH1D*> histmap; + TIter nextkey(gDirectory->GetListOfKeys()); // histograms + TKey *key; + std::vector<std::string> pos; + std::vector<float> threshs; + std::vector<float> thresherrs; + std::vector<float> sigmas; + std::vector<float> sigmaerrs; + while ((key=(TKey*)nextkey())) { + file->cd(); + std::string hname(key->GetName()); + boost::cmatch matches; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + char name[128]; + char title[128]; + if(boost::regex_search(hname.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string match2=addPosition(hname.c_str(), cfg).substr(0,5); + pos.push_back(match2); + std::string chi2HistoName = boost::regex_replace (hname, re2, "ChiSquare"); + std::string sigmaHistoName = boost::regex_replace (hname, re2, "Sigma"); + TH2* histo = (TH2*)key->ReadObj(); + TH2* chi2Histo=(TH2*)gDirectory->Get(chi2HistoName.c_str()); + TH2* sigmahisto=(TH2*)gDirectory->Get(sigmaHistoName.c_str()); + assert(chi2Histo!=0); + assert(sigmahisto!=0); + int binsx=histo->GetNbinsX(); + int binsy=histo->GetNbinsY(); + sprintf(name, "thresh2d_Mod_%d", id); + sprintf(title, "Thresholds Module %d at %s", id, findFieldName(cfg, id)); + TH2F* thresh2d=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + thresh2d->GetXaxis()->SetTitle("Column"); + thresh2d->GetYaxis()->SetTitle("Row"); + sprintf(name, "thresh1d_Mod_%d", id); + sprintf(title, "Thresholds Module %d at %s", id, findFieldName(cfg, id)); + int nbins=binsx*binsy; + TH1F* thresh1d=new TH1F(name, title, nbins, 0, (float)nbins); + thresh1d->GetXaxis()->SetTitle("Channel"); + thresh1d->SetOption("p9"); + sprintf(name, "sigma1d_Mod_%d", id); + sprintf(title, "Sigma Module %d at %s", id, findFieldName(cfg, id)); + TH1F* sigma1d=new TH1F(name, title, nbins, 0, (float)nbins); + sigma1d->GetXaxis()->SetTitle("Channel"); + sigma1d->SetOption("p9"); + sprintf(name, "threshdist_Mod_%d", id); + sprintf(title, "Threshold distribution Module %d at %s", id, findFieldName(cfg, id)); + TH1F* threshdist=new TH1F(name, title, 600, 0, 6000); + threshdist->GetXaxis()->SetTitle("Threshold"); + sprintf(name, "sigmadist_Mod_%d", id); + sprintf(title, "Sigma distribution Module %d at %s", id, findFieldName(cfg, id)); + TH1F* sigmadist=new TH1F(name, title, 500, 0, 1000); + sigmadist->GetXaxis()->SetTitle("Sigma"); + sprintf(name, "BadPixels_Mod_%d", id); + sprintf(title, "Bad Pixels Module %d at %s", id, findFieldName(cfg, id)); + TH2F* bad=new TH2F(name, title, binsx, 0, binsx, binsy, 0, binsy); + bad->GetXaxis()->SetTitle("Column"); + bad->GetYaxis()->SetTitle("Row"); + TH1D* hits1d=new TH1D(Form("HitsPerBin_Mod_%d", id), + Form("Hits per bin Mod %d at %s", id, findFieldName(cfg, id)), + numval, -.5, (float)numval-.5) ; + hits1d->GetXaxis()->SetTitle("Scan Point"); + unsigned char (*masks)[ipc::IPC_N_I4_PIXEL_ROWS]=0; + ipc::PixelFEI4AConfig* conf=findFEI4AConfig(cfg, id); + if(conf)masks=conf->FEMasks; + else { + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)masks=confb->FEMasks; + } + if(masks && scan->clearMasks()==true)clearFEI4Masks(masks); + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + thresh2d->SetBinContent(i,j,histo->GetBinContent(i,j)); + thresh1d->SetBinContent((i-1)*histo->GetNbinsY()+j, histo->GetBinContent(i,j)); + threshdist->Fill(histo->GetBinContent(i,j)); + sigma1d->SetBinContent((i-1)*histo->GetNbinsY()+j, sigmahisto->GetBinContent(i,j)); + sigmadist->Fill(sigmahisto->GetBinContent(i,j)); + if(chi2Histo->GetBinContent(i,j)==0){ + bad->SetBinContent(i,j,1); + if(masks){ + masks[i-1][j-1]&=0xfe; //reset bit 0 (enable) + masks[i-1][j-1]|=0x8; //reset bit 3 (hitbus) + } + } + } + } + TF1 gauss("gauss", "gaus", 100, 10000); + gauss.SetParameter(0, threshdist->GetMaximum()); + gauss.SetParameter(1, threshdist->GetMaximumBin()*threshdist->GetBinWidth(1)); + threshdist->Fit(&gauss,"q", "", 100, 10000); + sigmadist->Fit("gaus","q"); + threshs.push_back(threshdist->GetMean()); + thresherrs.push_back(threshdist->GetRMS()); + sigmas.push_back(sigmadist->GetMean()); + sigmaerrs.push_back(sigmadist->GetRMS()); + + for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (hname, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } + + if(masks) writeFEI4Config(anfile, runno); + anfile->cd(); + thresh2d->Write(); + thresh2d->SetDirectory(gDirectory); + thresh1d->Write(); + thresh1d->SetDirectory(gDirectory); + threshdist->Write(); + threshdist->SetDirectory(gDirectory); + sigma1d->Write(); + sigma1d->SetDirectory(gDirectory); + sigmadist->Write(); + sigmadist->SetDirectory(gDirectory); + bad->Write(); + bad->SetDirectory(gDirectory); + hits1d->Write(); + hits1d->SetDirectory(gDirectory); + } + } + TH1D* mhis[2]; + mhis[0]=new TH1D(Form("1-Thresholds"), Form("Thresholds 1st stave"), 32, 0, 32); + mhis[1]=new TH1D(Form("2-Thresholds"), Form("Thresholds 2nd stave"), 32, 0, 32); + TH1D* shis[2]; + shis[0]=new TH1D(Form("1-Sigma"), Form("Sigma 1st stave"), 32, 0, 32); + shis[1]=new TH1D(Form("2-Sigma"), Form("Sigma 2nd stave"), 32, 0, 32); + char position[10]; + for(int i=0;i<4;i++){ //half stave + if(i%2==0)position[0]='A'; + else position[0]='C'; + //mhis[i]->GetYaxis()->SetTitle("Threshold (e)"); + for(int j=1;j<=8;j++){ //module + for(int k=1;k<=2;k++){ //FE + sprintf(&position[1], "%d-%d", j,k); + int bin=0; + if(i%2==0)bin=17-((j-1)*2+k); // A side + else bin=16+(j-1)*2+k; + mhis[i/2]->GetXaxis()->SetBinLabel(bin,position); + shis[i/2]->GetXaxis()->SetBinLabel(bin,position); + for(size_t l=0;l<pos.size();l++){ + if(std::string(position)==pos[l].substr(1,4) && + pos[l].substr(0,1)==Form("%d", i/2+1)){ + mhis[i/2]->SetBinContent(bin, threshs[l]); + mhis[i/2]->SetBinError(bin, thresherrs[l]); + shis[i/2]->SetBinContent(bin, sigmas[l]); + shis[i/2]->SetBinError(bin, sigmaerrs[l]); + } + } + } + } + if(i%2==1){ + anfile->cd(); + mhis[i/2]->Write(); + mhis[i/2]->SetDirectory(gDirectory); + shis[i/2]->Write(); + shis[i/2]->SetDirectory(gDirectory); + } + } + + if(configUpdate())writeTopFile(cfg, anfile, runno); + +} diff --git a/rce/rcecalib/analysis/ThresholdAnalysis.hh b/rce/rcecalib/analysis/ThresholdAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..b4b415974b31c5d8da56fa381a30a04bb16a2b44 --- /dev/null +++ b/rce/rcecalib/analysis/ThresholdAnalysis.hh @@ -0,0 +1,24 @@ +#ifndef THRESHOLDANALYSIS_HH +#define THRESHOLDANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include <map> + +class ConfigGui; +class TFile; +class TH2; +class TH1D; + +namespace RCE{ + class PixScan; +} + +class ThresholdAnalysis: public CalibAnalysis{ +public: + ThresholdAnalysis(): CalibAnalysis(){} + ~ThresholdAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/TimeWalkAnalysis.cc b/rce/rcecalib/analysis/TimeWalkAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..26ff39c73953e5ff7514e6d5199a33c7516c2aa2 --- /dev/null +++ b/rce/rcecalib/analysis/TimeWalkAnalysis.cc @@ -0,0 +1,237 @@ +#include "rcecalib/analysis/TimeWalkAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +#include <TFile.h> +#include <TStyle.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TF1.h> +#include <TKey.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> + +namespace{ + const double threshold=0; +} +using namespace RCE; + +void TimeWalkAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + //unsigned int numval=scan->getLoopVarValues(0).size(); + gStyle->SetOptFit(10); + gStyle->SetOptStat(0); + std::cout<<"TimeWalk analysis"<<std::endl; + + const int totalScans = scan->getLoopVarValues(1).size(); + + float xVals[totalScans]; + float yVals[totalScans]; + + + TH1D* t0mean[totalScans]; + // TH1D* t0sigma[totalScans]; + + TH1D* histoTW(0); + + + float xMin = scan->getLoopVarValues(1).at(0); + float xMax = scan->getLoopVarValues(1).at(totalScans-1); + + if(xMax<xMin){ + float xtemp = xMax; + xMax = xMin; + xMin = xtemp; + } + + histoTW = new TH1D(Form("TimeWalk"), Form("Time Walk integrated over all pixels"), 50, xMin - 1, xMax + 1); + histoTW->GetXaxis()->SetTitle("N(e^{-})"); + histoTW->GetYaxis()->SetTitle("t0 (strobe delay counts)"); + + histoTW->SetOption("P"); + histoTW->SetMarkerStyle(2); + histoTW->SetMarkerSize(2); + + + + + //loop over the different T0 scans + for(int iScan = 0; iScan<totalScans; iScan++){ + + file->cd(Form("loop1_%d",iScan)); + + + TIter nextkey(gDirectory->GetListOfKeys()); + TKey *key; + boost::regex re("_(\\d+)_Mean"); + boost::regex re2("Mean"); + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + + + // std::cout<<"match = "<<match.c_str()<<std::endl; + int id=strtol(match.c_str(),0,10); + + // std::cout<<"id = "<<id<<std::endl; + + std::string sigmaHistoName = boost::regex_replace (name, re2, "Sigma"); + + struct ipc::PixelFECalibFEI4 *fecalib=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)fecalib=&confa->FECalib; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)fecalib=&confb->FECalib; + } + + TH2* histo = (TH2*)key->ReadObj(); + TH2* sigmaHisto=(TH2*)gDirectory->Get(sigmaHistoName.c_str()); + assert(sigmaHisto); + + + + //Get histogram ranges + float maxval[2] = {0,0}; + float minval[2] = {1e8, 1e8}; + float vals[2] = {0,0}; + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + + vals[0] = histo->GetBinContent(i, j); + vals[1] = sigmaHisto->GetBinContent(i, j); + + for(int kpar = 0; kpar<2; kpar++){ + if(vals[kpar]>maxval[kpar]){ + maxval[kpar] = vals[kpar]; + } + if(vals[kpar]<minval[kpar]&&vals[kpar]>0){ + minval[kpar] = vals[kpar]; + } + } + + } + } + + // TH1D* t0sigma[2]; + + + t0mean[iScan] =new TH1D(Form("T0_%d_Mod_%d",iScan,id), + Form("T0 for each pixel in Mod %d at %s (Scan %d)" + , id, findFieldName(cfg, id), iScan), + 50, minval[0]-1, maxval[0]+1); + // t0sigma[iScan] =new TH1D(Form("Sigma_%d_Mod_%d",iScan,id), Form("T0 S-CURVE sigma for each pixel in Mod %d (Scan %d)", id, iScan), 50, minval[1]-1, maxval[1]+1); + + t0mean[iScan]->GetXaxis()->SetTitle("t0 (strobe delay counts)"); + // t0sigma[iScan]->GetXaxis()->SetTitle("t0 S-Curve sigma (strobe delay counts)"); + + + for (int i=1;i<=histo->GetNbinsX();i++){ + for(int j=1;j<=histo->GetNbinsY();j++){ + + float val=0; + + if(histo->GetBinContent(i, j)!=0 ){ + val = histo->GetBinContent(i, j); + t0mean[iScan]->Fill(val); + } + + + // if(sigmaHisto->GetBinContent(i, j)!=0 ){ + // val = sigmaHisto->GetBinContent(i, j); + // t0sigma[iScan]->Fill(val); + // } + + } + + } + + t0mean[iScan]->Fit("gaus"); + yVals[iScan] = t0mean[iScan]->GetFunction("gaus")->GetParameter(1); + std::cout<<"T0 for module "<<id<<" for scan "<<iScan<<" is "<<yVals[iScan]<<std::endl; + + + + + xVals[iScan] = scan->getLoopVarValues(1).at(iScan); + + // std::cout<<"at scan "<<iScan<<" , x = "<<xVals[iScan]<<std::endl; + + + // for (int i=1;i<=histo->GetNbinsX();i++){ + // for(int j=1;j<=histo->GetNbinsY();j++){ + + // float val=0; + + // if(histo->GetBinContent(i, j)!=0 ){ + // val = histo->GetBinContent(i, j)*convFactor; + // t0mean_ns[0]->Fill(val); + // } + // if(histo2->GetBinContent(i, j)!=0 ){ + // val = histo2->GetBinContent(i, j)*convFactor; + // t0mean_ns[1]->Fill(val); + // } + + // if(sigmaHisto->GetBinContent(i, j)!=0 ){ + // val = sigmaHisto->GetBinContent(i, j)*convFactor; + // t0sigma_ns[0]->Fill(val); + // } + // if(sigmaHisto2->GetBinContent(i, j)!=0 ){ + // val = sigmaHisto2->GetBinContent(i, j)*convFactor; + // t0sigma_ns[1]->Fill(val); + // } + + // } + + // } + + + delete histo; + anfile->cd(); + + t0mean[iScan]->Write(); + t0mean[iScan]->SetDirectory(gDirectory); +// t0sigma[scan]->Write(); +// t0sigma[scan]->SetDirectory(gDirectory); + +// t0mean_ns[scan]->Write(); +// t0mean_ns[scan]->SetDirectory(gDirectory); +// t0sigma_ns[scan]->Write(); +// t0sigma_ns[scan]->SetDirectory(gDirectory); + file->cd(Form("loop1_%d",iScan)); + + } + + } + + } //end loop over iScan + + + for(int iScan = 0; iScan<totalScans; iScan++){ + + histoTW->Fill(xVals[iScan], yVals[iScan]); + + } + anfile->cd(); + histoTW->Write(); + histoTW->SetDirectory(gDirectory); + +} + + +void TimeWalkAnalysis::fillHit1d(std::string &name, TH1* hits1d, unsigned numval){ +for(unsigned int k=0;k<numval;k++){ + boost::regex re2("Mean"); + std::string histoName = boost::regex_replace (name, re2, Form("Occupancy_Point_%03d", k)); + TH2* occHisto=(TH2*)gDirectory->Get(histoName.c_str()); + if(occHisto==0){ + std::cout<<"No Occupancy histograms found. Won't fill 1-d hit histo."<<std::endl; + break; + } + hits1d->SetBinContent(k+1, occHisto->GetSumOfWeights()); + } +} diff --git a/rce/rcecalib/analysis/TimeWalkAnalysis.hh b/rce/rcecalib/analysis/TimeWalkAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..0e0bfddba0f57a235dfe11f9a3adde6cec7549f9 --- /dev/null +++ b/rce/rcecalib/analysis/TimeWalkAnalysis.hh @@ -0,0 +1,23 @@ +#ifndef TIMEWALKANALYSIS_HH +#define TIMEWALKANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" + +class ConfigGui; +class TFile; +class TH2D; +class TH1; +namespace RCE{ + class PixScan; +} + +class TimeWalkAnalysis: public CalibAnalysis{ +public: + TimeWalkAnalysis(): CalibAnalysis(){} + ~TimeWalkAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); + void fillHit1d(std::string &name, TH1* hits1d, unsigned numval); +}; + + +#endif diff --git a/rce/rcecalib/analysis/TotAnalysis.cc b/rce/rcecalib/analysis/TotAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..fa30aa55012229c5c90446d0523669a9d3be2438 --- /dev/null +++ b/rce/rcecalib/analysis/TotAnalysis.cc @@ -0,0 +1,169 @@ +#include "rcecalib/analysis/TotAnalysis.hh" +#include <boost/regex.hpp> + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1D.h> +#include <TKey.h> +#include <TStyle.h> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <cmath> + +void TotAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + gStyle->SetOptFit(111); + printf("Begin TOT Analysis\n"); + std::map<int, odata> histomap; + TKey *key; + std::vector<std::string> pos; + std::vector<float> tots; + std::vector<float> toterrs; + std::vector<float> sigmas; + std::vector<float> sigmaerrs; + + int binsx=0, binsy=0; + TIter nextkey(gDirectory->GetListOfKeys()); // TDAC settings + while ((key=(TKey*)nextkey())) { + std::string name(key->GetName()); + boost::regex re(Form("_(\\d+)_Occupancy_Point_%03d", 0)); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int lnm=strtol(match.c_str(),0,10); + std::string match2=addPosition(name.c_str(), cfg).substr(0,5); + pos.push_back(match2); + histomap[lnm].occ = (TH2*)key->ReadObj(); + boost::regex re2("Occupancy"); + std::string totHistoName = boost::regex_replace (name, re2, "ToT"); + histomap[lnm].tot=(TH2*)gDirectory->Get(totHistoName.c_str()); + std::string tot2HistoName = boost::regex_replace (name, re2, "ToT2"); + histomap[lnm].tot2=(TH2*)gDirectory->Get(tot2HistoName.c_str()); + assert(histomap[lnm].tot2); + binsx=histomap[lnm].tot2->GetNbinsX(); + binsy=histomap[lnm].tot2->GetNbinsY(); + } + } + for(std::map<int, odata>::iterator it=histomap.begin();it!=histomap.end();it++){ + int id=it->first; + int max=15; + if(findFEType(cfg, id)=="FEI3")max=63; + TH2D* ahis = new TH2D(Form("ToT_Mean_Mod_%i", id), + Form("ToT Mean Mod %d at %s", id, findFieldName(cfg, id)), + binsx,0,binsx,binsy,0,binsy); + ahis->GetXaxis()->SetTitle("Column"); + ahis->GetYaxis()->SetTitle("Row"); + ahis->SetMinimum(0); + ahis->SetMaximum(max+1); + TH2D* shis = new TH2D(Form("ToT_Sigma_Mod_%i", id), + Form("ToT Sigma Mod %d at %s", id, findFieldName(cfg, id)), + binsx,0,binsx,binsy,0,binsy); + ahis->GetXaxis()->SetTitle("Column"); + ahis->GetYaxis()->SetTitle("Row"); + TH2D* badpix = new TH2D(Form("BadPixels_Mod_%i", id), Form("Bad Pixel Map Mod %d", id),binsx,0,binsx,binsy,0,binsy); + badpix->GetXaxis()->SetTitle("Column"); + badpix->GetYaxis()->SetTitle("Row"); + TH1D* channel = new TH1D(Form("ToT_Mean_Channel_Mod_%i", id), + Form("ToT Mean Mod %d at %s", id, findFieldName(cfg, id)), + binsx*binsy,0,binsx*binsy); + channel->GetXaxis()->SetTitle("Channel"); + channel->SetOption("p9"); + channel->SetMinimum(0); + channel->SetMaximum(max+1); + TH1D* schannel = new TH1D(Form("ToT_Sigma_Channel_Mod_%i", id), + Form("ToT Sigma Mod %d at %s", id, findFieldName(cfg, id)), + binsx*binsy,0,binsx*binsy); + schannel->GetXaxis()->SetTitle("Channel"); + schannel->SetOption("p9"); + TH1D* dist=new TH1D(Form("ToT_Mean_Dist_Mod_%i", id), + Form("ToT Distribution Mod %d at %s", id, findFieldName(cfg, id)), + 100, 0, max); + dist->GetXaxis()->SetTitle("ToT"); + TH1D* sdist=new TH1D(Form("ToT_Sigma_Dist_Mod_%i", id), + Form("ToT Sigma Distribution Mod %d at %s", id, findFieldName(cfg, id)), + 100, 0, 3); + sdist->GetXaxis()->SetTitle("ToT"); + TH2* occ_histo=histomap[id].occ; + TH2* tot_histo=histomap[id].tot; + TH2* tot2_histo=histomap[id].tot2; + for(int j = 1; j <= ahis->GetNbinsX(); j++){ + for(int k = 1; k <= ahis->GetNbinsY(); k++){ + //printf("Point %3i\n",i); + float nhits = occ_histo->GetBinContent(j,k); + float tot=0; + if(nhits != 0){ + tot = float(tot_histo->GetBinContent(j,k)) / nhits; + float tot2=tot2_histo->GetBinContent(j,k); + float sig=0; + if(tot2>0)sig=sqrt(tot2/nhits-tot*tot); + ahis->SetBinContent(j,k,tot); + shis->SetBinContent(j,k,sig); + channel->SetBinContent(k+(j-1)*binsy, tot); + schannel->SetBinContent(k+(j-1)*binsy, sig); + dist->Fill(tot); + sdist->Fill(sig); + } + else badpix->SetBinContent(j,k,1); + } + } + dist->Fit("gaus"); + tots.push_back(dist->GetMean()); + std::cout<<"Dist Mean value: "<<dist->GetMean()<<", Dist Err: "<<dist->GetRMS()<<"|| Module: "<<findFieldName(cfg,id)<<std::endl; + toterrs.push_back(dist->GetRMS()); + anfile->cd(); + ahis->Write(); + ahis->SetDirectory(gDirectory); + shis->Write(); + shis->SetDirectory(gDirectory); + badpix->Write(); + badpix->SetDirectory(gDirectory); + channel->Write(); + channel->SetDirectory(gDirectory); + schannel->Write(); + schannel->SetDirectory(gDirectory); + dist->Write(); + dist->SetDirectory(gDirectory); + sdist->Write(); + sdist->SetDirectory(gDirectory); + } + TH1D* mhis[2]; + mhis[0]=new TH1D(Form("1-Tots"), Form("Tots 1st stave"), 32, 0, 32); + mhis[1]=new TH1D(Form("2-Tots"), Form("Tots 2nd stave"), 32, 0, 32); + + char position[10]; + for(int i=0;i<4;i++){ //half stave + if(i%2==0)position[0]='A'; + else position[0]='C'; + //mhis[i]->GetYaxis()->SetTitle("Threshold (e)"); + for(int j=1;j<=8;j++){ //module + for(int k=1;k<=2;k++){ //FE + sprintf(&position[1], "%d-%d", j,k); + int bin=0; + if(i%2==0)bin=17-((j-1)*2+k); // A side + else bin=16+(j-1)*2+k; + mhis[i/2]->GetXaxis()->SetBinLabel(bin,position); + for(size_t l=0;l<pos.size();l++){ + if(std::string(position)==pos[l].substr(1,4) && + pos[l].substr(0,1)==Form("%d", i/2+1)){ + mhis[i/2]->SetBinContent(bin, tots[l]); + mhis[i/2]->SetBinError(bin, toterrs[l]); + + } + } + } + } + if(i%2==1){ + anfile->cd(); + mhis[i/2]->Write(); + mhis[i/2]->SetDirectory(gDirectory); + } + } + + + + + printf("Done Analysis\n"); +} + diff --git a/rce/rcecalib/analysis/TotAnalysis.hh b/rce/rcecalib/analysis/TotAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..420364aed31c26ba6d32d1fab9ca7da1c8063159 --- /dev/null +++ b/rce/rcecalib/analysis/TotAnalysis.hh @@ -0,0 +1,28 @@ +#ifndef TOT_ANALYSIS_HH +#define TOT_ANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/CfgFileWriter.hh" +#include "rcecalib/server/PixScan.hh" + +class TFile; +class TH2; +namespace RCE{ + class PixScan; +} +class ConfigGui; + +class TotAnalysis: public CalibAnalysis{ +public: + struct odata{ + TH2* occ; + TH2* tot; + TH2* tot2; + }; + TotAnalysis(): CalibAnalysis(){} + ~TotAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/TotCalibAnalysis.cc b/rce/rcecalib/analysis/TotCalibAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..a0e4200f189686610a02e628090cfeb03de6ee9c --- /dev/null +++ b/rce/rcecalib/analysis/TotCalibAnalysis.cc @@ -0,0 +1,165 @@ +#include "analysis/TotCalibAnalysis.hh" +#include "server/PixScan.hh" +#include "server/ConfigGui.hh" +#include "config/FEI3/Module.hh" +#include "config/FEI4/Module.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TF1.h> +#include <TCanvas.h> +#include <TKey.h> +#include <TMath.h> +#include <boost/regex.hpp> +#include <iostream> +#include <fstream> +#include "TH1D.h" +#include "TStyle.h" + +void TotCalibAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + std::cout<<"TOT Calibration analysis running..."<<std::endl; + int repetitions = scan->getRepetitions(); + double targetEff = 0.5; + TKey* key; + char subdir[128]; + char name[128]; + char title[128]; + int binsx=0; + size_t numvals=scan->getLoopVarValues(1).size(); + std::map<int, int> idmap; + std::vector<int> modmap; + int nmod=0; + int nrows=336; + int ncols=80; + std::vector<float> varValues=scan->getLoopVarValues(1); + std::vector<std::vector<double**> > n, x, x2; + for (size_t i=0;i<numvals;i++){ + sprintf(subdir, "loop1_%d", i); + file->cd(subdir); // GDAC steps + TIter nextkey(gDirectory->GetListOfKeys()); // histos + while ((key=(TKey*)nextkey())) { + boost::cmatch matches; + boost::regex re("_(\\d+)_Occupancy_ToT_(\\d+)"); + if(boost::regex_search(key->GetName(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + std::string match2(matches[2].first, matches[2].second); + int tot=strtol(match2.c_str(),0,10); + TH2* histo = (TH2*)key->ReadObj(); + if(idmap.find(id)==idmap.end()){ + std::vector<double** > nvec; + std::vector<double** > xvec; + std::vector<double** > x2vec; + n.push_back(nvec); + x.push_back(xvec); + x2.push_back(x2vec); + for(int l=0;l<16;l++){ + n[nmod].push_back(new double*[ncols]); + x[nmod].push_back(new double*[ncols]); + x2[nmod].push_back(new double*[ncols]); + for(int j=0;j<ncols;j++){ + n[nmod][l][j]=new double[nrows]; + x[nmod][l][j]=new double[nrows]; + x2[nmod][l][j]=new double[nrows]; + for(int k=0;k<nrows;k++){ + n[nmod][l][j][k]=0; + x[nmod][l][j][k]=0; + x2[nmod][l][j][k]=0; + } + + } + } + modmap.push_back(id); + idmap[id]=nmod++; + } + int mod=idmap[id]; + struct ipc::PixelFECalibFEI4 *fecalib=0; + ipc::PixelFEI4AConfig* confa=findFEI4AConfig(cfg, id); + if(confa)fecalib=&confa->FECalib; + else{ + ipc::PixelFEI4BConfig* confb=findFEI4BConfig(cfg, id); + if(confb)fecalib=&confb->FECalib; + } + assert(fecalib); + float clo=fecalib->cinjLo; + float chi=fecalib->cinjHi; + float vcal1=fecalib->vcalCoeff[1]; + float vcal0=fecalib->vcalCoeff[0]; + float capacitance=0; + if(scan->getMaskStageMode()==PixLib::EnumMaskStageMode::FEI4_ENA_SCAP)capacitance=clo; + else if(scan->getMaskStageMode()==PixLib::EnumMaskStageMode::FEI4_ENA_LCAP)capacitance=chi; + else if(scan->getMaskStageMode()==PixLib::EnumMaskStageMode::FEI4_ENA_BCAP)capacitance=chi+clo; + capacitance=capacitance*6241; + float fldac=(float)varValues[i]; + float el= capacitance*(vcal0 + vcal1*fldac); + + for(int row=0;row<nrows;row++){ + for(int col=0;col<ncols;col++){ + double nentries=histo->GetBinContent(col+1, row+1); + n[mod][tot][col][row]+=nentries; + x[mod][tot][col][row]+=el*nentries; + x2[mod][tot][col][row]+=el*el*nentries; + } + } + } + } + } + std::cout<<"Part 1 done"<<std::endl; + anfile->cd(); + TH1D cc("calibration curve", "calibration curve", 16, 0, 16); + for (int mod=0;mod<nmod;mod++){ + int id=modmap[mod]; + TH2D* p0=new TH2D(Form("P0_Mod_%i",id),Form("P0 Mod %d at %s", id, findFieldName(cfg, id)),ncols, 0, ncols, nrows, 0, nrows); + TH2D* p1=new TH2D(Form("P1_Mod_%i",id),Form("P1 Mod %d at %s", id, findFieldName(cfg, id)),ncols, 0, ncols, nrows, 0, nrows); + TH2D* p2=new TH2D(Form("P2_Mod_%i",id),Form("P2 Mod %d at %s", id, findFieldName(cfg, id)),ncols, 0, ncols, nrows, 0, nrows); + for(int col=0;col<ncols;col++){ + for(int row=0;row<nrows;row++){ + cc.Reset(); + for(int tot=0;tot<16;tot++){ + double nent=n[mod][tot][col][row]; + if(nent!=0){ + cc.SetBinContent(tot+1, x[mod][tot][col][row]/nent); + cc.SetBinError(tot+1, TMath::Sqrt(TMath::Abs(x2[mod][tot][col][row]-x[mod][tot][col][row]*x[mod][tot][col][row]/nent))/nent); + } + } + cc.Fit("pol2", "", "", 1, 13); + TF1* fitfun=cc.GetFunction("pol2"); + if(fitfun && fitfun->GetNpar()==3){ + p0->SetBinContent(col+1,row+1, fitfun->GetParameter(0)); + p1->SetBinContent(col+1,row+1, fitfun->GetParameter(1)); + p2->SetBinContent(col+1,row+1, fitfun->GetParameter(2)); + } + } + } + p0->Write(); + p1->Write(); + p2->Write(); + } + for(size_t i=0;i<n.size();i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<ncols;k++){ + delete [] n[i][j][k]; + } + delete [] n[i][j]; + } + } + for(size_t i=0;i<n.size();i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<ncols;k++){ + delete [] x[i][j][k]; + } + delete [] x[i][j]; + } + } + for(size_t i=0;i<n.size();i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<ncols;k++){ + delete [] x2[i][j][k]; + } + delete [] x2[i][j]; + } + } +} diff --git a/rce/rcecalib/analysis/TotCalibAnalysis.hh b/rce/rcecalib/analysis/TotCalibAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..3fae4b4f66887627f9c0a98df540fb3c2b834d3b --- /dev/null +++ b/rce/rcecalib/analysis/TotCalibAnalysis.hh @@ -0,0 +1,23 @@ +#ifndef TOTCALIB_ANALYSIS_HH +#define TOTCALIB_ANALYSIS_HH + +#include "analysis/CalibAnalysis.hh" +#include "analysis/CfgFileWriter.hh" +#include "server/PixScan.hh" + +class TFile; +class TH2; +namespace RCE{ + class PixScan; +} +class ConfigGui; + +class TotCalibAnalysis: public CalibAnalysis{ +public: + TotCalibAnalysis(): CalibAnalysis(){} + ~TotCalibAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/analysis/analysisGui_Linkdef.hh b/rce/rcecalib/analysis/analysisGui_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..798aa03f737143e6e254d4c5b1738c1c60637061 --- /dev/null +++ b/rce/rcecalib/analysis/analysisGui_Linkdef.hh @@ -0,0 +1,2 @@ +#pragma link C++ class AnalysisGui; +#pragma link C++ class ConfigGui; diff --git a/rce/rcecalib/analysis/constituents.mk b/rce/rcecalib/analysis/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..a1bfff7ccdedd9bdc048c6dc8873dfb9be740cd5 --- /dev/null +++ b/rce/rcecalib/analysis/constituents.mk @@ -0,0 +1,124 @@ +ifeq ($(profiler),y) +CPPFLAGS+='-D__PROFILER_ENABLED__' +profiler_lib=rcecalib/profiler +endif + + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := analysis +libsrcs_analysis:= NoiseAnalysis.cc \ + GdacAnalysis.cc \ + GdacFastAnalysis.cc \ + GdacCoarseFastAnalysis.cc \ + TdacAnalysis.cc \ + TdacFastAnalysis.cc \ + Fdac_Analysis.cc \ + ThresholdAnalysis.cc \ + Iff_Analysis.cc \ + TotAnalysis.cc \ + TotCalibAnalysis.cc \ + DigitalTestAnalysis.cc \ + ModuleCrosstalkAnalysis.cc \ + OffsetAnalysis.cc \ + CrosstalkAnalysis.cc \ + T0Analysis.cc \ + TimeWalkAnalysis.cc \ + AnalysisFactory.cc \ + CalibAnalysis.cc \ + CfgFileWriter.cc \ + Fei4CfgFileWriter.cc \ + Fei3CfgFileWriter.cc \ + StuckPixelAnalysis.cc \ + MultiTrigAnalysis.cc \ + MultiTrigNoiseAnalysis.cc \ + SerialNumberAnalysis.cc \ + RegisterTestAnalysis.cc \ + TemperatureAnalysis.cc + +libincs_analysis := \ + rcecalib + + +LXFLAGS +=-pthread -lm -ldl -rdynamic +rootlibs:= \ + $(RELEASE_DIR)/build/root/lib/Gui \ + $(RELEASE_DIR)/build/root/lib/Thread \ + $(RELEASE_DIR)/build/root/lib/MathCore \ + $(RELEASE_DIR)/build/root/lib/Physics \ + $(RELEASE_DIR)/build/root/lib/Matrix \ + $(RELEASE_DIR)/build/root/lib/Postscript \ + $(RELEASE_DIR)/build/root/lib/Rint \ + $(RELEASE_DIR)/build/root/lib/Tree \ + $(RELEASE_DIR)/build/root/lib/Gpad \ + $(RELEASE_DIR)/build/root/lib/Graf3d \ + $(RELEASE_DIR)/build/root/lib/Graf \ + $(RELEASE_DIR)/build/root/lib/Hist \ + $(RELEASE_DIR)/build/root/lib/Net \ + $(RELEASE_DIR)/build/root/lib/RIO \ + $(RELEASE_DIR)/build/root/lib/Cint \ + $(RELEASE_DIR)/build/root/lib/Core + +tgtnames := analysisGui mergeMaskFilesFei4 histoViewer + +GUIHEADERSDEP = AnalysisGui.hh ../server/ConfigGui.hh HistoViewerGui.hh + +#-------------------------------------------- +tgtsrcs_analysisGui := AnalysisGui.cc \ + ../server/PixScan.cc \ + ../server/ConfigGui.cc \ + ../server/FEI4AConfigFile.cc \ + ../server/FEI4BConfigFile.cc \ + ../server/TurboDaqFile.cc \ + ../server/HitbusConfigFile.cc \ + ../server/AFPHPTDCConfigFile.cc \ + analysisGui_rootDict.cc + +guiheaders_analysisGui := AnalysisGui.hh ../server/ConfigGui.hh + + +tgtincs_analysisGui := \ + rcecalib \ + rcecalib/analysis + + + +tgtlibs_analysisGui := \ + rcecalib/analysis + +tgtslib_analysisGui := \ + dl\ + $(z_lib) \ + $(rootlibs) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(ers_lib) \ + $(boost_regex_lib) +#-------------------------------------------- +tgtsrcs_histoViewer := HistoViewerGui.cc \ + histoViewer_rootDict.cc + +guiheaders_histoViewer := HistoViewerGui.hh + + +tgtincs_histoViewer := \ + rcecalib \ + rcecalib/analysis + + + +tgtlibs_histoViewer := + +tgtslib_histoViewer := \ + dl\ + $(z_lib) \ + $(rootlibs) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(ers_lib) \ + $(boost_regex_lib) +tgtsrcs_mergeMaskFilesFei4 := MergeMaskFilesFei4.cc Fei4CfgFileWriter.cc +tgtincs_mergeMaskFilesFei4 := $(root_include_path) $(boost_include_path) +tgtslib_mergeMaskFilesFei4 := $(rootlibs) + +endif + diff --git a/rce/rcecalib/analysis/histoViewer_Linkdef.hh b/rce/rcecalib/analysis/histoViewer_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..5d778d1280b75c17a2812edcd54da06dc8166010 --- /dev/null +++ b/rce/rcecalib/analysis/histoViewer_Linkdef.hh @@ -0,0 +1 @@ +#pragma link C++ class HistoViewerGui; diff --git a/rce/rcecalib/analysis/tdacScanAnalysis.cc b/rce/rcecalib/analysis/tdacScanAnalysis.cc new file mode 100644 index 0000000000000000000000000000000000000000..02d55a2828aa056bd880d331e7c23e99892d33f5 --- /dev/null +++ b/rce/rcecalib/analysis/tdacScanAnalysis.cc @@ -0,0 +1,89 @@ +#include "rcecalib/analysis/tdacScanAnalysis.hh" + +#include <TFile.h> +#include <TH2.h> +#include <TH2D.h> +#include <TH1.h> +#include <TKey.h> +#include <iostream> +#include <iomanip> +#include <fstream> +#include <cmath> + +void tdacScanAnalysis::analyze(TFile* file, TFile *anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]){ + printf("Begin TDAC Analysis\n"); + float target = scan->getThresholdTargetValue(); + printf("Target Threshold Value: %2.1f\n",target); + for(int rce = 0; rce < 8; rce++){ + for(int module = 0; module < 16; module++){ + if(file->Get(Form("loop1_0/RCE%i_Mod_%i_Mean",rce,module)) == 0) continue; + TH2D* tdachis = new TH2D(Form("RCE%i_Mod_%i_TDAC",rce,module),"Best TDAC Settings",80,0,80,336,0,336); + tdachis->GetXaxis()->SetTitle("Column"); + tdachis->GetYaxis()->SetTitle("Row"); + TH2D* ahis = new TH2D(Form("RCE%i_Mod_%i_Threshold_MinDiff",rce,module),"min(Threshold - Target Threshold)",80,0,80,336,0,336); + ahis->GetXaxis()->SetTitle("Column"); + ahis->GetYaxis()->SetTitle("Row"); + for(int c = 1; c < 81; c++){ + for(int r = 1; r < 337; r++){ + ahis->SetBinContent(c,r,-1.0); + } + } + for(int i = 0; i < 32; i++){ + //printf("Point %3i\n",i); + TH2* mean_histo; + TH2* occ_histo; + mean_histo = (TH2*)file->Get(Form("loop1_%i/RCE%i_Mod_%i_Mean",i,rce,module)); + occ_histo = (TH2*)file->Get(Form("loop1_%i/RCE%i_Mod_%i_Occupancy_Point_100",i,rce,module)); + double mean = 0.0; + for(int j = 1; j <= mean_histo->GetNbinsX(); j++){ + for(int k = 1; k <= mean_histo->GetNbinsY(); k++){ + float nhits = occ_histo->GetBinContent(j,k); + if(nhits != 0){ + mean = mean_histo->GetBinContent(j,k); + if(std::fabs(mean - target) < ahis->GetBinContent(j,k) || ahis->GetBinContent(j,k) < 0){ + ahis->SetBinContent(j,k,std::fabs(mean - target)); + tdachis->SetBinContent(j,k,i); + } + } + } + } + delete mean_histo; + delete occ_histo; + } + std::string fn(anfile->GetName()); + int pos = fn.find("analysis.root"); + std::string outname = Form("%stdacs%i.dat",fn.substr(0,pos).c_str(),(rce*16+module)); + ofstream outfile(outname.c_str()); + outfile << "### "; + for (int i=1; i<41;i++) { + outfile << std::setw(4) << i; + } + outfile << std::endl; + outfile << "### "; + for (int i=41; i<81;i++) { + outfile << std::setw(4) << i; + } + outfile << std::endl; + for (int row=1; row<337; row++) { + outfile << std::setw(3) << row << "a"; + for (int col=1; col<41; col++) { + outfile << std::setw(4) << int(tdachis->GetBinContent(col,row)); + } + outfile << std::endl; + outfile << std::setw(3) << row << "b"; + for (int col=41; col<81; col++) { + outfile << std::setw(4) << int(tdachis->GetBinContent(col,row)); + } + outfile << std::endl; + + } + anfile->cd(); + tdachis->Write(); + ahis->Write(); + delete ahis; + delete tdachis; + } + } + printf("Done Analysis\n"); +} + diff --git a/rce/rcecalib/analysis/tdacScanAnalysis.hh b/rce/rcecalib/analysis/tdacScanAnalysis.hh new file mode 100644 index 0000000000000000000000000000000000000000..3f5b27780482b42ac4cbb6463ea697e9c8c56199 --- /dev/null +++ b/rce/rcecalib/analysis/tdacScanAnalysis.hh @@ -0,0 +1,22 @@ +#ifndef TDACSCANANALYSIS_HH +#define TDACSCANANALYSIS_HH + +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/server/PixScan.hh" + +class ConfigGui; +class TFile; +class TH2D; +namespace RCE{ + class PixScan; +} + +class tdacScanAnalysis: public CalibAnalysis{ +public: + tdacScanAnalysis(): CalibAnalysis(){} + ~tdacScanAnalysis(){} + void analyze(TFile* file, TFile* anfile, RCE::PixScan* scan, int runno, ConfigGui* cfg[]); +}; + + +#endif diff --git a/rce/rcecalib/config/AbsFormatter.hh b/rce/rcecalib/config/AbsFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..a91dff03b15f6ead2bfb9ef84712543851c658dc --- /dev/null +++ b/rce/rcecalib/config/AbsFormatter.hh @@ -0,0 +1,22 @@ +#ifndef ABSFORMATTER_HH +#define ABSFORMATTER_HH + +#include <vector> +#include <string> +#include <boost/property_tree/ptree_fwd.hpp> + +class AbsFormatter{ +public: + AbsFormatter(int id, const char* name=""):m_rb(0), m_name(name), m_id(id){} + virtual ~AbsFormatter(){} + virtual int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A)=0; + virtual void configure(boost::property_tree::ptree* scanOptions){}; + virtual void setReadbackPointer(std::vector<unsigned>* p){m_rb=p;} + const char* getName(){return m_name.c_str();} + int getId(){return m_id;} +protected: + std::vector<unsigned> *m_rb; + std::string m_name; + int m_id; +}; +#endif diff --git a/rce/rcecalib/config/AbsModule.hh b/rce/rcecalib/config/AbsModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..cb0957a2bfc9efb0adf5471d811f4580bba5aedf --- /dev/null +++ b/rce/rcecalib/config/AbsModule.hh @@ -0,0 +1,40 @@ +#ifndef ABSMODULE_HH +#define ABSMODULE_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ModuleInfo.hh" +#include "rcecalib/config/AbsFormatter.hh" + + +class AbsModule{ +public: + AbsModule(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt) + :m_name(name), m_id(id), m_inLink(inLink), m_outLink(outLink), m_formatter(fmt){} + virtual ~AbsModule(){delete m_formatter;} + virtual void configureHW()=0; + virtual void setupMaskStageHW(int stage)=0; + virtual int setupParameterHW(const char* name, int val)=0; //HW setup + virtual int configureScan(boost::property_tree::ptree* scanOptions)=0; + virtual void resetFE()=0; + virtual void enableDataTakingHW()=0; + virtual int verifyModuleConfigHW(){return 0;} + unsigned getId(){return m_id;} + AbsFormatter* getFormatter(){return m_formatter;} + virtual ModuleInfo getModuleInfo()=0; + virtual const float dacToElectrons(int fe, int dac)=0; + unsigned getInLink(){return m_inLink;} + unsigned getOutLink(){return m_outLink;} + void setInLink(unsigned pos){m_inLink=pos;} + void setOutLink(unsigned pos){m_outLink=pos;} + std::string getName(){return m_name;} + virtual void destroy()=0; + +protected: + std::string m_name; + unsigned m_id; + unsigned m_inLink; + unsigned m_outLink; + AbsFormatter *m_formatter; +}; + +#endif diff --git a/rce/rcecalib/config/AbsModuleGroup.cc b/rce/rcecalib/config/AbsModuleGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..dab1c36c8c6df2fd4fe5f53858d8f1d1807b1c8b --- /dev/null +++ b/rce/rcecalib/config/AbsModuleGroup.cc @@ -0,0 +1,22 @@ +#include "rcecalib/config/AbsModuleGroup.hh" +#include "rcecalib/HW/SerialIF.hh" + +void AbsModuleGroup::setChannelInMask(){ + SerialIF::setChannelInMask(m_channelInMask); +} +void AbsModuleGroup::setChannelOutMask(){ + SerialIF::setChannelOutMask(m_channelOutMask); +} +void AbsModuleGroup::disableAllOutChannels(){ + SerialIF::setChannelOutMask(0); +} +void AbsModuleGroup::disableAllInChannels(){ + SerialIF::setChannelInMask(0); +} + +unsigned AbsModuleGroup::getChannelInMask(){ + return m_channelInMask; +} +unsigned AbsModuleGroup::getChannelOutMask(){ + return m_channelOutMask; +} diff --git a/rce/rcecalib/config/AbsModuleGroup.hh b/rce/rcecalib/config/AbsModuleGroup.hh new file mode 100644 index 0000000000000000000000000000000000000000..0c87a0ec98220c196de7ee41e39bb7da4b82eb83 --- /dev/null +++ b/rce/rcecalib/config/AbsModuleGroup.hh @@ -0,0 +1,32 @@ +#ifndef ABSMODULEGROUP_HH +#define ABSMODULEGROUP_HH +#include <boost/property_tree/ptree_fwd.hpp> +#include <vector> + +class AbsModuleGroup{ +public: + AbsModuleGroup(): m_channelInMask(0), m_channelOutMask(0){} + virtual ~AbsModuleGroup(){}; + void setChannelInMask(); + void setChannelOutMask(); + unsigned getChannelInMask(); + unsigned getChannelOutMask(); + void disableAllOutChannels(); + void disableAllInChannels(); + virtual void deleteModules()=0; + virtual int setupParameterHW(const char* name, int val, bool bcOK)=0; + virtual int setupMaskStageHW(int stage)=0; + virtual void configureModulesHW()=0; + virtual int verifyModuleConfigHW()=0; + virtual void resetErrorCountersHW()=0; + virtual int configureScan(boost::property_tree::ptree *scanOptions)=0; + virtual void resetFE()=0; + virtual void enableDataTakingHW()=0; + virtual unsigned getNmodules()=0; +protected: + unsigned m_channelInMask; + unsigned m_channelOutMask; + +}; + +#endif diff --git a/rce/rcecalib/config/AbsTrigger.cc b/rce/rcecalib/config/AbsTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..774c4f0970e28383199f9ae99cf78aaf4d91ec17 --- /dev/null +++ b/rce/rcecalib/config/AbsTrigger.cc @@ -0,0 +1,9 @@ +#include "rcecalib/config/AbsTrigger.hh" +#include <algorithm> + + +bool AbsTrigger::lookupParameter(const char* name){ + std::list<std::string>::iterator result = std::find(m_parameters.begin(), m_parameters.end(), name); + if( result==m_parameters.end())return false; + else return true; + } diff --git a/rce/rcecalib/config/AbsTrigger.hh b/rce/rcecalib/config/AbsTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..be15ff4c5327cab419beb518b0de885cb5b9e392 --- /dev/null +++ b/rce/rcecalib/config/AbsTrigger.hh @@ -0,0 +1,27 @@ +#ifndef ABSTRIGGER_HH +#define ABSTRIGGER_HH + +#include <list> +#include <boost/property_tree/ptree_fwd.hpp> + +class AbsTrigger{ +public: + AbsTrigger():m_i(0){}; + virtual ~AbsTrigger(){} + // configureScan and setupParameter can be overridden by daughter classes + virtual int configureScan(boost::property_tree::ptree* scanOptions){ + m_i=0; + return 0; + } + virtual int setupParameter(const char* name, int val){return 0;} + virtual int sendTrigger()=0; + virtual int getNTriggers(){return m_i;} + virtual int enableTrigger(bool on)=0; + virtual int resetCounters(){return 0;} + bool lookupParameter(const char* name); +protected: + int m_i; + std::list<std::string> m_parameters; +}; + +#endif diff --git a/rce/rcecalib/config/BFU.hh b/rce/rcecalib/config/BFU.hh new file mode 100644 index 0000000000000000000000000000000000000000..0ac17af05c674ec11c0e90d752e9a08b2b5dba2a --- /dev/null +++ b/rce/rcecalib/config/BFU.hh @@ -0,0 +1,157 @@ +#ifndef BFU_H +#define BFU_H + + +/* ---------------------------------------------------------------------- *//*! + + \file BFU.h + \brief Bit Field Unpack Routines + \author JJRussell - russell@slac.stanford.edu + + Inline functions to (left justified) unpack bit fields. + */ +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- *\ + * + * HISTORY + * ------- + * + * DATE WHO WHAT + * -------- --- --------------------------------------------------------- + * 08.25.09 jjr Pilfered from the LAT code, then made two modifications + * 1. Changed BFU from a structure to unsigned long long + * Turns out that any structure that is returned from + * a routine is returned via stack memory. This defeats + * the whole purpose of the bit-extraction routines + * which is to avoid memory like the plague. + * 2. Then, after looking at the generated code, made + * macro versions of BFU__wordL, BFU__wordR, BFU__boolean. + * While changing BFU as indicated in (1) did result + * in it being returned in registers, the generated + * code showed a lot of register thrashing. Once the + * move to a macro was made, the interface was no longer + * constrained to being able to modify just two 32-bit + * values (typically the cached bit field and the + * extracted value). To take advantage of this, the + * buffer address is now incremented when a new cache + * value is extracted. + * + * This made a factor of 2 difference in the MCC decoder. + * + * Future improvements + * 1. Started on a better implementation of the left + * justified extraction routines. Currently they + * just call the right justified extraction routines + * and appropriately shift the result. While this + * produces the correct answer, it has a performance + * cost. + * 2. Add probe routine for the booleans. Since the + * cache value always contains at least one valid + * bit, it can be probed without advancing the stream. + * Doing arbitrary field probes is also possible, + * but is much more difficult. + * 3. The most ambitious thing would be to build custom + * routines for the different platforms. In particular, + * a PPC-specific routine could be substantially faster, + * taking advantage of the rlinm instructions. + * + * 09.30.06 jjr Corrected _bfu_construct (it didn't used the newly + * calculated bit offset to extract the buffered word into + * cur). Added _bfu_constructW for constructing a BFU from + * an aligned source buffer. + * 09.30.06 jjr Added History log +\* ---------------------------------------------------------------------- */ +#ifdef __cplusplus +extern "C" { +#endif + + + + +#define _bfu_wordR(_val, _cur, _wrds, _position, _width) \ +{ \ + /* Compute where in the current word this field is to be extracted from */ \ + int rposition = (_position) & 0x1f; \ + int shift = 32 - (rposition + (_width)); \ + unsigned int msk = ((((unsigned int)0x1) << ((_width)-1)) << 1) - 1; \ + \ + if (shift > 0) _val = ((_cur) >> shift) & msk; \ + else if (shift == 0) \ + { \ + _val = (_cur) & msk; \ + _cur = *(++_wrds); \ + } \ + else \ + { \ + /* \ + | Crosses over to the next word \ + | In this case -shift is the number of bits in the next word \ + */ \ + shift = -shift; \ + _val = ((_cur) & (msk >> shift)) << shift; \ + _cur = *(++_wrds); \ + _val |= (_cur) >> (32 - shift); \ + } \ +} + + +#if 1 + +/* + | This is the original version of the extrating a left justified field. + | It calls the right justified field extrractor, then shifts the value + | into place. This is algorithmically correct, but costs in performance +*/ +#define _bfu_wordL(_val, _cur, _wrds, _position, _width) \ +{ \ + _bfu_wordR (_val, _cur, _wrds, _position, _width); \ + _val <<= 32 - (_width); \ +} + +#else + + +/* + | This is an experimental version of extracting a left justified field + | Basically it works, but because its interface differs slightly from + | the original version above (the difference is that the unused bits + | are not cleared, but actually carry the next 'n' bits of the data + | stream, which, in certain applications can be useful as a look-ahead + | operation) cannot be a drop-in replacement. + | + | It should be more efficient than the original version. +*/ +#define _bfu_wordL(_val, _cur, _wrds, _position, _width) \ +{ \ + /* Compute where in the current word this field is to be extracted from */ \ + int rposition = (_position) & 0x1f; \ + int end = (rposition + (_width)); \ + int left = 32 - end; \ + \ + _val = _cur << _position; \ + if (left <= 0) \ + { \ + _cur = *(++_wrds); \ + if (left < 0) \ + { \ + unsigned int s = 32 - (_position); \ + unsigned int x = _cur >> s; \ + _val &= (signed)0x80000000 >> (s-1); \ + _val |= x; \ + } \ + } \ +} + +#endif + +/* ---------------------------------------------------------------------- */ +#define _bfu_testBit(_cur, _position) (_cur << ((_position) & 0x1f)) +/* ---------------------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rce/rcecalib/config/ConfigIF.cc b/rce/rcecalib/config/ConfigIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..baa032a3f3366372364b5043cda55583dc3f2b16 --- /dev/null +++ b/rce/rcecalib/config/ConfigIF.cc @@ -0,0 +1,250 @@ +//Dummy interface for debugging + +#include "ConfigIF.hh" +#include <boost/property_tree/ptree.hpp> +#include <stdio.h> +#include "rcecalib/config/ModuleFactory.hh" +#include "rcecalib/config/AbsModule.hh" +#include "rcecalib/config/AbsModuleGroup.hh" +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/VerifyErrors.hh" +#include "ers/ers.h" +#include "ipc/object.h" +#include "rcecalib/HW/SerialIF.hh" + +ConfigIF::ConfigIF(ModuleFactory *mf):m_moduleFactory(mf),m_trigger(0), m_linkInMask(0), m_linkOutMask(0){ + m_modulegroups=mf->getModuleGroups(); +} + +int ConfigIF::setupParameter(const char* name, int val, bool enable){ + int retval=0; + assert(m_trigger!=0); + bool istrgpar=m_trigger->lookupParameter(name); + if(istrgpar==true){ + retval=m_trigger->setupParameter(name,val); + }else{ + disableAllChannels(); + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)retval+=m_modulegroups[i]->setupParameterHW(name,val, enable); + } + if(enable){ + enableDataTakingHW(); + setChannelMask(); + } + // m_trigger->resetCounters(); + } + return retval; +} + +int ConfigIF::setupMaskStage(int stage){ + disableAllChannels(); + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)m_modulegroups[i]->setupMaskStageHW(stage); + } + enableDataTakingHW(); + setChannelMask(); + // m_trigger->resetCounters(); + return 0; +} + +void ConfigIF::configureModulesHW(bool enable){ + //std::cout<<"Configure Modules HW"<<std::endl; + disableAllChannels(); + sendHWcommand(9); // reset Firmware + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)m_modulegroups[i]->configureModulesHW(); + } + if(enable==true){ + enableDataTakingHW(); + setChannelMask(); + if(m_trigger){ + //std::cout<<"Resetting counters"<<std::endl; + m_trigger->resetCounters(); + } + } +} + +int ConfigIF::verifyModuleConfigHW(int id){ + int retval=0; + int mod=-1; + for (size_t i=0; i<m_modules.size();i++){ + if(m_modules[i]->getModuleInfo().getId()==id){ + mod=i; + break; + } + } + if(mod<0)return ModuleVerify::NO_MODULE; + SerialIF::setChannelInMask(m_modules[mod]->getInLink()); + SerialIF::setChannelOutMask(m_modules[mod]->getOutLink()); + retval=m_modules[mod]->verifyModuleConfigHW(); + disableAllChannels(); + return retval; +} + +unsigned ConfigIF::getNmodules(){ + return m_modules.size(); +} + +int ConfigIF::sendTrigger(){ + m_trigger->sendTrigger(); + return 0; +} + +int ConfigIF::setChannelMask(){ + SerialIF::setChannelInMask(m_linkInMask); + SerialIF::setChannelOutMask(m_linkOutMask); + //std::cout<<"Link In Mask "<<std::hex<<m_linkInMask<<std::dec<<std::endl; + //std::cout<<"Link Out Mask "<<std::hex<<m_linkOutMask<<std::dec<<std::endl; + return 0; +} + +void ConfigIF::disableAllChannels(){ + SerialIF::setChannelInMask(0); + SerialIF::setChannelOutMask(0); +} +unsigned ConfigIF::sendHWcommand(unsigned char opcode){ + return SerialIF::sendCommand(opcode); +} +unsigned ConfigIF::writeHWregister(unsigned addr, unsigned val){ + return SerialIF::writeRegister(addr,val); +} +unsigned ConfigIF::readHWregister(unsigned addr, unsigned &val){ + return SerialIF::readRegister(addr, val); +} +unsigned ConfigIF::writeHWblockData(std::vector<unsigned>& data){ + return SerialIF::writeBlockData(data); +} +unsigned ConfigIF::readHWblockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec){ + return SerialIF::readBlockData(data, retvec); +} +unsigned ConfigIF::readHWbuffers(std::vector<unsigned char>& retvec){ + return SerialIF::readBuffers(retvec); +} +void ConfigIF::resetCountersHW(){ + m_trigger->resetCounters(); +} + +int ConfigIF::enableTrigger(){ + return m_trigger->enableTrigger(1); +} +int ConfigIF::disableTrigger(){ + return m_trigger->enableTrigger(0); +} +void ConfigIF::resetFE(){ + disableAllChannels(); + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)m_modulegroups[i]->resetFE(); + } + if(m_trigger)disableTrigger(); +} +void ConfigIF::resetErrorCountersHW(){ + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)m_modulegroups[i]->resetErrorCountersHW(); + } +} +void ConfigIF::enableDataTakingHW(){ + //std::cout<<"ConfigIF enabled data taking"<<std::endl; + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)m_modulegroups[i]->enableDataTakingHW(); + } +} + +int ConfigIF::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + if(m_trigger!=0)retval=m_trigger->configureScan(scanOptions); + for (unsigned int i=0;i<m_modulegroups.size();i++){ + if(m_modulegroups[i]->getNmodules()!=0)retval+=m_modulegroups[i]->configureScan(scanOptions); + } + return retval; +} + +int ConfigIF::setupModule(const char* name, const char* type, unsigned id, unsigned inLink, unsigned outLink, const char* formatter){ + int retval=0; + char err_msg[128]; + try{ + //name, id, link are unique. Check that they don't exist already. + for (unsigned int i=0;i<m_modules.size();i++){ + if(m_modules[i]->getId()==id ){ + std::cout<<"setupModule error: Duplicate id "<<id<<std::endl; + sprintf(err_msg,"id = %d",id); + rcecalib::Param_exists issue(ERS_HERE,err_msg); + throw issue; + } + if(m_modules[i]->getName()==name ){ + std::cout<<"setupModule error: Duplicate name "<<name<<std::endl; + sprintf(err_msg,"name = %s",name); + rcecalib::Param_exists issue(ERS_HERE,err_msg); + throw issue; + } + if( m_modules[i]->getOutLink()==outLink){ + std::cout<<"setupModule error: Duplicate outlink "<<outLink<<std::endl; + sprintf(err_msg,"link = %d",outLink); + rcecalib::Param_exists issue(ERS_HERE,err_msg); + throw issue; + } + } + //std::cout<<name<<" "<<type<<" "<<id<<" "<<link<<std::endl; + AbsModule *newmod=m_moduleFactory->createModule(name, type,id, inLink, outLink, formatter); + //std::cout<<"setupModule after create "<<newmod<<std::endl; + //success + if(std::string(type)!="IPC_Hitbus_multiThread"){ + m_modules.push_back(newmod); + m_linkInMask|=1<<newmod->getInLink(); + } + m_linkOutMask|=1<<newmod->getOutLink(); + } + catch(rcecalib::Param_exists ex){ + ers::error(ex); + retval=1; + } + catch(rcecalib::Unknown_Module_Type ex){ + ers::error(ex); + retval=1; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch(std::bad_alloc &ex){ + std::cerr<<"Bad alloc "<<ex.what()<<std::endl; + } + catch(...){ + std::cerr<<"Unknown error "<<std::endl; + } + return retval; +} + +int ConfigIF::setupTriggerIF(const char* type){ + delete m_trigger; + m_trigger=m_moduleFactory->createTriggerIF(type, this); + return 0; +} + +void ConfigIF::deleteModules(){ + for (unsigned i=0; i<m_modulegroups.size();i++){ + //cannot call delete directly because IPC modules need to call _destroy() instead. + m_modulegroups[i]->deleteModules(); + } + m_modules.clear(); + m_linkInMask=0; + m_linkOutMask=0; +} + +int ConfigIF::nTrigger(){ + return m_trigger!=0? m_trigger->getNTriggers(): -1; +} + +ModuleInfo ConfigIF::getModuleInfo(int mod){ + ERS_ASSERT(mod<(int)m_modules.size()); + return m_modules[mod]->getModuleInfo(); +} +const float ConfigIF::dacToElectrons(int mod, int fe, int dac){ + if(mod>=(int)m_modules.size())return -1; + return m_modules[mod]->dacToElectrons(fe,dac); +} diff --git a/rce/rcecalib/config/ConfigIF.hh b/rce/rcecalib/config/ConfigIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..414af2193fe600cc7d8ab186d9f167685c5b0733 --- /dev/null +++ b/rce/rcecalib/config/ConfigIF.hh @@ -0,0 +1,53 @@ +#ifndef CONFIGIF_HH +#define CONFIGIF_HH +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ModuleInfo.hh" +#include <vector> + +class ModuleFactory; +class AbsModule; +class AbsModuleGroup; +class AbsTrigger; + +class ConfigIF{ +public: + ConfigIF(ModuleFactory*); + virtual ~ConfigIF(){} + int setupParameter(const char* name, int val, bool enable=true); + int setupMaskStage(int stage); + int sendTrigger(); + int setChannelMask(); + void disableAllChannels(); + void configureModulesHW(bool enable=true); + int verifyModuleConfigHW(int id); + int enableTrigger(); + int disableTrigger(); + unsigned sendHWcommand(unsigned char opcode); + unsigned writeHWregister(unsigned addr, unsigned val); + unsigned readHWregister(unsigned addr, unsigned &val); + unsigned writeHWblockData(std::vector<unsigned>& data); + unsigned readHWblockData(std::vector<unsigned>& data, std::vector<unsigned>& retvec); + unsigned readHWbuffers(std::vector<unsigned char>& retvec); + void resetCountersHW(); + void resetErrorCountersHW(); + int nTrigger(); + int configureScan(boost::property_tree::ptree *scanOptions); + unsigned getNmodules(); + ModuleInfo getModuleInfo(int mod); + const float dacToElectrons(int mod, int fe, int dac); + void deleteModules(); + void resetFE(); + void enableDataTakingHW(); + int setupTriggerIF(const char* type); + int setupModule(const char* name, const char* type, unsigned id, unsigned inLink, unsigned outLink, const char* formatter); +private: + std::vector<AbsModule*> m_modules; + std::vector<AbsModuleGroup*> m_modulegroups; + ModuleFactory* m_moduleFactory; + AbsTrigger* m_trigger; + unsigned m_linkInMask; + unsigned m_linkOutMask; + +}; + +#endif diff --git a/rce/rcecalib/config/DummyFormatter.cc b/rce/rcecalib/config/DummyFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..0d743fd9d56326ab3f48155d917402c1d6ce7b8e --- /dev/null +++ b/rce/rcecalib/config/DummyFormatter.cc @@ -0,0 +1,20 @@ +#include "rcecalib/config/DummyFormatter.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> + +DummyFormatter::DummyFormatter(int id): + AbsFormatter(id){ +} +DummyFormatter::~DummyFormatter(){ +} +void DummyFormatter::configure(boost::property_tree::ptree* config){ +} + +int DummyFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + std::cout<<"Dummy formatter called!"<<std::endl; + return 0; +} + diff --git a/rce/rcecalib/config/DummyFormatter.hh b/rce/rcecalib/config/DummyFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..2febd19f074cd98601c89be344dde2295bf003c6 --- /dev/null +++ b/rce/rcecalib/config/DummyFormatter.hh @@ -0,0 +1,13 @@ +#ifndef DUMMYFORMATTER_HH +#define DUMMYFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" + +class DummyFormatter:public AbsFormatter{ +public: + DummyFormatter(int id); + virtual ~DummyFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); +}; +#endif diff --git a/rce/rcecalib/config/Endianness.hh b/rce/rcecalib/config/Endianness.hh new file mode 100644 index 0000000000000000000000000000000000000000..8156d423cf9d1800a9d43dd3483cd274e322f37e --- /dev/null +++ b/rce/rcecalib/config/Endianness.hh @@ -0,0 +1,270 @@ +#ifndef ENDIANNESS_H +#define ENDIANNESS_H + + + +/* ---------------------------------------------------------------------- *//*! + + \file Endianness.h + \brief Provides definitions of the ENDIANNESS of the target machine. The + symbols \a ENDIANNESS_IS_LITTLE and \a ENDIANNESS_IS_BIG should be + used in preprocessing directives to determine the endianness of + the machine, while the symbol \a ENDIANNESS can be more easily + used in 'C' code. + \author JJRussell - russell@slac.stanford.edu + +\verbatim + + CVS $Id: Endianness.hh,v 1.2 2010/10/15 11:34:31 wittgen Exp $ +\endverbatim + + \par SYNOPSIS + One of two symbols are defined + - \a ENDIANNESS_IS_LITTLE + - \a ENDIANNESS_IS_BIG. + + \par + As a convenience to the programmer, an overall symbol, \a ENDIANNESS + is also defined. It will take on one of the three values. + + - ENDIANNESS_K_UNKNOWN + - ENDIANNESS_K_LITTLE + - ENDIANNESS_K_BIG + + \par USAGE + One should use this as follows \par + + \code + #if ENDIANNESS_IS_LITTLE + + / * Do little endian kind of things * / + + #elif ENDIANNESS_IS_BIG + + / * Do big endian kind of things * / + + #else + + #error _FILE_ Endianness not determined in this file + + #endif + \endcode + + \par + It is recommended that both BIG and LITTLE conditions are tested for. + This can save one from embarrassing typographical errors. For example, + consider the consequences of the following \par + + \code + + #if ENDIANESS_IS_LITTLE + + / * Do little endian kind of things * / + + #else + + / * Do big endian kind of things * / + + #endif + + \endcode + + \par + It takes a keen eye to note the misspelling of \a ENDIANNESS_IS_LITTLE + as \a ENDIANESS_IS_LITTLE. Since there is no such symbol as + \a ENDIANESS_IS_LITTLE, the 'big' endian kind of things will always be + done. + + \par + It is also recommended that one use \e \#if preprocessor directive over + the \#ifdef form. Either works with the current implementation, but + future implementations reserves the right to support only the \#if + form. + + \par TARGET PLATFORMS + All FSW supported platforms. + */ +/* --------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- *\ + * + * HISTORY WHO WHAT + * ------- --- ------------------------------------------------------- + * 09.28.05 jjr Corrected documentation formating for Doxygen 1.4.4 + * 09.28.05 jjr Added history log + * +\* ---------------------------------------------------------------------- */ + + + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS_IS_LITTLE + \brief Defined and set to a non-zero value, \a ENDIANNESS_K_LITTLE, if + the target is a little endian machine. + */ +/* --------------------------------------------------------------------- */ + + + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS_IS_BIG + \brief Defined and set to a non-zero value, \a ENDIANNESS_BIG, if + the target is a big endian machine. + */ +/* --------------------------------------------------------------------- */ + + + + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS_K_UNKNOWN + \brief Value of ENDIANNESS the endianness of the target is undefined. + */ +/* --------------------------------------------------------------------- */ +#define ENDIANNESS_K_UNKNOWN 0 +/* --------------------------------------------------------------------- */ + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS_K_LITTLE + \brief Value of ENDIANNESS if the target is a little endian machine. + */ +/* --------------------------------------------------------------------- */ +#define ENDIANNESS_K_LITTLE 1 +/* --------------------------------------------------------------------- */ + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS_K_BIG + \brief Value of ENDIANNESS if the target is a big endian machine + machine. + */ +/* --------------------------------------------------------------------- */ +#define ENDIANNESS_K_BIG 2 +/* --------------------------------------------------------------------- */ + + + + +/* --------------------------------------------------------------------- *//*! + + \def ENDIANNESS + \brief \a ENDINANESS assumes one of the values, + \li \a ENDIANNESS_K_LITTLE + \li \a ENDIANNESS_K_BIG + \li \a ENDIANNESS_K_UNKNOWN. + + + \note + Since DOXYGEN does not have access to the full set of compile time + preprocessor symbols, \a ENDIANNESS will appear to be defined as + \a ENDIANNESS_K_UNKNOWN. + + \warning + It is not recommended that this symbol be used in preprocessor + directives to determine the endianness of the machine. Use + \a ENDIANNESS_IS_LITTLE or \a ENDIANNESS_IS_BIG. Why? To do this + correctly one must use the following long-winded style: \par + + \code + if defined (ENDIANNESS) && (ENDIANNESS == ENDIANNESS_K_LITTLE) + { + . + . + } + elif defined (ENDIANNESS) && (ENDIANNESS == ENDIANNESS_K_BIG) + { + . + . + } + else + { + . + / * Endianness unknown * / + } + \endcode + + \par + The check for \a ENDIANNESS being defined is mandatory for robustness. + If the user forgets to include "PBI/Endiannness.h", all the \e ENDIANNESS + symbols are, in fact, undefined. Without the check that \a ENDIANNESS + is defined, the simple check of (\a ENDIANNESS == \a ENDIANNESS_K_LITTLE) + will \b always succeed, causing the big endian if clause to always be + taken. If the code is developed on a big endian machine, it is only + when the code is ported to a little endian machine will the problem + show up as malfunctioning code which the poor developer will eventually + trace to the ill-constructed endianness determination. + */ +/* --------------------------------------------------------------------- */ + +#if defined(__LITTLE_ENDIAN__) && (__BIG_ENDIAN__) + + # define ENDIANNESS_IS_LITTLE ENDIANNESS_K_UNKNOWN + # define ENDIANNESS_IS_BIG ENDIANNESS_K_UNKNOWN + + # undef ENDIANNESS_IS_LITTLE + # undef ENDIANNESS_IS_BIG + + #error "Endianness.h:found both __BIG_ENDIAN__ and __LITTLE_ENDIAN defined" + +#else +/* MW fix for gcc version > 4.1 */ +#if defined(__i386) || defined(i386) || defined(__IEEE_LITTLE_ENDIAN) || (__LITTLE_ENDIAN_) + + + # define ENDIANNESS_IS_LITTLE ENDIANNESS_K_LITTLE + # define ENDIANNESS ENDIANNESS_K_LITTLE +// #warning "Little endian" + + + #elif defined(__sparc) || defined(__IEEE_BIG_ENDIAN) || (__BIG_ENDIAN__) + + # define ENDIANNESS_IS_BIG ENDIANNESS_K_BIG + # define ENDIANNESS ENDIANNESS_K_BIG +// #warning "Big endian" + + #else + + # define ENDIANNESS ENDIANNESS_K_UNKNOWN + + /* + | From a programming standpoint this not necessary, but since + | DOXYGEN does not have access to the full set of compile time + | preprocessor symbols, the first two clauses will not define + | ENDIANNESS_IS_LITTLE or ENDIAN_IS_BIG, causing DOXYGEN to complain + | about documented, but undefined symbols. In effect, these two + | statements are just to keep DOXYGEN from spitting out compliants. + */ + # define ENDIANNESS_IS_LITTLE ENDIANNESS_K_UNKNOWN + # define ENDIANNESS_IS_BIG ENDIANNESS_K_UNKNOWN + + # undef ENDIANNESS_IS_LITTLE + # undef ENDIANNESS_IS_BIG + + # error "Endianness.h: Cannot determine the endianness of the machine" + + #endif +#endif +/* --------------------------------------------------------------------- */ + + +#endif + + + + + + + + + + diff --git a/rce/rcecalib/config/EventFromDspTrigger.cc b/rce/rcecalib/config/EventFromDspTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..d6326ac246d90eb256f1c61c9c1e47d0bdbe68c1 --- /dev/null +++ b/rce/rcecalib/config/EventFromDspTrigger.cc @@ -0,0 +1,93 @@ +#include "rcecalib/config/EventFromDspTrigger.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/config/TriggerReceiverIF.hh" +#include "rcecalib/legacy/dsp_types.h" +#include "rcecalib/legacy/sysParams_specific.h" +#include "rcecalib/legacy/histogram.h" +#include "rcecalib/legacy/histogramCtrl.h" + +#include <iostream> + + + + +EventFromDspTrigger::EventFromDspTrigger():AbsTrigger(){ + m_inpf.open("/reg/lab1/home/wittgen/data/___slave_dump___",std::ios::binary); + unsigned int file_header[3]; + if(m_inpf.is_open()) { + m_inpf.read((char*)&file_header,sizeof(file_header)); + unsigned int nFrames=file_header[1]; + unsigned int nWords=file_header[2]; + std::cout << nFrames << " " << nWords <<std::endl; + HistogramOptions histogramOptions; + m_inpf.read((char*)&histogramOptions,sizeof(HistogramOptions)); + std::cout<<"nTriggers= "<<histogramOptions.nTriggers<<std::endl; + std::cout<<"nFrames= "<<nFrames<<std::endl; + std::cout<<"nTriggers= "<<histogramOptions.nTriggers<<std::endl; + std::cout<<"nBins= "<<histogramOptions.nBins[0]<<std::endl; + std::cout<<"nModules= "<<histogramOptions.nModules<<std::endl; + histogramOptions.nMaskStages--; + std::cout<<"nMaskStages= "<<histogramOptions.nMaskStages<<std::endl; + + std::cout<<"maskStageBegin= "<<histogramOptions.maskStageBegin<<std::endl; + std::cout<<"type= "<<histogramOptions.type<<std::endl; + std::cout<<"maskStageTotalSteps= "<<histogramOptions.maskStageTotalSteps<<std::endl; + + + + m_nBins=histogramOptions.nBins[0]; + m_nStages=histogramOptions.nMaskStages; + } + m_inpf.read((char *) &m_frame_header,sizeof(m_frame_header)); + m_bin=m_frame_header[2]; + m_stage=m_frame_header[3]; + m_frameSize=m_frame_header[1]; + m_inpf.read((char*) &m_frame,m_frameSize*sizeof(unsigned int)); + m_inpf.read((char*) &m_frame_trailer,sizeof(m_frame_trailer)); + +} + + +int EventFromDspTrigger::sendTrigger(){ + // static int count=0; + static int eof=0; + static int bof=0; + static int hits=0; + static int skipframe=0; + static int newEvent=0; + + + + newEvent=0;hits=0; + do { + if(!skipframe) { + if(m_frame[255]==0xe0f00000) skipframe=1; + for(int i=0;i<m_frameSize;i++) { + if((m_frame[i]&0xffff0000)==0xb0f00000) {bof++;} + if((m_frame[i]>>28)==0x8) { + m_event[hits]=m_frame[i]; + hits++; + } + if((m_frame[i]&0xffff0000)==0xe0f00000) {eof++;newEvent=1;break;} + } + } else skipframe=0; + + m_inpf.read((char *) &m_frame_header,sizeof(m_frame_header)); + m_bin=m_frame_header[2]; + m_stage=m_frame_header[3]; + m_frameSize=m_frame_header[1]; + m_inpf.read((char*) &m_frame,m_frameSize*sizeof(unsigned int)); + m_inpf.read((char*) &m_frame_trailer,sizeof(m_frame_trailer)); + + } while(!m_inpf.eof() && m_bin<m_nBins && m_stage<m_nStages && !newEvent); + // std::cout << "send Trigger "<< count++ << std::endl; + TriggerReceiverIF::receive(&m_event[0],hits); + m_i++; + // if(m_i%100==0) std::cout << "trigger " << m_i<<std::endl; + + return 0; +} + + + diff --git a/rce/rcecalib/config/EventFromDspTrigger.hh b/rce/rcecalib/config/EventFromDspTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..b3a76145eee40b4b5a662a83417f18456fbf1418 --- /dev/null +++ b/rce/rcecalib/config/EventFromDspTrigger.hh @@ -0,0 +1,28 @@ +#ifndef EVENTFROMDSPRIGGER_HH +#define EVENTFROMDSPTRIGGER_HH +#include <fstream> +#include "rcecalib/config/AbsTrigger.hh" +#include <vector> + + + class EventFromDspTrigger: public AbsTrigger{ + public: + EventFromDspTrigger(); + ~EventFromDspTrigger(){if(m_inpf.is_open()) m_inpf.close();}; + int sendTrigger(); + int enableTrigger(bool on){return 0;} + private: + unsigned m_event[2048]; + std::ifstream m_inpf; + int m_bin; + int m_stage; + int m_nBins; + int m_nStages; + int m_frameSize; + unsigned int m_frame_header[4]; + unsigned int m_frame_trailer; + unsigned int m_frame[256]; + }; + + +#endif diff --git a/rce/rcecalib/config/EventFromFileTrigger.cc b/rce/rcecalib/config/EventFromFileTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..57631f747113e8362f44da199b7016a03bbcecd3 --- /dev/null +++ b/rce/rcecalib/config/EventFromFileTrigger.cc @@ -0,0 +1,29 @@ + +#include "rcecalib/config/EventFromFileTrigger.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/config/TriggerReceiverIF.hh" +#include <iostream> +#include <fstream> + + + +EventFromFileTrigger::EventFromFileTrigger():AbsTrigger(){ + //std::cout<<"eventfromfiletrigger"<<std::endl; + std::ifstream flog("/nfs/event1.txt"); + while(!flog.eof()){ + unsigned word; + flog>>std::hex>>word; + m_event.push_back((word<<16)|(word>>16)); + } + m_event.push_back(0); + } + + + int EventFromFileTrigger::sendTrigger(){ + TriggerReceiverIF::receive(&m_event[0],m_event.size()); + m_i++; + return 0; + } + + diff --git a/rce/rcecalib/config/EventFromFileTrigger.hh b/rce/rcecalib/config/EventFromFileTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..0a4419c1ddb5b62c415847d79e27c2c50a9d1c0b --- /dev/null +++ b/rce/rcecalib/config/EventFromFileTrigger.hh @@ -0,0 +1,19 @@ +#ifndef EVENTFROMFILETRIGGER_HH +#define EVENTFROMFILETRIGGER_HH + +#include "rcecalib/config/AbsTrigger.hh" +#include <vector> + + + class EventFromFileTrigger: public AbsTrigger{ + public: + EventFromFileTrigger(); + ~EventFromFileTrigger(){}; + int sendTrigger(); + int enableTrigger(bool on){return 0;} + private: + std::vector<unsigned> m_event; + }; + + +#endif diff --git a/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.cc b/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..1538c87d404e906bbb15e21e4fd246e95400feba --- /dev/null +++ b/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.cc @@ -0,0 +1,42 @@ +#include "rcecalib/config/FEI3/CrosstalkMaskStaging.hh" +#include "rcecalib/config/FEI3/Module.hh" + +namespace FEI3{ + + CrosstalkMaskStaging::CrosstalkMaskStaging(FEI3::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI3::Module>(mod, masks, type){ + m_nStages=2880; + } + + void CrosstalkMaskStaging::setupMaskStageHW(int maskStage){ + if(maskStage % Frontend::N_ROWS < 2 || maskStage % Frontend::N_ROWS == 159){ + clearBitsHW(); + for (int i=0;i<Module::N_FRONTENDS;i++){ + int nPixelsPerChip = Frontend::N_ROWS * Frontend::N_COLS; + for(int index=maskStage;index<nPixelsPerChip;index+=m_nStages){ + int row = (int) index % Frontend::N_ROWS; + int col = (int) index / Frontend::N_ROWS; + if( col%2 ) row = 159 - row; + PixelRegister *pixel=m_module->frontend(i)->getPixelRegister(col,row); + pixel->set(pixel->get() | m_masks.xtalk_on); + if(row<159){ + PixelRegister *pixelm=m_module->frontend(i)->getPixelRegister(col,row+1); + pixelm->set(pixelm->get() | m_masks.xtalk_off); + } + if(row>0){ + PixelRegister *pixell=m_module->frontend(i)->getPixelRegister(col,row-1); + pixell->set(pixell->get() | m_masks.xtalk_off); + } + } + } + m_module->configureHW(); + }else{ + m_module->resetHW(false); // only reset MCC, not FE + m_module->mcc()->configureHW(); + //std::cout<<"Shifting enables"<<std::endl; + for (int i=0;i<Module::N_FRONTENDS;i++){ + m_module->frontend(i)->shiftEnablesHW(m_masks.iMask); + } + } + } +} diff --git a/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.hh b/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..10091ca40fb3e00f5b34746781c010fb4a8b7cb0 --- /dev/null +++ b/rce/rcecalib/config/FEI3/CrosstalkMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef FEI3CROSSTALKMASKSTAGING_HH +#define FEI3CROSSTALKMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI3{ + class Module; + + class CrosstalkMaskStaging: public MaskStaging<FEI3::Module>{ + public: + CrosstalkMaskStaging(FEI3::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI3/FECommands.cc b/rce/rcecalib/config/FEI3/FECommands.cc new file mode 100644 index 0000000000000000000000000000000000000000..42d55c43ec4baa94498da0166d0d16fd9badb8df --- /dev/null +++ b/rce/rcecalib/config/FEI3/FECommands.cc @@ -0,0 +1,63 @@ + +#include "rcecalib/config/FEI3/FECommands.hh" + +namespace FEI3{ + + void FECommands::mccWriteRegister(BitStream *bs, Mcc::Register reg, unsigned value){ + bs->push_back(0x1); /* header (10110) + field2 (1011) + field3 (0000) */ + bs->push_back(0x6B000000 | (reg << 16) | (value & 0xffff)); /* field4 = (address(3:0)) + data(15:0) */ + bs->push_back(0); // padding a la NewDsp + } + void FECommands::resetMCC(BitStream *bs){ + bs->push_back(0x16B900); + bs->push_back(0); // padding a la NewDsp + } + void FECommands::resetFE(BitStream *bs, unsigned width) { + bs->push_back(0x16BA00 | (width & 0xf)); + bs->push_back(0); + } + void FECommands::enableDataTaking(BitStream *bs) { + bs->push_back(0); + bs->push_back(0x0016B800); + bs->push_back(0); + } + void FECommands::L1A(BitStream *bs){ + bs->push_back(0xE8000000); + } + void FECommands::sendECR(BitStream *bs){ + bs->push_back(0); + bs->push_back(0x00162000); /* MCC ECR command */ + bs->push_back(0); + } + void FECommands::sendBCR(BitStream *bs){ + bs->push_back(0); + bs->push_back(0x00161000); /* MCC BCR command */ + bs->push_back(0); + } + void FECommands::feWriteCommand(BitStream *bs, unsigned chip, int cmd, bool rw){ + if(rw){ + bs->push_back(0x16B50); + }else{ + bs->push_back(0x16B40); // write only + } + unsigned mask = 0x00800000; + unsigned command=cmd; + unsigned parity = 0; + for(int k=1;k<24;++k,mask>>=1) { + if(mask & command) parity ^= 1; + } + command |= parity; + command <<= 5; /* for geographical address */ + command |= chip; + for(int k=7;k>-1;--k) { + unsigned word=0; + for (int i=3;i>=0;i--){ + word<<=8; + if((command>>(k*4+i))&0x1)word|=0xff; + } + bs->push_back(word); + } + } + + +}; diff --git a/rce/rcecalib/config/FEI3/FECommands.hh b/rce/rcecalib/config/FEI3/FECommands.hh new file mode 100644 index 0000000000000000000000000000000000000000..c64e0da154262305b9bb838eeb0c5067fa4c1234 --- /dev/null +++ b/rce/rcecalib/config/FEI3/FECommands.hh @@ -0,0 +1,46 @@ +#ifndef FECOMMANDS_FEI3_HH +#define FECOMMANDS_FEI3_HH + +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI3/Mcc.hh" + +namespace FEI3{ + + class FECommands{ + public: + enum Command{ + FE_CMD_NULL=0x000000, + FE_CMD_REF_RESET=0x000002, + FE_CMD_SOFT_RESET=0x00000C , + FE_CMD_CLOCK_GLOBAL=0x000010, + FE_CMD_WRITE_GLOBAL=0x000060, + FE_CMD_READ_GLOBAL=0x000080, + FE_CMD_CLOCK_PIXEL=0x000100, + FE_CMD_WRITE_HITBUS=0x000200, + FE_CMD_WRITE_SELECT=0x000400, + FE_CMD_WRITE_MASK=0x000800, + FE_CMD_WRITE_TDAC0=0x001000, + FE_CMD_WRITE_TDAC1=0x002000, + FE_CMD_WRITE_TDAC2=0x004000, + FE_CMD_WRITE_TDAC3=0x008000, + FE_CMD_WRITE_TDAC4=0x010000, + FE_CMD_WRITE_TDAC5=0x020000, + FE_CMD_WRITE_TDAC6=0x040000, + FE_CMD_WRITE_FDAC0=0x080000, + FE_CMD_WRITE_FDAC1=0x100000, + FE_CMD_WRITE_FDAC2=0x200000, + FE_CMD_WRITE_KILL=0x400000, + FE_CMD_READ_PIXEL=0x800000}; + static void mccWriteRegister(BitStream* bs, Mcc::Register reg, unsigned value); + static void resetMCC(BitStream *bs); + static void resetFE(BitStream* bs, unsigned width); + static void enableDataTaking(BitStream *bs); + static void L1A(BitStream *bs); + static void sendECR(BitStream *bs); + static void sendBCR(BitStream *bs); + static void feWriteCommand(BitStream* bs, unsigned chip, int cmd, bool rw=0); + }; + +}; +#endif + diff --git a/rce/rcecalib/config/FEI3/Frontend.cc b/rce/rcecalib/config/FEI3/Frontend.cc new file mode 100644 index 0000000000000000000000000000000000000000..ffc32a9e26a1e3369e85532af51d5b9d4cb6f486 --- /dev/null +++ b/rce/rcecalib/config/FEI3/Frontend.cc @@ -0,0 +1,204 @@ + +#include "rcecalib/config/FEI3/Frontend.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <iostream> + +namespace FEI3{ + + Frontend::Frontend(unsigned chip):m_chip(chip){ + m_global=new GlobalRegister(chip, chip); + } + Frontend::~Frontend(){ + delete m_global; + } + void Frontend::setChipAddress(unsigned i, unsigned addr){ + if(i<16 && addr<16){ + if(m_chip!=addr){ // cannot use the cached global register + delete m_global; + m_global=new GlobalRegister(i, addr); + std::cout<<"Creating new GlobalRegister position "<<i<<" address "<<addr<<std::endl; + } + m_chip=addr; + } + } + + void Frontend::writeGlobalRegisterHW(){ + //std::cout<<"write global register chip "<<m_chip<<std::endl; + m_global->writeHW(); + } + void Frontend::setGlobalRegField(const char* name, int val){ + m_global->setField(name,val); + } + + void Frontend::setPixelParameter(PixelRegister::Field field, int val){ + for(int j=0;j<N_COLS;j++){ + for (int i=0;i<N_ROWS;i++){ + m_pixel[j][i].setField(field, val); + } + } + for(unsigned int i=fieldPos[field]; i<fieldPos[field+1];i++){ + writePixelRegisterHW(i); + } + } + + void Frontend::writePixelRegisterHW(unsigned bit){ + //std::cout<<"write pixel register "<<bit<<" in chip "<<m_chip<<std::endl; + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + unsigned nPixelsPerChip = Frontend::N_COLS * Frontend::N_ROWS; + unsigned dcnt = nPixelsPerChip; /* all column pairs */ + unsigned cnt = (dcnt << 3) | 4; + FECommands::mccWriteRegister(bs, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bs,m_chip, FECommands::FE_CMD_CLOCK_PIXEL); + pixelUsrToRaw(bs, bit); + bs->push_back(0);// one clean word afterwards + cnt = 4; + FECommands::mccWriteRegister(bs, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bs, m_chip, FECommands::FE_CMD_WRITE_HITBUS << bit); + bs->push_back(0); + FECommands::feWriteCommand(bs, m_chip, FECommands::FE_CMD_NULL); + bs->push_back(0); + SerialIF::send(bs); + delete bs; +} + + void Frontend::pixelUsrToRaw(BitStream *bs, unsigned bit){ + int col; + unsigned row; + unsigned short *pixelReg, mask; + mask = (1 << bit); + col = 0; + /* form the snake pattern */ + col = Frontend::N_COLS - 1; /* the last column */ + while(col > 0) { /* works because we are decrementing by 2 each loop. otherwise, > -1 */ + pixelReg = (unsigned short*)&m_pixel[col][0]; + --col; + for(row=0;row<Frontend::N_ROWS/sizeof(unsigned);++row){ + unsigned word=0; + for(int i=0;i<4;i++){ + word<<=8; + word|= (*pixelReg++ & mask) ? 0xff : 0x00; /* upwards */ + } + bs->push_back(word); + } + pixelReg = (unsigned short*)&m_pixel[col][Frontend::N_ROWS-1]; + --col; + for(row=0;row<Frontend::N_ROWS/sizeof(unsigned);++row){ + unsigned word=0; + for(int i=0;i<4;i++){ + word<<=8; + word |= (*pixelReg-- & mask) ? 0xff : 0x00; /* backwards */ + } + bs->push_back(word); + } + } + } + void Frontend::setVcalCoeff(unsigned i, float val){ + if(i<4)m_vcalCoeff[i]=val; + } + void Frontend::setCapVal(unsigned i, float val){ + if(i<2)m_capVal[i]=val; + } + float Frontend::getVcalCoeff(unsigned i){ + if(i<4)return m_vcalCoeff[i]; + else return -999; + } + float Frontend::getCapVal(unsigned i){ + if(i<2)return m_capVal[i]; + else return -999; + } + + // TODO: get rid of float + const float Frontend::dacToElectrons(int dac){ + bool isChigh=m_global->getField("enableCinjHigh"); + float capacity = 6.241495961*(isChigh ? m_capVal[1] : m_capVal[0]); + float fldac=(float)dac; + return capacity*(m_vcalCoeff[0] + (m_vcalCoeff[1] + (m_vcalCoeff[2] + m_vcalCoeff[3]*fldac)*fldac)*fldac); + } + + const int Frontend::electronsToDac(float ne) { + float min=10000.; + int mini=-1; + for(int i=0;i<1024;i++) { + float diff=(ne-dacToElectrons(i)); + if(diff<0.) diff=-diff; + if(diff<min) { + min=diff;mini=i; + } + } + return mini; + } + + + PixelRegister* Frontend::getPixelRegister(unsigned col, unsigned row){ + return &m_pixel[col][row]; + } + + void Frontend::configureHW(){ + m_global->enableAll(); + //std::cout<<"write global register chip "<<m_chip<<std::endl; + m_global->writeHW(); + for (int i=0;i<N_PIXEL_REGISTER_BITS;i++){ + writePixelRegisterHW(i); + } + } + + void Frontend::shiftEnablesHW(unsigned short bitmask){ + m_global->enableAll(); + //global bitstream is cached + m_global->setField("doMux",11); + BitStream* bitStream=new BitStream; + for (int bit=0;bit<N_PIXEL_REGISTER_BITS;bit++){ + if(bitmask & (1<<bit)){ + m_global->writeHW(); + int cnt = 4; + FECommands::mccWriteRegister(bitStream, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_READ_PIXEL); + bitStream->push_back(0); + FECommands::feWriteCommand(bitStream, m_chip, (FECommands::FE_CMD_WRITE_HITBUS << bit) | + FECommands::FE_CMD_READ_PIXEL); + + bitStream->push_back(0); + int dcnt = 2; + cnt = (dcnt << 3) | 4; + FECommands::mccWriteRegister(bitStream, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bitStream, m_chip, (FECommands::FE_CMD_WRITE_HITBUS << bit) | + FECommands::FE_CMD_READ_PIXEL | FECommands::FE_CMD_CLOCK_PIXEL); + bitStream->push_back(0); + bitStream->push_back(0); + bitStream->push_back(0); + + cnt = 4; + FECommands::mccWriteRegister(bitStream, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bitStream, m_chip, (FECommands::FE_CMD_WRITE_HITBUS << bit) | + FECommands::FE_CMD_READ_PIXEL); + + bitStream->push_back(0); + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_READ_PIXEL); + bitStream->push_back(0); + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_NULL); + + bitStream->push_back(0); + dcnt = 1; // was npixels which always seems to be 1 + cnt = (dcnt << 3) | 4; + FECommands::mccWriteRegister(bitStream, Mcc::MCC_CNT, cnt); + + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_CLOCK_PIXEL); + bitStream->push_back(0); + + cnt = 4; + FECommands::mccWriteRegister(bitStream, Mcc::MCC_CNT, cnt); + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_WRITE_HITBUS << bit); + bitStream->push_back(0); + FECommands::feWriteCommand(bitStream, m_chip, FECommands::FE_CMD_NULL); + bitStream->push_back(0); + SerialIF::send(bitStream); + } + } + delete bitStream; + m_global->setField("doMux",8); + m_global->writeHW(); + } + +}; diff --git a/rce/rcecalib/config/FEI3/Frontend.hh b/rce/rcecalib/config/FEI3/Frontend.hh new file mode 100644 index 0000000000000000000000000000000000000000..1146532e77add7f4ca9d8a2cfa4400e0f14b78d9 --- /dev/null +++ b/rce/rcecalib/config/FEI3/Frontend.hh @@ -0,0 +1,42 @@ +#ifndef FEI3__FRONTEND_HH +#define FEI3__FRONTEND_HH + +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI3/GlobalRegister.hh" +#include "rcecalib/config/FEI3/PixelRegister.hh" + +namespace FEI3{ + + class Frontend{ + public: + Frontend(unsigned chip); + ~Frontend(); + enum{N_COLS=18, N_ROWS=160 ,N_PIXEL_REGISTER_BITS=14}; + void setChipAddress(unsigned i, unsigned addr); + void setVcalCoeff(unsigned i, float val); + void setCapVal(unsigned i, float val); + float getVcalCoeff(unsigned i); + float getCapVal(unsigned i); + void writePixelRegisterHW(unsigned bit); + void writeGlobalRegisterHW(); + void setGlobalRegField(const char *name, int val); + void setPixelParameter(PixelRegister::Field field, int val); + void configureHW(); + void shiftEnablesHW(unsigned short bitmask); + PixelRegister* getPixelRegister(unsigned col, unsigned row); + GlobalRegister* getGlobalRegister(){return m_global;} + const float dacToElectrons(int dac); + const int electronsToDac(float ne); + + private: + void pixelUsrToRaw(BitStream *bs, unsigned bit); + unsigned m_chip; + GlobalRegister *m_global; + PixelRegister m_pixel[N_COLS][N_ROWS]; + float m_vcalCoeff[4]; + float m_capVal[2]; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI3/GlobalRegister.cc b/rce/rcecalib/config/FEI3/GlobalRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..bba6aef0cd91bbf80702d76f3d03fc000d8bf23c --- /dev/null +++ b/rce/rcecalib/config/FEI3/GlobalRegister.cc @@ -0,0 +1,235 @@ + +#include "rcecalib/config/FEI3/GlobalRegister.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> + +namespace FEI3{ + + GlobalRegister::GlobalRegister(unsigned fe, unsigned chip){ + // initialize static field dictionay + if(!m_initialized)initialize(); + + //now build the write global register stream which will be cached. + // enable the front end + BitStreamUtils::prependZeros(&m_bitStream); + FECommands::mccWriteRegister(&m_bitStream, Mcc::MCC_FEEN, (1 << fe)); + + // cnt register with dcnt = # of global register bits = 231 + unsigned dcnt = FE_I3_N_GLOBAL_BITS; + unsigned cnt = (dcnt << 3) | 4; + FECommands::mccWriteRegister(&m_bitStream, Mcc::MCC_CNT, cnt); + + // clock in the global register. + FECommands::feWriteCommand(&m_bitStream, chip, FECommands::FE_CMD_CLOCK_GLOBAL); + // remember the index at which the global register itself will go + unsigned globalReg=m_bitStream.size(); + // initialize the register with zeroes. + unsigned gsize=(m_pos+sizeof(unsigned)-1)/sizeof(unsigned); + for(unsigned int i=0;i<gsize;i++)m_bitStream.push_back(0); + + // cnt register with dcnt = 0 + cnt = 4; + FECommands::mccWriteRegister(&m_bitStream, Mcc::MCC_CNT, cnt); + + // issue a write global + FECommands::feWriteCommand(&m_bitStream, chip, FECommands::FE_CMD_WRITE_GLOBAL); + m_bitStream.push_back(0); + FECommands::feWriteCommand(&m_bitStream, chip, FECommands::FE_CMD_NULL); + m_bitStream.push_back(0); + + // byte swap because the global register is big endian + //BitStreamUtils::byteSwap(&m_bitStream); + //set the pointer to the location of the global register + m_data=(unsigned char*)&m_bitStream[globalReg]; + } + GlobalRegister::~GlobalRegister(){ + } + void GlobalRegister::writeHW(){ + //SerialIF::send(&m_bitStream,SerialIF::DONT_CLEAR, SerialIF::BYTESWAP); + SerialIF::send(&m_bitStream,SerialIF::DONT_CLEAR); + } + + void GlobalRegister::setField(const char* name, unsigned val){ + char msg[128]; + sprintf(msg,"parameter %s is invalid",name); + ERS_ASSERT_MSG(m_fields.find(name)!=m_fields.end(),msg); + FieldParams params=m_fields[name]; + unsigned parity=0; + if(params.parity==true) + parity=getField("parity"); + unsigned char par; + for (unsigned int i=0;i<params.width;i++){ + unsigned char bit=(val>>(params.width-1-i))&0x1; + unsigned char bit5mhz= bit ? 0xff : 0; + if(params.parity){ + par=bit5mhz ^ m_data[params.position+i]; + parity ^= par; + } + m_data[params.position+i]=bit5mhz; + } + if(params.parity){ + setField("parity",parity); + } + } + + unsigned GlobalRegister::getField(const char* name){ + ERS_ASSERT_MSG(m_fields.find(name)!=m_fields.end(),"parameter name is invalid"); + FieldParams params=m_fields[name]; + unsigned retval=0; + for (unsigned int i=0;i<params.width;i++){ + retval<<=1; + if(m_data[params.position+i]) retval|=1; + } + return retval; + } + void GlobalRegister::enableAll(){ + setField("enableCP0",1); + setField("enableCP1",1); + setField("enableCP2",1); + setField("enableCP3",1); + setField("enableCP4",1); + setField("enableCP5",1); + setField("enableCP6",1); + setField("enableCP7",1); + setField("enableCP8",1); + setField("doMux",8); +} + + + std::string GlobalRegister::lookupParameter(const char* name){ + // check if this is the last name used, return cached value + if(name==m_cachedName)return m_cachedField; + // Now check if we can translate the name to a field name + if(m_parameters.find(name)!=m_parameters.end()){ + //cache result + m_cachedName=name; + m_cachedField=m_parameters[name]; + return m_cachedField; + // maybe it's a proper field name? + } else if (m_fields.find(name)!=m_fields.end()){ + m_cachedName=name; + m_cachedField=name; + return m_cachedField; + } + // not found. + else return ""; + } + void GlobalRegister::addParameter(const char* name, const char* field){ + m_parameters[name]=field; + } + void GlobalRegister::addField(const char* name,unsigned width, bool parity){ + FieldParams temp; + temp.position=m_pos; + temp.width=width; + temp.parity=parity; + m_fields[name]=temp; + m_pos+=width; + } + + std::map<std::string, FieldParams > GlobalRegister::m_fields; + std::map<std::string, std::string> GlobalRegister::m_parameters; + unsigned GlobalRegister::m_pos = 0; + bool GlobalRegister::m_initialized = false; + std::string GlobalRegister::m_cachedName; + std::string GlobalRegister::m_cachedField; + + void GlobalRegister::initialize(){ + addField("enableIpMonitor",1); + addField("enableBiasComp",1); + addField("enableTune",1); + addField("gTDac",5); + addField("enableHitbus",1); + addField("enableCP0",1); + addField("modeTOTThresh",2); + addField("threshTOTDouble",8); + addField("threshTOTMinimum",8); + addField("enableCP1",1); + addField("testDacIL2Dac",1); + addField("dacIL2",8); + addField("dacIL",8); + addField("testDacILDac",1); + addField("enableCP2",1); + addField("testDacForITH2Dac",1); + addField("dacITH2",8); + addField("dacITH1",8); + addField("testDacForITH1Dac",1); + addField("enableCP3",1); + addField("enableDigitalInject",1); + addField("CEUClockControl",2); + addField("eocMux",2); + addField("enableTestAnalogRef",1); + addField("enableExternalInj",1); + addField("enableCinjHigh",1); + addField("enableCP4",1); + addField("testDacForVCalDac",1); + addField("dacVCAL",10); + addField("dacITRIMIF",8); + addField("testDacForITrimIfDac",1); + addField("enableCP5",1); + addField("testDacForIFDac",1); + addField("dacIF",8); + addField("dacITRIMTH",8); + addField("testDacForITrimThDac",1); + addField("enableCP6",1); + addField("testDacForIPDac",1); + addField("dacIP",8); + addField("dacIP2",8); + addField("testDacForIP2Dac",1); + addField("enableCP7",1); + addField("testDacForIDDac",1); + addField("dacID",8); + addField("dacIVDD2",8); + addField("testDacForIVDD2Dac",1); + addField("enableCP8",1); + addField("enableBufferBoost",1); + addField("enableLeakMeas",1); + addField("enableVCalMeas",1); + addField("enableTestPixelMux",2); + addField("enableAnalogOut",1); + addField("enableCapTest",1); + addField("capMeasCircuitry",6); + addField("dRegMeas",2); + addField("enableDRegMeas",1); + addField("dRegTrim",2); + addField("enableLVDSRefMeas",1); + addField("enableAReg",1); + addField("aRegMeas",2); + addField("enableARegMeas",1); + addField("aRegTrim",2); + addField("monLeakADCMonComp",1, 0); // does not contribute to parity + addField("monLeakADCEnableComparator",1); + addField("monLeakDACTest",1); + addField("monLeakADCDAC",10); + addField("monLeakADCRefTest",1); + addField("hitBusScaler",8, 0); // does not contribute to parity + addField("enableEOEParity",1); + addField("selectDataPhase",1); + addField("tsiTscEnable",1); + addField("selectMonHit",4); + addField("doMux",4); + addField("enableHitParity",1); + addField("enableSelfTrigger",1); + addField("selfTriggerWidth",4); + addField("selfTriggerDelay",4); + addField("latency",8); + addField("parity",1, 0); + addField("rsvd",1, 0);/*to ensure word alignment*/ + + // Translation from scan parameter to Global register field + addParameter("LATENCY", "latency"); + addParameter("GDAC", "gTDac"); + addParameter("VCAL", "dacVCAL"); + addParameter("IF", "dacIF"); + m_initialized=true; + } + void GlobalRegister::dump(){ + std::cout<<"Global Register"<<std::endl; + for(std::map<std::string, FieldParams>::iterator it=m_fields.begin(); it!=m_fields.end();it++){ + std::cout<<it->first<<" "<<getField(it->first.c_str())<<std::endl; + } + } + +}; diff --git a/rce/rcecalib/config/FEI3/GlobalRegister.hh b/rce/rcecalib/config/FEI3/GlobalRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..45ca255a18f93de59df2fd8214a3908ea173315f --- /dev/null +++ b/rce/rcecalib/config/FEI3/GlobalRegister.hh @@ -0,0 +1,44 @@ +#ifndef GLOBALREGISTER_FEI3_HH +#define GLOBALREGISTER_FEI3_HH + +#include <map> +#include <string> +#include "rcecalib/HW/BitStream.hh" + +namespace FEI3{ + + struct FieldParams{ + unsigned position; + unsigned width; + bool parity; + }; + + class GlobalRegister{ + public: + GlobalRegister(unsigned fe, unsigned chip); + ~GlobalRegister(); + void setField(const char* name, unsigned val); + unsigned getField(const char* name); + void writeHW(); + void enableAll(); + static std::string lookupParameter(const char* name); + enum {FE_I3_N_GLOBAL_BITS=231}; + void dump(); + private: + unsigned char* m_data; + BitStream m_bitStream; + + // static functions + static void addField(const char* name, unsigned width, bool parity=1); + static void addParameter(const char* name, const char* field); + static void initialize(); + static std::map<std::string, FieldParams> m_fields; + static std::map<std::string, std::string> m_parameters; + static std::string m_cachedName, m_cachedField; + static unsigned m_pos; + static bool m_initialized; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI3/IPCModule.cc b/rce/rcecalib/config/FEI3/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..402a60d8f0d976496c71a2c0e4199eab45c3f3b1 --- /dev/null +++ b/rce/rcecalib/config/FEI3/IPCModule.cc @@ -0,0 +1,203 @@ +#ifndef FEI3__IPCMODULE_CC +#define FEI3__IPCMODULE_CC +#include "rcecalib/util/RceName.hh" +#include "rcecalib/config/FEI3/IPCModule.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace FEI3{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI3Adapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::PixelModuleConfig &legacyModuleConfig){ + m_mcc.setRegister(Mcc::MCC_LV1,legacyModuleConfig.MCCRegisters.regLV1); + m_mcc.setRegister(Mcc::MCC_CSR,legacyModuleConfig.MCCRegisters.regCSR); + m_mcc.setRegister(Mcc::MCC_CAL,legacyModuleConfig.MCCRegisters.regCAL); + m_mcc.setRegister(Mcc::MCC_FEEN,legacyModuleConfig.maskEnableFEConfig); + + const ipc::PixelFEConfig *legacyFEConfig; + const ipc::PixelFETrims *legacyFETrims; + const ipc::PixelFEMasks *legacyFEMasks; + for(int chip=0;chip<N_FRONTENDS;++chip) { + m_frontend[chip]->setChipAddress(chip, legacyModuleConfig.FEConfig[chip].FEIndex); + legacyFEConfig = &legacyModuleConfig.FEConfig[chip]; + legacyFETrims = &legacyFEConfig->FETrims; + legacyFEMasks = &legacyFEConfig->FEMasks; + + globalLegacyToUsr(legacyFEConfig, chip); + + m_frontend[chip]->setVcalCoeff(0, legacyFEConfig->FECalib.vcalCoeff[0]); + m_frontend[chip]->setVcalCoeff(1, legacyFEConfig->FECalib.vcalCoeff[1]); + m_frontend[chip]->setVcalCoeff(2, legacyFEConfig->FECalib.vcalCoeff[2]); + m_frontend[chip]->setVcalCoeff(3, legacyFEConfig->FECalib.vcalCoeff[3]); + m_frontend[chip]->setCapVal(0, legacyFEConfig->FECalib.cinjLo); + m_frontend[chip]->setCapVal(1, legacyFEConfig->FECalib.cinjHi); + + for(int col=0;col<Frontend::N_COLS;++col) { + for(int row=0;row<Frontend::N_ROWS;++row) { + unsigned char tdac = legacyFETrims->dacThresholdTrim[row][col]; + unsigned char fdac = legacyFETrims->dacFeedbackTrim[row][col]; + unsigned mask = (1 << (row & 0x1f)); + unsigned char enable = (legacyFEMasks->maskEnable[row >> 5][col] & mask) ? 1 : 0; + unsigned char select = (legacyFEMasks->maskSelect[row >> 5][col] & mask) ? 1 : 0; + unsigned char kill = (legacyFEMasks->maskPreamp[row >> 5][col] & mask) ? 1 : 0; + unsigned char hitbus = (legacyFEMasks->maskHitbus[row >> 5][col] & mask) ? 1 : 0; + PixelRegister* pixel=m_frontend[chip]->getPixelRegister(col,row); + pixel->setField(PixelRegister::tdac, tdac); + pixel->setField(PixelRegister::fdac, fdac); + pixel->setField(PixelRegister::enable, enable); + pixel->setField(PixelRegister::select, select); + pixel->setField(PixelRegister::kill, kill); + pixel->setField(PixelRegister::hitbus, hitbus); + } + } + } + std::cout<<"Configure done"<<std::endl; + return 0; +} +template <class TP> +void IPCModule<TP>::globalLegacyToUsr(const ipc::PixelFEConfig* legacyFE, unsigned chip){ + + const ipc::PixelFEGlobal *feGlobal; + feGlobal = &legacyFE->FEGlobal; + + m_frontend[chip]->setGlobalRegField("latency", feGlobal->latency); + m_frontend[chip]->setGlobalRegField("selfTriggerDelay", feGlobal->selfLatency); + m_frontend[chip]->setGlobalRegField("selfTriggerWidth", feGlobal->selfWidth); + m_frontend[chip]->setGlobalRegField("enableSelfTrigger", feGlobal->enableSelfTrigger); + m_frontend[chip]->setGlobalRegField("enableHitParity", feGlobal->enableHitParity); + m_frontend[chip]->setGlobalRegField("doMux", feGlobal->muxDO); + m_frontend[chip]->setGlobalRegField("selectMonHit", feGlobal->muxMonHit); + m_frontend[chip]->setGlobalRegField("tsiTscEnable", feGlobal->enableTimestamp); + + m_frontend[chip]->setGlobalRegField("selectDataPhase", 0); /* previously spare */ + m_frontend[chip]->setGlobalRegField("enableEOEParity", 0); /* previously spare */ + + m_frontend[chip]->setGlobalRegField("hitBusScaler", 0); /* read-only */ + + m_frontend[chip]->setGlobalRegField("monLeakADCRefTest", feGlobal->monADCRef); + m_frontend[chip]->setGlobalRegField("monLeakADCDAC", feGlobal->dacMonLeakADC); + m_frontend[chip]->setGlobalRegField("monLeakDACTest", feGlobal->monMonLeakADC); + m_frontend[chip]->setGlobalRegField("monLeakADCEnableComparator", feGlobal->enableMonLeak); + m_frontend[chip]->setGlobalRegField("monLeakADCMonComp", 0); /* status */ + m_frontend[chip]->setGlobalRegField("aRegTrim", feGlobal->aregTrim); + m_frontend[chip]->setGlobalRegField("enableARegMeas", feGlobal->enableAregMeas); + m_frontend[chip]->setGlobalRegField("aRegMeas", feGlobal->aregMeas); + m_frontend[chip]->setGlobalRegField("enableAReg", feGlobal->enableAreg); + m_frontend[chip]->setGlobalRegField("enableLVDSRefMeas", feGlobal->enableLvdsRegMeas); + m_frontend[chip]->setGlobalRegField("dRegTrim", feGlobal->dregTrim); + m_frontend[chip]->setGlobalRegField("enableDRegMeas", feGlobal->enableDregMeas); + m_frontend[chip]->setGlobalRegField("dRegMeas", feGlobal->dregMeas); + m_frontend[chip]->setGlobalRegField("capMeasCircuitry", feGlobal->capMeasure); + + m_frontend[chip]->setGlobalRegField("enableCapTest", feGlobal->enableCapTest); + m_frontend[chip]->setGlobalRegField("enableAnalogOut", feGlobal->enableBuffer); + m_frontend[chip]->setGlobalRegField("enableTestPixelMux", feGlobal->muxTestPixel); + m_frontend[chip]->setGlobalRegField("enableVCalMeas", feGlobal->enableVcalMeasure); + m_frontend[chip]->setGlobalRegField("enableLeakMeas", feGlobal->enableLeakMeasure); + m_frontend[chip]->setGlobalRegField("enableBufferBoost", feGlobal->enableBufferBoost); + + m_frontend[chip]->setGlobalRegField("enableCP8", feGlobal->enableCP8); + m_frontend[chip]->setGlobalRegField("testDacForIVDD2Dac", feGlobal->monIVDD2); + m_frontend[chip]->setGlobalRegField("dacIVDD2", feGlobal->dacIVDD2); + m_frontend[chip]->setGlobalRegField("dacID", feGlobal->dacID); + m_frontend[chip]->setGlobalRegField("testDacForIDDac", feGlobal->monID); + + m_frontend[chip]->setGlobalRegField("enableCP7", feGlobal->enableCP7); + m_frontend[chip]->setGlobalRegField("testDacForIP2Dac", feGlobal->monIP2); + m_frontend[chip]->setGlobalRegField("dacIP2", feGlobal->dacIP2); + m_frontend[chip]->setGlobalRegField("dacIP", feGlobal->dacIP); + m_frontend[chip]->setGlobalRegField("testDacForIPDac", feGlobal->monIP); + + m_frontend[chip]->setGlobalRegField("enableCP6", feGlobal->enableCP6); + m_frontend[chip]->setGlobalRegField("testDacForITrimThDac", feGlobal->monITRIMTH); + m_frontend[chip]->setGlobalRegField("dacITRIMTH", feGlobal->dacITRIMTH); + m_frontend[chip]->setGlobalRegField("dacIF", feGlobal->dacIF); + m_frontend[chip]->setGlobalRegField("testDacForIFDac", feGlobal->monIF); + + m_frontend[chip]->setGlobalRegField("enableCP5", feGlobal->enableCP5); + m_frontend[chip]->setGlobalRegField("testDacForITrimIfDac", feGlobal->monITRIMIF); + m_frontend[chip]->setGlobalRegField("dacITRIMIF", feGlobal->dacITRIMIF); + m_frontend[chip]->setGlobalRegField("dacVCAL", feGlobal->dacVCAL); + m_frontend[chip]->setGlobalRegField("testDacForVCalDac", feGlobal->monVCAL); + + m_frontend[chip]->setGlobalRegField("enableCP4", feGlobal->enableCP4); + m_frontend[chip]->setGlobalRegField("enableCinjHigh", feGlobal->enableCinjHigh); + m_frontend[chip]->setGlobalRegField("enableExternalInj", feGlobal->enableExternal); + m_frontend[chip]->setGlobalRegField("enableTestAnalogRef", feGlobal->enableTestAnalogRef); + m_frontend[chip]->setGlobalRegField("eocMux", feGlobal->muxEOC); + m_frontend[chip]->setGlobalRegField("CEUClockControl", feGlobal->frequencyCEU); + + m_frontend[chip]->setGlobalRegField("enableDigitalInject", feGlobal->enableDigital); + m_frontend[chip]->setGlobalRegField("enableCP3", feGlobal->enableCP3); + m_frontend[chip]->setGlobalRegField("testDacForITH1Dac", feGlobal->monITH1); + m_frontend[chip]->setGlobalRegField("dacITH1", feGlobal->dacITH1); + m_frontend[chip]->setGlobalRegField("dacITH2", feGlobal->dacITH2); + m_frontend[chip]->setGlobalRegField("testDacForITH2Dac", feGlobal->monITH2); + + m_frontend[chip]->setGlobalRegField("enableCP2", feGlobal->enableCP2); + m_frontend[chip]->setGlobalRegField("testDacILDac", feGlobal->monIL); + m_frontend[chip]->setGlobalRegField("dacIL", feGlobal->dacIL); + m_frontend[chip]->setGlobalRegField("dacIL2", feGlobal->dacIL2); + m_frontend[chip]->setGlobalRegField("testDacIL2Dac", feGlobal->monIL2); + + m_frontend[chip]->setGlobalRegField("enableCP1", feGlobal->enableCP1); + m_frontend[chip]->setGlobalRegField("threshTOTMinimum", feGlobal->threshTOTMinimum); + m_frontend[chip]->setGlobalRegField("threshTOTDouble", feGlobal->threshTOTDouble); + m_frontend[chip]->setGlobalRegField("modeTOTThresh", feGlobal->modeTOTThresh); + + m_frontend[chip]->setGlobalRegField("enableCP0", feGlobal->enableCP0); + m_frontend[chip]->setGlobalRegField("enableHitbus", feGlobal->enableHitbus); + m_frontend[chip]->setGlobalRegField("gTDac", feGlobal->gdac); + m_frontend[chip]->setGlobalRegField("enableTune", feGlobal->enableTune); + m_frontend[chip]->setGlobalRegField("enableBiasComp", feGlobal->enableBiasComp); + m_frontend[chip]->setGlobalRegField("enableIpMonitor", feGlobal->enableIpMonitor); +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/rcecalib/config/FEI3/IPCModule.hh b/rce/rcecalib/config/FEI3/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..e47a335d0bfd8e45d099257c7cb74cb6bfbfe012 --- /dev/null +++ b/rce/rcecalib/config/FEI3/IPCModule.hh @@ -0,0 +1,27 @@ +#ifndef IPCFEI3MODULE_HH +#define IPCFEI3MODULE_HH + +#include "rcecalib/config/FEI3/Module.hh" +#include "ipc/object.h" +#include "PixelModuleConfig.hh" +#include "IPCFEI3Adapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI3{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCFEI3Adapter,TP>, public FEI3::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelModuleConfig &config); + void globalLegacyToUsr(const ipc::PixelFEConfig* legacy, unsigned chip); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/rcecalib/config/FEI3/JJFormatter.cc b/rce/rcecalib/config/FEI3/JJFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..9cba38ac6df0e566720cda6de4836d3f94575f73 --- /dev/null +++ b/rce/rcecalib/config/FEI3/JJFormatter.cc @@ -0,0 +1,774 @@ +#include "rcecalib/config/FEI3/JJFormatter.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/config/Endianness.hh" +#include "rcecalib/config/BFU.hh" +#include <stdio.h> +//#define DEBUG +/* ====================================================================== */ +/* NEW DECODER */ +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- */ +/*! brief Maps out the sizes of the objects that are common amongst + various classes. */ +/* ---------------------------------------------------------------------- */ +namespace Size +{ + /* ------------------------------------------------------------------ */ + /*!< \brief The sizes of common objects */ + /* ------------------------------------------------------------------ */ + enum Size + { + HEADER = 5, + L1ID = 8, + SYNCH = 1, + BCID = 8, + KEY = 4, + FENUM = 4, + LEFT = 32-(HEADER + L1ID + SYNCH + BCID + SYNCH + KEY), + ZEROES = LEFT - 1 + }; + + + /* ------------------------------------------------------------------ */ + /*!< \brief Size of the three possible record types */ + /* ------------------------------------------------------------------ */ + namespace Record + { + enum Record + { + HEADER = 31, + MCCFE = 9, + HIT = 22, + TRAILER = 23 + }; + }; +} +/* ---------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------- *//*! + + \brief The value of the key field. + + The key field describes the 4-bit object identifier + */ +/* ---------------------------------------------------------------------- */ +namespace Key +{ + enum Key + { + MCCFE = 0xe, + FEFLAG = 0xf, + TRAILER = 0x0 + }; +} +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- *//*! + + \brief The value of the left-justified key field including the SYNCH bit + */ +/* ---------------------------------------------------------------------- */ +namespace SynchKey +{ + enum Key + { + MCCFE = (1<<31) | (Key::MCCFE << 27), + FEFLAG = (1<<31) | (Key::FEFLAG << 27), + TRAILER = (1<<31) | (Key::TRAILER << 27) + }; +} +/* ---------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------- *//*! + + \brief Maps out the first 32-bits of the record + */ +/* ---------------------------------------------------------------------- */ +namespace Header +{ + /* -------------------------------- *\ + | | + | 0123456789abcdef0123456789abcdef | + | -------------------------------- | + | hhhhhllllllllsbbbbbbbbskkkkffffs | + | 11101........1........11110....1 | + | | + \* -------------------------------- */ + struct MccFe + { +#if ENDIANNESS_IS_BIG + + unsigned int header: Size::HEADER; + unsigned int l1id: Size:: L1ID; + unsigned int synch0: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch1: Size:: SYNCH; + unsigned int key: Size:: KEY; + unsigned int fenum: Size:: FENUM; + unsigned int synch2: Size:: SYNCH; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int synch2: Size::SYNCH; + unsigned int fenum: Size::FENUM; + unsigned int key: Size:: KEY; + unsigned int synch1: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch0: Size:: SYNCH; + unsigned int l1id: Size:: L1ID; + unsigned int header: Size::HEADER; + +#else + +#error ENDIANNESS is not defined + +#endif + }; + + + /* -------------------------------- *\ + | | + | 0123456789abcdef0123456789abcdef | + | -------------------------------- | + | hhhhhllllllllsbbbbbbbbskkkkxxxxx | + | 11101........1........1........ | + | | + \* -------------------------------- */ + struct Generic + { +#if ENDIANNESS_IS_BIG + + unsigned int header: Size::HEADER; + unsigned int l1id: Size:: L1ID; + unsigned int synch0: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch1: Size:: SYNCH; + unsigned int key: Size:: KEY; + unsigned int left: Size:: LEFT; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int left: Size:: LEFT; + unsigned int key: Size:: KEY; + unsigned int synch1: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch0: Size:: SYNCH; + unsigned int l1id: Size:: L1ID; + unsigned int header: Size::HEADER; + +#else + +#error ENDIANNESS is not defined + +#endif + }; + + + /* -------------------------------- *\ + | | + | 0123456789abcdef0123456789abcdef | + | -------------------------------- | + | hhhhhllllllllsbbbbbbbbskkkksxxxx | + | 11101........1........1....1... | + | | + \* -------------------------------- */ + struct Trailer + { +#if ENDIANNESS_IS_BIG + + unsigned int header: Size::HEADER; + unsigned int l1id: Size:: L1ID; + unsigned int synch0: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch1: Size:: SYNCH; + unsigned int key: Size:: KEY; + unsigned int synch2: Size:: SYNCH; + unsigned int zeroes: Size::ZEROES; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int zeroes: Size::ZEROES; + unsigned int synch2: Size:: SYNCH; + unsigned int key: Size:: KEY; + unsigned int synch1: Size:: SYNCH; + unsigned int bcid: Size:: BCID; + unsigned int synch0: Size:: SYNCH; + unsigned int l1id: Size:: L1ID; + unsigned int header: Size::HEADER; + +#else + +#error ENDIANNESS is not defined + +#endif + }; + + + union Header + { + unsigned int ui; + Generic bf; + MccFe fe; + Trailer trailer; + } + u; +} +/* ---------------------------------------------------------------------- */ + + + + +/* ---------------------------------------------------------------------- *//*! + + \brief Maps out the extracted value word when it is interpretted as an + MCC-FE record + */ +/* ---------------------------------------------------------------------- */ +namespace MccFe +{ + struct MccFe_bf + { +#if ENDIANNESS_IS_BIG + + unsigned int synch: Size::SYNCH; + unsigned int key: Size:: KEY; + unsigned int fenum: Size::FENUM; + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + Size::FENUM); + +#elif ENDIANNESS_IS_LITTLE + + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + Size::FENUM); + unsigned int fenum: Size::FENUM; + unsigned int key: Size:: KEY; + unsigned int synch: Size::SYNCH; + +#endif + + }; + + union MccFe + { + unsigned int ui; + MccFe_bf bf; + }; +} +/* ---------------------------------------------------------------------- */ + + + + +/* ---------------------------------------------------------------------- *//*! + + \brief Maps out the extracted value word when it is interpretted as a + HIT record + */ +/* ---------------------------------------------------------------------- */ +namespace Hit +{ + enum Size + { + ROW = 8, + COL = 5, + TOT = 8, + VAL = ROW + COL + TOT + }; + + struct Hit_val + { + +#if ENDIANNESS_IS_BIG + + unsigned int synch: Size::SYNCH; + unsigned int val: VAL; + unsigned int pad: 32 - (Size::SYNCH + VAL); + +#elif ENDIANNESS_IS_LITTLE + + unsigned int pad: 32 - (Size::SYNCH + VAL); + unsigned int val: VAL; + unsigned int synch: Size::SYNCH; + +#endif + }; + + struct Hit_bf + { + +#if ENDIANNESS_IS_BIG + + unsigned int synch: Size::SYNCH; + unsigned int row: ROW; + unsigned int col: COL; + unsigned int tot: TOT; + unsigned int pad: 32 - (Size::SYNCH + VAL); + +#elif ENDIANNESS_IS_LITTLE + + unsigned int pad: 32 - (Size::SYNCH + VAL); + unsigned int tot: TOT; + unsigned int col: COL; + unsigned int row: ROW; + unsigned int synch: Size::SYNCH; + +#endif + }; + + union Hit + { + unsigned int ui; + Hit_val val; + Hit_bf bf; + }; + +} +/* ---------------------------------------------------------------------- */ + + + +/* ---------------------------------------------------------------------- *//*! + + \brief Maps out the extracted value word when it is interpretted as a + FEFLAG record + */ +/* ---------------------------------------------------------------------- */ +namespace FeFlag +{ + enum Size + { + MB1 = 1, + MCC = 8, + FE = 8, + VAL = MB1 + MCC + FE + }; + + + struct FeFlag_val + { +#if ENDIANNESS_IS_BIG + + unsigned int synch: Size::SYNCH; + unsigned int key: Size:: KEY; + unsigned int val: VAL; + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + VAL); + +#elif ENDIANNESS_IS_LITTLE + + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + VAL); + unsigned int val: VAL; + unsigned int key: Size:: KEY; + unsigned int synch: Size::SYNCH; + +#endif + }; + + struct FeFlag_bf + { + +#if ENDIANNESS_IS_BIG + + unsigned int synch: Size::SYNCH; + unsigned int key: Size:: KEY; + unsigned int mb1: MB1; + unsigned int mcc: MCC; + unsigned int fe: FE; + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + VAL); + +#elif ENDIANNESS_IS_LITTLE + + unsigned int pad: 32 - (Size::SYNCH + Size::KEY + VAL); + unsigned int fe: FE; + unsigned int mcc: MCC; + unsigned int mb1: MB1; + unsigned int key: Size:: KEY; + unsigned int synch: Size::SYNCH; + +#endif + }; + + union FeFlag + { + unsigned int ui; + FeFlag_val val; + FeFlag_bf bf; + }; +} +/* ---------------------------------------------------------------------- */ + + +/* ====================================================================== */ +/* DEBUGGING AIDs */ +/* ---------------------------------------------------------------------- */ +#ifdef DEBUG + +static inline void print_header_fe (Header::Header hdr) +{ + printf ("MccFe: %8.8x H:%2.2x L1:%2.2x Synch:%1u BC:%2.2x " + "Synch:%1u Key:%1.1x Fenum:%1x Synch:%1x\n", + hdr.ui, + hdr.fe.header, + hdr.fe.l1id, + hdr.fe.synch0, + hdr.fe.bcid, + hdr.fe.synch1, + hdr.fe.key, + hdr.fe.fenum, + hdr.fe.synch2); + return; +} + +static inline void print_header_trailer (Header::Header hdr) +{ + printf ("Trailer: %8.8x H:%2.2x L1:%2.2x Synch:%1u BC:%2.2x " + "Synch:%1u Key:%1.1x Synch:%1u zeroes:%2.2x\n", + hdr.ui, + hdr.trailer.header, + hdr.trailer.l1id, + hdr.trailer.synch0, + hdr.trailer.bcid, + hdr.trailer.synch1, + hdr.trailer.key, + hdr.trailer.synch2, + hdr.trailer.zeroes + ); + return; +} + +static inline void print_title (Header::Header hdr) +{ + printf ( +" Value What Raw Fe Row Col Tot Mb1 Mcc Fe L1id BCid\n" +" -------- ------- -------- ---- --- --- --- --- --- --- %2x %2x\n", + hdr.bf.l1id, + hdr.bf.bcid); + return; +} + +static inline void print_mccfe0 (Header::Header header) +{ + printf (" MccFe ........ %4x ... ... ... ... ... ...\n", + header.fe.fenum); + return; +} + + +static inline void print_hit (unsigned int val) +{ + Hit::Hit hit; + hit.ui = val; + printf (" %8.8x Hit %8.8x .... %3x %3x %3x ... ... ...\n", + hit.ui, + hit.val.val, + hit.bf.row, + hit.bf.col, + hit.bf.tot); + return; +} + +static inline void print_mccfe (unsigned int val) +{ + MccFe::MccFe mccfe; + mccfe.ui = val; + printf (" %8.8x MccFe ........ %4x ... ... ... ... ... ...\n", + mccfe.ui, + mccfe.bf.fenum); + return; +} + +static inline void print_feflag (unsigned int val) +{ + FeFlag::FeFlag feflag; + feflag.ui = val; + printf (" %8.8x FeFlag %8.8x .... ... ... ... %3x %3x %3x\n", + feflag.ui, + feflag.val.val, + feflag.bf.mb1, + feflag.bf.mcc, + feflag.bf.fe); + return; +} + +static inline void print_error (unsigned int val) +{ + printf (" %8.8x Error\n", val); + return; +} + + +static inline void print_trailer (unsigned int val) +{ + printf (" %8.8x Trailer\n", val); + return; +} + +#else +#define print_header_fe(_hdr) +#define print_header_trailer(_hdr) +#define print_title(_hdr) +#define print_mccfe0(_intro) +#define print_hit(_val) +#define print_mccfe(_val) +#define print_feflag(_val) +#define print_error(_val) +#define print_trailer(_val) + +#endif +/* ====================================================================== */ + + + + + +/* ---------------------------------------------------------------------- */ +namespace Decoder { +namespace Status { + + +/* ---------------------------------------------------------------------- *//*! + + \brief Enumerate the various return status codes that decoder can return + + The usual UNIX convention is used. If the value is + - > 0, none currently + - ==0, Successful + - < 0, Error + */ +/* ---------------------------------------------------------------------- */ +enum Status +{ + OK = 0, /*!< Clean finish */ + HeaderSynch = -1, /*!< Initial synch bit in the header not found */ + L1IdSynch = -2, /*!< Synch bit preceeding the LI id not found */ + BCIdSynch = -3, /*!< Synch bit preceeding the BC id not found */ + HeaderTrailer = -4, /*!< Malformed trailer key occurred in the header */ + HeaderKey = -5, /*!< An illegal key occurred in the header, only + MccFe and Trailer keys are allowed */ + PrematureEos = -6, /*!< The bit stream-terminated too soon. There + must be at least a TRAILER records worth of + bits after the header record has been + processed. */ + NoSynch = -7, /*!< Synch bit on a record after the header was + not found. */ +}; + +}} + + + +/* ====================================================================== *//*! + + \brief The record decoder + + \param buffer The record buffer to decoder + \param buflen The length, in 32-bit words, of \a buffer + */ +/* ---------------------------------------------------------------------- */ +int JJFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A) +{ + using namespace Decoder; + + int end = buflen * 32; + int position = 0; + Header::Header hdr; + const unsigned int *buf = buffer; + Hit::Hit hit; + MccFe::MccFe mccfe; + + // Loop over all events in this buffer + while (1) + { + unsigned int val; + unsigned int cur = buffer[position >> 5]; + while(position < end && (signed)_bfu_testBit(cur,position)>=0){ + _bfu_wordL (val, cur, buf, position, 1); + position += 1; + } + + // Check if have enough bits to continue + if (position + Size::Record::HEADER >= end) return Status::OK; + + + _bfu_wordL (hdr.ui, cur, buf, position, Size::Record::HEADER); + position += Size::Record::HEADER; + print_title (hdr); + // printf("%x\n",hdr.ui); + + if(hdr.ui==0)return Status::OK; + // If the synch bit (its in the sign bit) is not set, then error + if ((signed)hdr.ui > 0) + { + print_error (hdr.ui); + return Status::HeaderSynch; + } + + unsigned int key = hdr.bf.key; + + /* + | In the usual case, the key should be MCCFE. + | The only other legitimate value is the TRAILER. + */ + if (key != Key::MCCFE) + { + // Either immediate end or error + if (key == Key::TRAILER) + { + //print_header_trailer (hdr); + + // Need another 14 bits of 0s to complete the trailer + _bfu_wordL (val, cur, buf, position, Size::Record::TRAILER + - Size::Record::MCCFE); + position += Size::Record::TRAILER - Size::Record::MCCFE; + + // If non-zero, error + if (val) + { + print_error (hdr.ui); + return Status::HeaderTrailer; + } + + print_trailer (hdr.ui); + nL1A++; + FormattedRecord fr(FormattedRecord::HEADER); + fr.setL1id(hdr.trailer.l1id); + fr.setBxid(hdr.trailer.bcid); + parsedData[parsedsize++]=fr.getWord(); + continue; + } + + // Illegitimate record key found + print_error (hdr.ui); + return Status::HeaderKey; + } + + + // Print the header as holding an MCC FE record + print_mccfe (hdr.ui); + mccfe.bf.fenum = hdr.fe.fenum; + FormattedRecord fr(FormattedRecord::HEADER); + fr.setL1id(hdr.fe.l1id); + fr.setBxid(hdr.fe.bcid); + parsedData[parsedsize++]=fr.getWord(); + nL1A++; + + + /* + | Start the real decoding + | The loop grabs 22 bits at a time on the premise that the only + | object not at least that long is the MCC-FE. Note the trailer + | is 23 bits, so if it is encountered, one more bit needs to be + | grabbed. If the MCC-FE is found, special action is taken which + | consists of (effectively) pushing the overread bits back into + | the input stream. + */ + while (1) + { + // Must have at least 23 bits remaining for the trailer + if (position + Size::Record::TRAILER >= end) + { + print_error (0xffffffff); + return Status::PrematureEos; + } + + _bfu_wordL (val, cur, buf, position, Size::Record::HIT); + position += Size::Record::HIT; + + /* + | Since the synch bit is in the sign bit, if the signed + | interpretation is greater than 0, then, error + */ + if ((signed)val > 0) + { + // Error, the stream is lost + print_error (val); + return Status::NoSynch; + } + + + if (val < (unsigned)SynchKey::MCCFE) + { + // This is either a hit or the trailer + if ((val << 1) == 0) + { + /* + | Looks like the trailer, but maybe HIT = 0 exception + | The next bit determines which. If this is not the end + | then this bit is effectively the synch bit for the + | next record. If it is, we don't want to read it, that + | would leave the bit stream at the wrong place. So here + | we just test it. + */ + val = _bfu_testBit (cur, position); + + // If >=0, then have hit the trailer for this event + if ((signed)val >= 0) + { + print_trailer (val); + + // The test bit belongs with the trailer, update pos + _bfu_wordL (val, cur, buf, position, 1); + position += 1; + + // Check if any left + if (position + Size::Record::HEADER >= end) + { + /* + | !!! Need to check that the remaining bits to + | the end of the 32-bit word are 0. + */ + return Status::OK; + } + + /* + | Done with this event, but still more to process + | The reestablishment of 'cur' happens at the top + | of loop that reads the header. + */ + break; + } + + // This was the case of ROW = 0, COL = 0 TOT = 0 + // Just continue + } + + // Just a hit + print_hit (val); + hit.ui=val; + FormattedRecord fr(FormattedRecord::DATA); + fr.setToT(hit.bf.tot); + fr.setCol(hit.bf.col); + fr.setRow(hit.bf.row); + fr.setFE(mccfe.bf.fenum); + parsedData[parsedsize++]=fr.getWord(); + } + + + else if (val < (unsigned)SynchKey::FEFLAG) + { + /* + | MCCFe, have pulled too many bits, put the excess back + | Have pulled 22 bits, + | 5 are the synch and key, + | 4 are the fenum + | This means 22 - 9 must be pushed backed + */ + print_mccfe (val); + mccfe.ui=val; + position -= (Size::Record::HIT - Size::Record::MCCFE); + buf = buffer + (position >> 5); + cur = *buf; + } + + else + { + print_feflag (val); + //printf("fe flag\n"); + } + } + } +} +/* ====================================================================== */ diff --git a/rce/rcecalib/config/FEI3/JJFormatter.hh b/rce/rcecalib/config/FEI3/JJFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..b81d6d466b44f93f4b93a31a76087c3844480bfe --- /dev/null +++ b/rce/rcecalib/config/FEI3/JJFormatter.hh @@ -0,0 +1,14 @@ +#ifndef JJFORMATTER_HH +#define JJFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" + +class JJFormatter:public AbsFormatter{ +public: + JJFormatter(int id): + AbsFormatter(id, "JJ"){} + virtual ~JJFormatter(){} + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + +}; +#endif diff --git a/rce/rcecalib/config/FEI3/MaskStageFactory.cc b/rce/rcecalib/config/FEI3/MaskStageFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..97d3b160d66d31188afd8eb5225dc7ce7fa47f67 --- /dev/null +++ b/rce/rcecalib/config/FEI3/MaskStageFactory.cc @@ -0,0 +1,86 @@ +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI3/PixelRegister.hh" +#include "rcecalib/config/FEI3/RegularMaskStaging.hh" +#include "rcecalib/config/FEI3/CrosstalkMaskStaging.hh" +#include "rcecalib/config/Masks.hh" +#include <assert.h> +#include <string> +#include <iostream> + +using namespace FEI3; + +template<> Masks MaskStageFactory::createIOmasks<FEI3::Module>(const char* maskStagingMode){ + Masks m; + m.oMask=m.iMask=m.xtalk_on=m.xtalk_off=m.crosstalking=0; + std::string stagingMode(maskStagingMode); + if(std::string(stagingMode)=="SEL"){ + m.oMask=(1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::hitbus]); + m.iMask=(1<<fieldPos[PixelRegister::select]); + } else if(std::string(stagingMode)=="ENA"){ + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::enable]); + m.iMask=(1<<fieldPos[PixelRegister::enable]); + } else if(std::string(stagingMode)=="SEL_ENA"){ + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]); + m.iMask=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]); + } else if(std::string(stagingMode)=="SEL_ENA_PRE"){ + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.iMask=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + } else if(std::string(stagingMode)=="SEL_PRE"){ + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.iMask=(1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + } else if(std::string(stagingMode)=="SENS_XTALK"){ + m.crosstalking = 1; + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]); + m.iMask=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.xtalk_off=(1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.xtalk_on=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::kill]); + } else if(std::string(stagingMode)=="XTALK"){ + m.crosstalking = 1; + m.oMask=(1<<fieldPos[PixelRegister::hitbus]) + | (1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.iMask=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::select]) + | (1<<fieldPos[PixelRegister::kill]); + m.xtalk_off=(1<<fieldPos[PixelRegister::select]); + m.xtalk_on=(1<<fieldPos[PixelRegister::enable]) + | (1<<fieldPos[PixelRegister::kill]); + } + m.oMask=~m.oMask; // invert + return m; +} + +template<> +MaskStaging<FEI3::Module>* MaskStageFactory::createMaskStaging(FEI3::Module* mod, const char* maskStagingType, const char* maskStagingMode){ + Masks iomask=createIOmasks<FEI3::Module>(maskStagingMode); + std::string stagingType(maskStagingType); + if(stagingType.substr(0,6)=="STEPS_" && iomask.crosstalking==false) + return new FEI3::RegularMaskStaging(mod, iomask, stagingType); + else if(stagingType=="STEPS_2880" && iomask.crosstalking==true) + return new FEI3::CrosstalkMaskStaging(mod, iomask, stagingType); + else{ + std::cout<<"Wrong staging type "<<stagingType<<std::endl; + assert(0); + } +} diff --git a/rce/rcecalib/config/FEI3/MaskStaging.cc b/rce/rcecalib/config/FEI3/MaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..aff466d4e34c6295679b2bbea99b51ec39733db9 --- /dev/null +++ b/rce/rcecalib/config/FEI3/MaskStaging.cc @@ -0,0 +1,22 @@ +#include "rcecalib/config/MaskStaging.hh" +#include "rcecalib/config/FEI3/Module.hh" + +using namespace FEI3; + +template<> bool MaskStaging<FEI3::Module>::cLow(){ + return m_clow; +} +template<> bool MaskStaging<FEI3::Module>::cHigh(){ + return m_chigh; +} + +template<> void MaskStaging<FEI3::Module>::clearBitsHW(){ + for (int k=0;k<Module::N_FRONTENDS;k++){ + for (int i=0;i<Frontend::N_COLS;i++){ + for (int j=0;j<Frontend::N_ROWS;j++){ + PixelRegister *pixel=m_module->frontend(k)->getPixelRegister(i,j); + pixel->set(pixel->get() & m_masks.oMask); + } + } + } +} diff --git a/rce/rcecalib/config/FEI3/Mcc.cc b/rce/rcecalib/config/FEI3/Mcc.cc new file mode 100644 index 0000000000000000000000000000000000000000..59f3db2215dc62af1543096e63c816e42c71005c --- /dev/null +++ b/rce/rcecalib/config/FEI3/Mcc.cc @@ -0,0 +1,92 @@ + +#include "rcecalib/config/FEI3/Mcc.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "ers/ers.h" + +namespace FEI3{ + Mcc::Mcc(){ + clear(); + } + Mcc::~Mcc(){} + void Mcc::clear(){ + for (int i=0;i<MCC_NREG;i++)m_register[i]=0; + } + + void Mcc::setRegister(Mcc::Register reg, unsigned val){ + if(reg<MCC_NREG){ + m_register[reg]=val; + } + } + void Mcc::setNLvl1(unsigned val){ + ERS_ASSERT_MSG(val<=16, "the number of L1A triggers is too large"); + m_register[MCC_LV1]=(val-1)<<8; + } + void Mcc::enableDelay(bool on){ + if(on){ + m_register[MCC_CAL]|=(1<<10); + }else{ + m_register[MCC_CAL]&=~(1<<10); + } + } + void Mcc::setBandwidth(unsigned val){ + m_register[MCC_CSR]=val; + } + void Mcc::setChipEnables(unsigned val){ + m_register[MCC_FEEN]=val; + } + void Mcc::setStrobeDuration(unsigned val){ + m_register[MCC_CNT]=val; + } + void Mcc::setStrobeDelayRange(unsigned val){ + ERS_ASSERT_MSG(val<16, "value is too large"); + m_register[MCC_CAL]&=~(0xf<<6); //clear the field + m_register[MCC_CAL]|=(val<<6); + } + void Mcc::setStrobeDelay(unsigned val){ + ERS_ASSERT_MSG(val<64, "value is too large"); + m_register[MCC_CAL]&=~(0x3f); //clear the field + m_register[MCC_CAL]|=val; + enableDelay(1);//delay gets enabled implicitely + // std::cout<<" MCC_CAL "<<std::hex<<m_register[MCC_CAL]<<std::dec<<std::endl; + } + void Mcc::writeRegister(BitStream *bs, Mcc::Register reg){ + FECommands::mccWriteRegister(bs,reg,m_register[reg]); + } + void Mcc::configureHW(){ + BitStream* bs=new BitStream; + BitStreamUtils::prependZeros(bs); + writeRegister(bs, Mcc::MCC_CSR); + writeRegister(bs, Mcc::MCC_LV1); + writeRegister(bs, Mcc::MCC_CAL); + writeRegister(bs, Mcc::MCC_CNT); + SerialIF::send(bs); + delete bs; + } + + int Mcc::setParameter(const char* name, int val){ + int retval=1; + if(std::string(name)=="STROBE_DELAY"){ + setStrobeDelay(val); + }else if(std::string(name)=="STROBE_DEL_RANGE"){ + setStrobeDelayRange(val); + }else if (std::string(name)=="trigOpt.nL1AperEvent"){ + setNLvl1(val); + }else if (std::string(name)=="trigOpt.strobeMCCDelay"){ + setStrobeDelay(val); + }else if (std::string(name)=="trigOpt.strobeMCCDelayRange"){ + setStrobeDelayRange(val); + }else if (std::string(name)=="trigOpt.strobeDuration"){ + setStrobeDuration(val); + }else if (std::string(name)=="bandwidth"){ + setBandwidth(val); + }else if (std::string(name)=="enables"){ + setChipEnables(val); + }else{ + retval=0; + } + return retval; + } +}; + + diff --git a/rce/rcecalib/config/FEI3/Mcc.hh b/rce/rcecalib/config/FEI3/Mcc.hh new file mode 100644 index 0000000000000000000000000000000000000000..d1a69c03137e0ff016878909fdc0c795dc0c56ab --- /dev/null +++ b/rce/rcecalib/config/FEI3/Mcc.hh @@ -0,0 +1,37 @@ +#ifndef MCC_HH +#define MCC_HH + +#include <map> +#include "rcecalib/HW/BitStream.hh" + +namespace FEI3{ + +class Mcc{ +public: + enum Register{MCC_CSR, MCC_LV1, MCC_FEEN, MCC_WFE, MCC_WMCC, MCC_CNT, MCC_CAL, MCC_PEF, MCC_NREG}; + Mcc(); + ~Mcc(); + void setRegister(Register reg, unsigned val); + void setNLvl1(unsigned val); + void enableDelay(bool on); + void setStrobeDelayRange(unsigned val); + void setStrobeDelay(unsigned val); + void setStrobeDuration(unsigned val); + void setBandwidth(unsigned val); + void setChipEnables(unsigned val); + void writeRegister(BitStream* bs, Mcc::Register reg); + void configureHW(); + void clear(); + int setParameter(const char* name, int val); + // MCC related commands + static void writeRegister(BitStream* bs, Mcc::Register reg, unsigned value); + static void resetMCC(BitStream *bs); + + +private: + unsigned short m_register[8]; + +}; + +}; +#endif diff --git a/rce/rcecalib/config/FEI3/Module.cc b/rce/rcecalib/config/FEI3/Module.cc new file mode 100644 index 0000000000000000000000000000000000000000..e8c45626df35d16ecab35b4167275bbcdc461b9e --- /dev/null +++ b/rce/rcecalib/config/FEI3/Module.cc @@ -0,0 +1,172 @@ +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> + +namespace FEI3{ + + Module::Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt) + :AbsModule(name, id,inLink, outLink, fmt), m_maskStaging(0){ + // std::cout<<"Module"<<std::endl; + for (int i=0;i<N_FRONTENDS;i++){ + m_frontend[i]=new Frontend(i); + } + } + Module::~Module(){ + for (int i=0;i<N_FRONTENDS;i++){ + delete m_frontend[i]; + } + delete m_maskStaging; + } + void Module::configureHW(){ + //std::cout<<"Configuring "<<m_inLink<<std::endl; + resetHW(); + m_mcc.configureHW(); + for (int i=0;i<N_FRONTENDS;i++){ + m_frontend[i]->configureHW(); + } + } + + void Module::resetFE(){ + resetHW(true); + } + void Module::resetHW(bool resetfe){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FECommands::resetMCC(bs); + if(resetfe)FECommands::resetFE(bs,FECommands::FE_CMD_SOFT_RESET); + SerialIF::send(bs); + delete bs; + } + void Module::enableDataTakingHW(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FECommands::sendECR(bs); + FECommands::sendBCR(bs); + SerialIF::send(bs); + BitStreamUtils::prependZeros(bs); + m_mcc.writeRegister(bs, Mcc::MCC_CNT); + m_mcc.writeRegister(bs, Mcc::MCC_FEEN); + FECommands::enableDataTaking(bs); + SerialIF::send(bs); + delete bs; + } + + void Module::setupMaskStageHW(int maskStage) { + m_maskStaging->setupMaskStageHW(maskStage); + } + + //set the value in the register but not in the frontend + Module::PAR Module::setParameter(const char* name, int val){ + if(std::string(name)=="CHARGE"){ + for (int i=0;i<N_FRONTENDS;i++){ + //std::cout<<"Fronted "<<i<<" dac setting "<<m_frontend[i]->electronsToDac(val)<<std::endl; + m_frontend[i]->setGlobalRegField("dacVCAL", m_frontend[i]->electronsToDac(val)); + } + return SPECIAL; + } + if (std::string(name)=="NO_PAR"){ + return SPECIAL; + } + PixelRegister::Field fpar=PixelRegister::lookupParameter(name); + if (fpar!=PixelRegister::not_found){ + for (int i=0;i<N_FRONTENDS;i++){ + m_frontend[i]->setPixelParameter(fpar, val); + } + return PIXEL; + } + std::string par=GlobalRegister::lookupParameter(name); + if(par!=""){ //it's a global variable + for (int i=0;i<N_FRONTENDS;i++){ + m_frontend[i]->setGlobalRegField(par.c_str(), val); + } + return GLOBAL; + } + // wasn't a global variable, should be MCC then. + int rt=m_mcc.setParameter(name, val); + if(rt)return MCC; + char error_message[128]; + sprintf(error_message, "parameter %s was not found.",name); + ERS_ASSERT_MSG(NOT_FOUND, error_message); + return NOT_FOUND; + } + // set a parameter (global or MCC) in the frontend + int Module::setupParameterHW(const char* name, int val){ + int retval=1; + //first set the appropriate internal register + PAR p=setParameter(name,val); + // now send the config to the frontend + if(p!=NOT_FOUND){ + retval=0; + resetHW(false); //don't reset FE, only MCC + m_mcc.configureHW(); + for (int i=0;i<N_FRONTENDS;i++){ + m_frontend[i]->writeGlobalRegisterHW(); + } + } + return retval; + } + + int Module::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + //std::cout<<"FEI3::Module::configureScan"<<std::endl; + try{ + // MCC + setParameter("trigOpt.nL1AperEvent",scanOptions->get<int>("trigOpt.nL1AperEvent")); + setParameter("bandwidth",0); + setParameter("trigOpt.strobeMCCDelayRange",scanOptions->get<int>("trigOpt.strobeMCCDelayRange")); + setParameter("trigOpt.strobeMCCDelay",scanOptions->get<int>("trigOpt.strobeMCCDelay")); + setParameter("trigOpt.strobeDuration",scanOptions->get<int>("trigOpt.strobeDuration")); + //setParameter("enables",0xffff); + // Global regs + int diginject=scanOptions->get("trigOpt.optionsMask.DIGITAL_INJECT", 0); + if(diginject)setParameter("enableDigitalInject",1); + else setParameter("enableDigitalInject",0); + setParameter("latency",scanOptions->get<int>("trigOpt.Lvl1_Latency")); + int chigh=scanOptions->get("trigOpt.optionsMask.USE_CHIGH", 0); + if(chigh)setParameter("enableCinjHigh",1); + else setParameter("enableCinjHigh",0); + std::string stagingMode=scanOptions->get<std::string>("stagingMode"); + std::string maskStages=scanOptions->get<std::string>("maskStages"); + delete m_maskStaging; + MaskStageFactory msf; + m_maskStaging=msf.createMaskStaging(this, maskStages.c_str(), stagingMode.c_str()); + if(chigh){ + m_maskStaging->setClow(0); + m_maskStaging->setChigh(1); + }else{ + m_maskStaging->setClow(1); + m_maskStaging->setChigh(0); + } + setParameter("doMux",8); // event data + // set Vcal for each FE + std::string par="dacVCAL"; + if(scanOptions->get("trigOpt.optionsMask.SPECIFY_CHARGE_NOT_VCAL", 0)==1)par="CHARGE"; + setParameter(par.c_str(),scanOptions->get<int>("trigOpt.vcal_charge")); + } + catch(boost::property_tree::ptree_bad_path ex){ + retval=1; + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + // std::cout<<"FEI3::Module::configureScan end"<<std::endl; + return retval; + } + void Module::destroy(){ + delete this; + } + ModuleInfo Module::getModuleInfo(){ + return ModuleInfo(m_name, m_id,m_inLink, m_outLink,Module::N_FRONTENDS,Frontend::N_ROWS,Frontend::N_COLS, m_formatter); + } + const float Module::dacToElectrons(int fe, int dac){ + if(fe>=N_FRONTENDS)return -1; + return m_frontend[fe]->dacToElectrons(dac); + } +}; + diff --git a/rce/rcecalib/config/FEI3/Module.hh b/rce/rcecalib/config/FEI3/Module.hh new file mode 100644 index 0000000000000000000000000000000000000000..96897d7af60ebaf3a35d211ff1152ad43139dbde --- /dev/null +++ b/rce/rcecalib/config/FEI3/Module.hh @@ -0,0 +1,41 @@ +#ifndef FEI3__MODULE_HH +#define FEI3__MODULE_HH + +#include "rcecalib/config/FEI3/Frontend.hh" +#include "rcecalib/config/FEI3/Mcc.hh" +#include "rcecalib/config/AbsModule.hh" +#include "rcecalib/config/MaskStaging.hh" +#include <boost/property_tree/ptree_fwd.hpp> + +class AbsFormatter; + +namespace FEI3{ + + class Module: public AbsModule{ + public: + Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + virtual ~Module(); + enum {N_FRONTENDS=16}; + enum PAR{NOT_FOUND, GLOBAL, MCC, SPECIAL, PIXEL}; + Mcc* mcc(){return &m_mcc;} + Frontend* frontend(int i){return m_frontend[i];} + void configureHW(); + void resetHW(bool resetfe=true); + void resetFE(); + void setupMaskStageHW(int stage); + void enableDataTakingHW(); + int setupParameterHW(const char* name, int val); //HW setup + PAR setParameter(const char* name, int val); // internal setup + int configureScan(boost::property_tree::ptree* scanOptions); + ModuleInfo getModuleInfo(); + const float dacToElectrons(int fe, int dac); + virtual void destroy(); + +protected: + Frontend *m_frontend[N_FRONTENDS]; + Mcc m_mcc; + MaskStaging<FEI3::Module>* m_maskStaging; +}; + +}; +#endif diff --git a/rce/rcecalib/config/FEI3/ModuleGroup.cc b/rce/rcecalib/config/FEI3/ModuleGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..63e65e59aa893bbe35ada113fa50d3da74c594fc --- /dev/null +++ b/rce/rcecalib/config/FEI3/ModuleGroup.cc @@ -0,0 +1,88 @@ + +#include <boost/property_tree/ptree.hpp> +#include <stdio.h> +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI3/ModuleGroup.hh" +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include "rcecalib/HW/SerialIF.hh" + +namespace FEI3{ + +void ModuleGroup::addModule(Module* module){ + m_modules.push_back(module); + m_channelInMask|=1<<module->getInLink(); + m_channelOutMask|=1<<module->getOutLink(); +} + +void ModuleGroup::deleteModules(){ + for (unsigned i=0; i<m_modules.size();i++){ + //cannot call delete directly because IPC modules need to call _destroy() instead. + m_modules[i]->destroy(); + } + m_modules.clear(); + m_channelInMask=0; + m_channelOutMask=0; +} + +int ModuleGroup::setupParameterHW(const char* name, int val, bool bcOK){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + retval+=m_modules[i]->setupParameterHW(name,val); + } + disableAllInChannels(); + return retval; +} + +int ModuleGroup::setupMaskStageHW(int stage){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->setupMaskStageHW(stage); + } + disableAllInChannels(); + return 0; +} + +void ModuleGroup::configureModulesHW(){ + //std::cout<<"Configure Modules HW"<<std::endl; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->configureHW(); + } + disableAllInChannels(); +} + +void ModuleGroup::resetFE(){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->resetFE(); + } + disableAllInChannels(); +} + +void ModuleGroup::enableDataTakingHW(){ + //std::cout<<"ConfigIF enabled data taking"<<std::endl; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->enableDataTakingHW(); + } + disableAllInChannels(); +} + +int ModuleGroup::verifyModuleConfigHW(){ + return 0; // does not exist for FEI3 +} +void ModuleGroup::resetErrorCountersHW(){ + //does not exist for FEI3 +} + +int ModuleGroup::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + retval+=m_modules[i]->configureScan(scanOptions); + } + return retval; +} + +} diff --git a/rce/rcecalib/config/FEI3/ModuleGroup.hh b/rce/rcecalib/config/FEI3/ModuleGroup.hh new file mode 100644 index 0000000000000000000000000000000000000000..1c1647309d269644a081b20591dd5c6f5b341322 --- /dev/null +++ b/rce/rcecalib/config/FEI3/ModuleGroup.hh @@ -0,0 +1,33 @@ +#ifndef MODULEGROUPFEI3_HH +#define MODULEGROUPFEI3_HH +#include "rcecalib/config/AbsModuleGroup.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <vector> + +namespace FEI3{ + + class Module; + +class ModuleGroup: public AbsModuleGroup{ +public: + ModuleGroup():AbsModuleGroup(){}; + virtual ~ModuleGroup(){} + void addModule(Module* module); + void deleteModules(); + int setupParameterHW(const char* name, int val, bool bcok); + int setupMaskStageHW(int stage); + void configureModulesHW(); + int verifyModuleConfigHW(); + void resetErrorCountersHW(); + int configureScan(boost::property_tree::ptree *scanOptions); + void resetFE(); + void enableDataTakingHW(); + unsigned getNmodules(){return m_modules.size();} +private: + void switchToConfigModeHW(); + std::vector<Module*> m_modules; + +}; +} + +#endif diff --git a/rce/rcecalib/config/FEI3/PixelRegister.cc b/rce/rcecalib/config/FEI3/PixelRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..2c0886c2e03f7b575d35337eab88c68554ad66aa --- /dev/null +++ b/rce/rcecalib/config/FEI3/PixelRegister.cc @@ -0,0 +1,25 @@ +#include "rcecalib/config/FEI3/PixelRegister.hh" + +namespace FEI3{ + std::string PixelRegister::m_cachedName; + PixelRegister::Field PixelRegister::m_cachedField(not_found); + std::map<std::string, PixelRegister::Field> PixelRegister::m_parameters; + bool PixelRegister::m_initialized = false; + void PixelRegister::initialize(){ + // Translation from scan parameter to Global register field + m_parameters["TDACS"]=tdac; + m_parameters["FDACS"]=fdac; + m_initialized=true; + } + PixelRegister::Field PixelRegister::lookupParameter(const char* name){ + // check if this is the last name used, return cached value + if(std::string(name)==m_cachedName)return m_cachedField; + // Now check if we can translate the name to a field name + if(m_parameters.find(name)!=m_parameters.end()){ + //cache result + m_cachedName=name; + m_cachedField=m_parameters[name]; + return m_cachedField; + }else return not_found; + } +} diff --git a/rce/rcecalib/config/FEI3/PixelRegister.hh b/rce/rcecalib/config/FEI3/PixelRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..9ca1211094ee37cb42b50878cc950848c29a1664 --- /dev/null +++ b/rce/rcecalib/config/FEI3/PixelRegister.hh @@ -0,0 +1,56 @@ +#ifndef PIXEL_REGISTER_FEI3_HH +#define PIXEL_REGISTER_FEI3_HH + +#include <string> +#include <map> + + +namespace FEI3{ + + static const unsigned fieldPos[]={0,1,2,3,10,13}; + static const unsigned fieldMask[]={1,1,1,0x7f,0x7,1}; + + class PixelRegister{ + public: + enum Field{hitbus, select, enable, tdac, fdac, kill, Nfields, not_found}; + PixelRegister(): m_register(0){ + if(!m_initialized)initialize(); + } + unsigned getBit(unsigned i){ + return (m_register>>i)&0x1; + } + void setBit(unsigned i, bool val){ + if(val){ + m_register|=(1<<i); + } else{ + m_register&=~(1<<i); + } + } + void setField(Field f, unsigned val){ + m_register&=~(fieldMask[f]<<fieldPos[f]); //clear + m_register|=(fieldMask[f]&val)<<fieldPos[f]; //set + } + unsigned getField(Field f){ + return (m_register>>fieldPos[f])&fieldMask[f]; + } + unsigned short get(){ + return m_register; + } + void set(unsigned short val){ + m_register=val; + } + + static Field lookupParameter(const char* name); + + private: + unsigned short m_register; + static std::string m_cachedName; + static Field m_cachedField; + static std::map<std::string, Field> m_parameters; + static bool m_initialized; + static void initialize(); + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI3/RegularMaskStaging.cc b/rce/rcecalib/config/FEI3/RegularMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..d648c7fc4879ddaa162e765ef5183ab39d4c7860 --- /dev/null +++ b/rce/rcecalib/config/FEI3/RegularMaskStaging.cc @@ -0,0 +1,34 @@ +#include "rcecalib/config/FEI3/RegularMaskStaging.hh" +#include "rcecalib/config/FEI3/Module.hh" + +namespace FEI3{ + + RegularMaskStaging::RegularMaskStaging(FEI3::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI3::Module>(mod, masks, type){ + m_nStages=strtoul(type.substr(6).c_str(),0,10); + } + + void RegularMaskStaging::setupMaskStageHW(int maskStage){ + if(maskStage==0){ + clearBitsHW(); + for (int i=0;i<Module::N_FRONTENDS;i++){ + int nPixelsPerChip = Frontend::N_ROWS * Frontend::N_COLS; + for(int index=maskStage;index<nPixelsPerChip;index+=m_nStages){ + int row = (int) index % Frontend::N_ROWS; + int col = (int) index / Frontend::N_ROWS; + if( col%2 ) row = 159 - row; + PixelRegister *pixel=m_module->frontend(i)->getPixelRegister(col,row); + pixel->set(pixel->get() | m_masks.iMask); + } + } + m_module->configureHW(); + }else{ + m_module->resetHW(false); // only reset MCC, not FE + m_module->mcc()->configureHW(); + //std::cout<<"Shifting enables"<<std::endl; + for (int i=0;i<Module::N_FRONTENDS;i++){ + m_module->frontend(i)->shiftEnablesHW(m_masks.iMask); + } + } + } +} diff --git a/rce/rcecalib/config/FEI3/RegularMaskStaging.hh b/rce/rcecalib/config/FEI3/RegularMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..ba6d4a5aae41e8e76a62a3bd0cb192052b8e6c76 --- /dev/null +++ b/rce/rcecalib/config/FEI3/RegularMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef FEI3REGULARMASKSTAGING_HH +#define FEI3REGULARMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI3{ + class Module; + + class RegularMaskStaging: public MaskStaging<FEI3::Module>{ + public: + RegularMaskStaging(FEI3::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.cc b/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.cc new file mode 100644 index 0000000000000000000000000000000000000000..6c4b360cb82c9b237e03ff6e57984b5283763fd2 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.cc @@ -0,0 +1,43 @@ +#include "rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + AnalogColpr2MaskStagingFei4a::AnalogColpr2MaskStagingFei4a(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + if(type=="FEI4_COLPR2x6")m_nStages=6; + else m_nStages=1; + } + + void AnalogColpr2MaskStagingFei4a::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + const int nColStages=14; + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned dcolStage=maskStage%nColStages; + unsigned stage=maskStage/nColStages; + if((maskStage+nColStages)/nColStages!=(maskStage+nColStages-1)/nColStages){ //need to set up pixel mask + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStage(i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, 0, 0); + } + } + } + // stage 0-5: colpr_mode=2, colpr_addr= 1, 2, 3, 4, 5, 6 + // stage 6-9: colpr_mode=0, colpr_addr= 8, 16, 24, 32 + // stage 10-13: colpr_mode=0, colpr_addr= 7, 15, 23, 31 + if(dcolStage<6){ + global->setField("Colpr_Mode", 2, GlobalRegister::SW); + global->setField("Colpr_Addr", dcolStage+1, GlobalRegister::HW); + }else { + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + int addr= dcolStage<10? (dcolStage-6)*8+8 : (dcolStage-10)*8+7; + global->setField("Colpr_Addr", addr , GlobalRegister::HW); + } + } +} diff --git a/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.hh b/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.hh new file mode 100644 index 0000000000000000000000000000000000000000..a5fa001ab57cb76415e2bb7b75167519606f3792 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.hh @@ -0,0 +1,20 @@ +#ifndef FEI4ANALOGCOLPR2MASKSTAGINGFEI4A_HH +#define FEI4ANALOGCOLPR2MASKSTAGINGFEI4A_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class AnalogColpr2MaskStagingFei4a: public MaskStaging<FEI4::Module>{ + public: + AnalogColpr2MaskStagingFei4a(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.cc b/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..f23e25a36ddf6fae763cfd04c0f20b3fd85d7c58 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.cc @@ -0,0 +1,51 @@ +#include "rcecalib/config/FEI4/AnalogColprMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + AnalogColprMaskStaging::AnalogColprMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type), m_oldDcolStage(-1){ + m_nStages=strtoul(type.substr(12).c_str(),0,10); + m_colpr_mode=strtoul(type.substr(10,1).c_str(),0,10); + if(m_colpr_mode==0)m_nColStages=40; + else if(m_colpr_mode==1)m_nColStages=4; + else if(m_colpr_mode==2)m_nColStages=8; + else m_nColStages=1; + std::cout<<"Set up COLPR mask staging with "<<m_nColStages<<" col stages and "<< m_nStages<<" row stages"<<std::endl; + } + + void AnalogColprMaskStaging::setupMaskStageHW(int maskStage){ + int dcolStage=maskStage/m_nStages; + unsigned stage=maskStage%m_nStages; + if(m_initialized==false || maskStage==0 || dcolStage!=m_oldDcolStage){ + clearBitsHW(); + m_initialized=true; + m_oldDcolStage=dcolStage; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + global->setField("Colpr_Mode", m_colpr_mode, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStageCol(dcolStage*2+1, i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolStage, dcolStage); + int seconddcol=dcolStage-1<0? m_nColStages-1 : dcolStage-1; + pixel->setupMaskStageCol(seconddcol*2+2, i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, seconddcol, seconddcol); + if(dcolStage==0 || dcolStage==m_nColStages-1){ + if(dcolStage==0){ + pixel->setBitCol(80, i, 0); + }else{ + pixel->setupMaskStageCol(79, i, stage, m_nStages); + pixel->setupMaskStageCol(80, i, stage, m_nStages); + } + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + m_module->writeDoubleColumnHW(i, i, 39, 39); + global->setField("Colpr_Mode", m_colpr_mode, GlobalRegister::SW); + } + } + } + global->setField("Colpr_Mode", m_colpr_mode, GlobalRegister::SW); + global->setField("Colpr_Addr", dcolStage, GlobalRegister::HW); + } +} diff --git a/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.hh b/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..e8074e63223f3bec2f1c357557ca9b6b97a01cf4 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogColprMaskStaging.hh @@ -0,0 +1,23 @@ +#ifndef FEI4ANALOGCOLPRMASKSTAGING_HH +#define FEI4ANALOGCOLPRMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class AnalogColprMaskStaging: public MaskStaging<FEI4::Module>{ + public: + AnalogColprMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + int m_nColStages; + int m_colpr_mode; + int m_oldDcolStage; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/AnalogMaskStaging.cc b/rce/rcecalib/config/FEI4/AnalogMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..c03faa9796eed7129c5d7ecd26fb23c09e5a23a7 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogMaskStaging.cc @@ -0,0 +1,36 @@ +#include "rcecalib/config/FEI4/AnalogMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + AnalogMaskStaging::AnalogMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type), m_oldDcolStage(-1){ + if(type=="FEI4_COL_ANL_40x8")m_nStages=6; + else m_nStages=3; + } + + void AnalogMaskStaging::setupMaskStageHW(int maskStage){ + int dcolStage=maskStage/m_nStages; + int stage=maskStage%m_nStages; + if(m_initialized==false || maskStage==0 || dcolStage!=m_oldDcolStage){ + clearBitsHW(); + m_initialized=true; + m_oldDcolStage=dcolStage; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStageCol(dcolStage*2+1, i, stage, m_nStages); + if(dcolStage==39)pixel->setupMaskStageCol(80, i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolStage, dcolStage); + if(dcolStage!=0){ + pixel->setupMaskStageCol(dcolStage*2, i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolStage-1, dcolStage-1); + global->setField("Colpr_Addr", dcolStage, GlobalRegister::HW); + } + } + } + } +} diff --git a/rce/rcecalib/config/FEI4/AnalogMaskStaging.hh b/rce/rcecalib/config/FEI4/AnalogMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..592a6280cfc215363ed23f64bc6af55d645acec4 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogMaskStaging.hh @@ -0,0 +1,21 @@ +#ifndef FEI4ANALOGMASKSTAGING_HH +#define FEI4ANALOGMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class AnalogMaskStaging: public MaskStaging<FEI4::Module>{ + public: + AnalogMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_oldDcolStage; + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.cc b/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..e98d254ec404a99da3b42ecd9c2260b3961a085b --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.cc @@ -0,0 +1,38 @@ +#include "rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + AnalogSimpleColprMaskStaging::AnalogSimpleColprMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=strtoul(type.substr(12).c_str(),0,10); + m_colpr_mode=strtoul(type.substr(10,1).c_str(),0,10); + if(m_colpr_mode==0)m_nColStages=40; + else if(m_colpr_mode==1)m_nColStages=4; + else if(m_colpr_mode==2)m_nColStages=8; + else m_nColStages=1; + std::cout<<"Set up COLPR mask staging with "<<m_nColStages<<" col stages and "<< m_nStages<<" row stages"<<std::endl; + } + + void AnalogSimpleColprMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned dcolStage=maskStage%m_nColStages; + unsigned stage=maskStage/m_nColStages; + if((maskStage+m_nColStages)/m_nColStages!=(maskStage+m_nColStages-1)/m_nColStages){ //need to set up pixel mask + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStage(i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, 0, 0); + } + } + } + global->setField("Colpr_Mode", m_colpr_mode, GlobalRegister::SW); + global->setField("Colpr_Addr", dcolStage+1, GlobalRegister::HW); + } +} diff --git a/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.hh b/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..244b72940994d7f46be77275b75137b1c05040cd --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.hh @@ -0,0 +1,22 @@ +#ifndef FEI4ANALOGSIMPLECOLPRMASKSTAGING_HH +#define FEI4ANALOGSIMPLECOLPRMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class AnalogSimpleColprMaskStaging: public MaskStaging<FEI4::Module>{ + public: + AnalogSimpleColprMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + int m_nColStages; + int m_colpr_mode; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.cc b/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..17ce67272b2d6a04f122283dcaa14779c8101297 --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.cc @@ -0,0 +1,19 @@ +#include "rcecalib/config/FEI4/AnalogSingleMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + AnalogSingleMaskStaging::AnalogSingleMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + } + + void AnalogSingleMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + GlobalRegister* global=m_module->global(); + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + global->setField("Colpr_Addr", maskStage, GlobalRegister::HW); + } +} diff --git a/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.hh b/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..4cfa4728c769d9ef34b01319b9545ebab5a64c5e --- /dev/null +++ b/rce/rcecalib/config/FEI4/AnalogSingleMaskStaging.hh @@ -0,0 +1,18 @@ +#ifndef FEI4ANALOGSINGLEMASKSTAGING_HH +#define FEI4ANALOGSINGLEMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class AnalogSingleMaskStaging: public MaskStaging<FEI4::Module>{ + public: + AnalogSingleMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.cc b/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..416c75e152ec1061ae1119b33596477af278b245 --- /dev/null +++ b/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.cc @@ -0,0 +1,106 @@ +#include "rcecalib/config/FEI4/CrosstalkFastMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + CrosstalkFastMaskStaging::CrosstalkFastMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=8; + } + + void CrosstalkFastMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned rowstage=maskStage%m_nStages; + unsigned dcolstage=maskStage/m_nStages; + + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + + // std::cout<<"stage = "<<maskStage<<" : dcol = "<<dcolstage<<" ; rowgroup = "<<rowstage<<std::endl; + + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + + if(m_masks.xtalk_on&(1<<i)){ + //this is for the pixel we are reading out, this should set the "enable" bit + + pixel->setupMaskStageCol(2*dcolstage+1, i, rowstage, m_nStages); //this sets bits starting in rowstage+1 + if(dcolstage==39)pixel->setupMaskStageCol(80, i, rowstage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolstage, dcolstage); + + if(dcolstage!=0){ + if(rowstage==0)pixel->setBitCol(dcolstage*2-1, i, 0); //disable previous column + pixel->setupMaskStageCol(dcolstage*2, i, rowstage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolstage-1, dcolstage-1); + if(dcolstage>1){ + if(rowstage==0)pixel->setBitCol(dcolstage*2-2, i, 0); //disable previous-previous column + m_module->writeDoubleColumnHW(i, i, dcolstage-2, dcolstage-2); + } + } + + + } + if(m_masks.xtalk_off&(1<<i)){ + //this is for the pixel we are strobing + + if(rowstage>0){ + pixel->setupMaskStageCol(2*dcolstage+1, i, rowstage-1, m_nStages); //this sets bits starting in rowstage + } + else{ + pixel->setupMaskStageCol(2*dcolstage+1, i, rowstage+m_nStages-1, m_nStages); //this sets bits starting in rowstage+m_nStages + } + //we have to set the bits for rowstage+2 by hand, since setupMaskStageCol clears the bits each time it's called + for(int krow=rowstage+2;krow<=PixelRegister::N_ROWS;krow+=m_nStages){ + pixel->setBit(i, krow, 2*dcolstage+1, 1); + } + + if(dcolstage==39){ + + if(rowstage>0){ + pixel->setupMaskStageCol(80, i, rowstage-1, m_nStages); //this sets bits starting in rowstage + } + else{ + pixel->setupMaskStageCol(80, i, rowstage+m_nStages-1, m_nStages); //this sets bits starting in rowstage+m_nStages + } + //we have to set the bits for rowstage+2 by hand, since setupMaskStageCol clears the bits each time it's called + for(int krow=rowstage+2;krow<=PixelRegister::N_ROWS;krow+=m_nStages){ + pixel->setBit(i, krow, 80, 1); + } + + } + m_module->writeDoubleColumnHW(i, i, dcolstage, dcolstage); + + if(dcolstage!=0){ + if(rowstage==0)pixel->setBitCol(dcolstage*2-1, i, 0); //disable previous column + + if(rowstage>0){ + pixel->setupMaskStageCol(2*dcolstage, i, rowstage-1, m_nStages); //this sets bits starting in rowstage + } + else{ + pixel->setupMaskStageCol(2*dcolstage, i, rowstage+m_nStages-1, m_nStages); //this sets bits starting in rowstage+m_nStages + } + + //we have to set the bits for rowstage+2 by hand, since setupMaskStageCol clears the bits each time it's called + for(int krow=rowstage+2;krow<=PixelRegister::N_ROWS;krow+=m_nStages){ + pixel->setBit(i, krow, 2*dcolstage, 1); + } + m_module->writeDoubleColumnHW(i, i, dcolstage-1, dcolstage-1); + + if(dcolstage>1){ + if(rowstage==0)pixel->setBitCol(dcolstage*2-2, i, 0); //disable previous-previous column + m_module->writeDoubleColumnHW(i, i, dcolstage-2, dcolstage-2); + } + + } + + } //end if(m_masks.xtalk_off&(1<<i)) + + } //end for-loop over pixel register bits + + global->setField("Colpr_Addr", dcolstage, GlobalRegister::HW); + + } +} diff --git a/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.hh b/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..19152410a9c4ae77360b90dfd0f6b0d7c7efd7d1 --- /dev/null +++ b/rce/rcecalib/config/FEI4/CrosstalkFastMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef CROSSTALKFASTMASKSTAGING_HH +#define CROSSTALKFASTMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + + class CrosstalkFastMaskStaging: public MaskStaging<FEI4::Module>{ + public: + CrosstalkFastMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; +}; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.cc b/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..cb8e76380d409afdbecb32d1a225e5a728142cd8 --- /dev/null +++ b/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.cc @@ -0,0 +1,44 @@ +#include "rcecalib/config/FEI4/CrosstalkMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + CrosstalkMaskStaging::CrosstalkMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=PixelRegister::N_ROWS*PixelRegister::N_COLS; + } + + void CrosstalkMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned rowstage=maskStage%PixelRegister::N_ROWS; + unsigned colstage=maskStage/PixelRegister::N_ROWS; + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.xtalk_on&(1<<i)){ + pixel->setupMaskStageCol(colstage+1, i, rowstage, PixelRegister::N_ROWS); + m_module->writeDoubleColumnHW(i, i, colstage/2, colstage/2); + } + if(m_masks.xtalk_off&(1<<i)){ + pixel->setBitCol(colstage+1, i, 0); + if(rowstage>0)pixel->setBit(i, rowstage, colstage+1, 1); + if(rowstage+1<PixelRegister::N_ROWS)pixel->setBit(i, rowstage+2, colstage+1, 1); + m_module->writeDoubleColumnHW(i, i, colstage/2, colstage/2); + } + //clear previous column + if(((m_masks.xtalk_off | m_masks.xtalk_on)&(1<<i)) && rowstage==0&&colstage!=0){ + pixel->setBitCol(colstage, i, 0); + m_module->writeDoubleColumnHW(i, i, (colstage-1)/2, (colstage-1)/2); + } + } + if(colstage!=79) { + global->setField("Colpr_Addr", (colstage+1)/2, GlobalRegister::HW); + } else { + global->setField("Colpr_Addr", 39, GlobalRegister::HW); + } + } +} diff --git a/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.hh b/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..c305cdb622cb8562614b0018be00d6d66e7a7446 --- /dev/null +++ b/rce/rcecalib/config/FEI4/CrosstalkMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef CROSSTALKMASKSTAGING_HH +#define CROSSTALKMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + + class CrosstalkMaskStaging: public MaskStaging<FEI4::Module>{ + public: + CrosstalkMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; +}; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/DiffusionMaskStaging.cc b/rce/rcecalib/config/FEI4/DiffusionMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..e020b501273a02fd2d69e3803ecb2f8c11560cf6 --- /dev/null +++ b/rce/rcecalib/config/FEI4/DiffusionMaskStaging.cc @@ -0,0 +1,28 @@ +#include "rcecalib/config/FEI4/DiffusionMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + DiffusionMaskStaging::DiffusionMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=16; + } + + void DiffusionMaskStaging::setupMaskStageHW(int maskStage){ + + // std::cout<<"diffusion stage = "<<maskStage<<std::endl; + + GlobalRegister* global=m_module->global(); + + //std::cout<<"Setting colpr_mode to 3"<<std::endl; + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + + //the "double column" for enabling strobe, which has skewed addressing + //the strobe double columns 0,1,2.....38,39 correspond to columns: + //(0),(1,2),(3,4).....(75,76),(77,78,79) + int strobeDCol = 39; //it doesn't matter what value we set this to, but we do need to set it. + global->setField("Colpr_Addr", strobeDCol, GlobalRegister::HW); + + } + +} diff --git a/rce/rcecalib/config/FEI4/DiffusionMaskStaging.hh b/rce/rcecalib/config/FEI4/DiffusionMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..b0c7f0da8b8258c8beead4f5ef8e8dc20d332ffc --- /dev/null +++ b/rce/rcecalib/config/FEI4/DiffusionMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef DIFFUSIONMASKSTAGING_HH +#define DIFFUSIONMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + + class DiffusionMaskStaging: public MaskStaging<FEI4::Module>{ + public: + DiffusionMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; +}; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/DigStepMaskStaging.cc b/rce/rcecalib/config/FEI4/DigStepMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..d1ccd2d982dc02fe81d9a44c00d8d681bcd49db3 --- /dev/null +++ b/rce/rcecalib/config/FEI4/DigStepMaskStaging.cc @@ -0,0 +1,29 @@ +#include "rcecalib/config/FEI4/DigStepMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + DigStepMaskStaging::DigStepMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=strtoul(type.substr(6).c_str(),0,10); + } + + void DigStepMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + global->setField("Colpr_Addr", 0, GlobalRegister::SW); + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStage(i, maskStage, m_nStages); + m_module->writeDoubleColumnHW(i, i, 0, 0); //stage 0 writes all bits (below) + } + } + // enable all pixels for charge injection + global->setField("Colpr_Mode", 3, GlobalRegister::HW); + } +} diff --git a/rce/rcecalib/config/FEI4/DigStepMaskStaging.hh b/rce/rcecalib/config/FEI4/DigStepMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..dcb4a02471dba5551eaae821a105869762e347f4 --- /dev/null +++ b/rce/rcecalib/config/FEI4/DigStepMaskStaging.hh @@ -0,0 +1,19 @@ +#ifndef FEI4DIGITALSTEPSMASKSTAGING_HH +#define FEI4DIGITALSTEPSMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + + class DigStepMaskStaging: public MaskStaging<FEI4::Module>{ + public: + DigStepMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; +}; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/DigitalMaskStaging.cc b/rce/rcecalib/config/FEI4/DigitalMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..2f9087ed88ac9333539c138b12fc3fc027396955 --- /dev/null +++ b/rce/rcecalib/config/FEI4/DigitalMaskStaging.cc @@ -0,0 +1,28 @@ +#include "rcecalib/config/FEI4/DigitalMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + DigitalMaskStaging::DigitalMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + } + + void DigitalMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + // Digital injection dcol by dcol + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setBitDcol(maskStage, i, 1); //enable bit in double column + pixel->setBitDcol(maskStage-1, i, 0); //disable previous column + m_module->writeDoubleColumnHW(i, i, maskStage-1, maskStage); + global->setField("Colpr_Addr", maskStage, GlobalRegister::HW); + } + } + } +} diff --git a/rce/rcecalib/config/FEI4/DigitalMaskStaging.hh b/rce/rcecalib/config/FEI4/DigitalMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..84fe445bb5034128ae5978e1555515306207c734 --- /dev/null +++ b/rce/rcecalib/config/FEI4/DigitalMaskStaging.hh @@ -0,0 +1,17 @@ +#ifndef FEI4DIGITALMASKSTAGING_HH +#define FEI4DIGITALMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + + class DigitalMaskStaging: public MaskStaging<FEI4::Module>{ + public: + DigitalMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/FECommands.cc b/rce/rcecalib/config/FEI4/FECommands.cc new file mode 100644 index 0000000000000000000000000000000000000000..aa4598fddc12b5e09ed59f64cd4b57ae6fa04ab9 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FECommands.cc @@ -0,0 +1,61 @@ + +#include "rcecalib/config/FEI4/FECommands.hh" + +namespace FEI4{ + + void FECommands::writeGlobalRegister(BitStream *bs, int reg, unsigned short value){ + unsigned cmd=0x5a0800; /* header (10110) + field2 (1000) + field3 (0010) */; + cmd|=((m_chipAddr|m_broadcasting)&0xf)<<6; // chip id + cmd|=reg&0x3f; // register address + bs->push_back(cmd); + bs->push_back(value<<16); // 16 bit register value + bs->push_back(0); // padding a la NewDsp + } + void FECommands::readGlobalRegister(BitStream *bs, int reg){ + unsigned cmd=0x5a0400; /* header (10110) + field2 (1000) + field3 (0001) */; + cmd|=((m_chipAddr|m_broadcasting)&0xf)<<6; // chip id + cmd|=reg&0x3f; // register address + bs->push_back(cmd); + bs->push_back(0); // padding a la NewDsp + } + void FECommands::globalReset(BitStream *bs){ + unsigned cmd=0x16880; + cmd|=(m_chipAddr|m_broadcasting)&0xf; + bs->push_back(cmd); + bs->push_back(0); // padding a la NewDsp + } + void FECommands::globalPulse(BitStream *bs, unsigned width) { + unsigned cmd=0x5a2400; /* header (10110) + field2 (1000) + field3 (1001) */; + cmd|=((m_chipAddr|m_broadcasting)&0xf)<<6; // chip id + cmd|=width&0x3f; // pulse width + bs->push_back(cmd); + bs->push_back(0); + } + void FECommands::switchMode(BitStream *bs, MODE m) { + unsigned cmd=0x5a2800; /* header (10110) + field2 (1000) + field3 (1010) */; + cmd|=((m_chipAddr|m_broadcasting)&0xf)<<6; // chip id + cmd|=m&0x3f; // mode (conf or run) + bs->push_back(cmd); + bs->push_back(0); + } + void FECommands::L1A(BitStream *bs){ + bs->push_back(0xE8000000); + } + void FECommands::sendECR(BitStream *bs){ + bs->push_back(0); + bs->push_back(0x00162000); /* MCC ECR command */ + bs->push_back(0); + } + void FECommands::sendBCR(BitStream *bs){ + bs->push_back(0); + bs->push_back(0x00161000); /* MCC BCR command */ + bs->push_back(0); + } + void FECommands::feWriteCommand(BitStream *bs){ + bs->push_back(0); + unsigned cmd=0x5a1000; + cmd|=((m_chipAddr|m_broadcasting)&0xf)<<6; + bs->push_back(cmd); + } + +}; diff --git a/rce/rcecalib/config/FEI4/FECommands.hh b/rce/rcecalib/config/FEI4/FECommands.hh new file mode 100644 index 0000000000000000000000000000000000000000..f6632470e8ac009e6be97a95822327b5a11e07b9 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FECommands.hh @@ -0,0 +1,35 @@ +#ifndef FECOMMANDS_FEI4_HH +#define FECOMMANDS_FEI4_HH + +#include "rcecalib/HW/BitStream.hh" + +namespace FEI4{ + + class FECommands{ + public: + enum MODE {CONF=0x7, RUN=0x38}; + enum {PULSE_WIDTH=1}; + FECommands():m_chipAddr(0), m_broadcasting(0){} + void writeGlobalRegister(BitStream* bs, int reg, unsigned short value); + void readGlobalRegister(BitStream* bs, int reg); + void globalReset(BitStream* bs); + void globalPulse(BitStream* bs, unsigned width); + void switchMode(BitStream *bs, MODE m); + void L1A(BitStream *bs); + void sendECR(BitStream *bs); + void sendBCR(BitStream *bs); + void feWriteCommand(BitStream* bs); + void setAddr(unsigned addr){m_chipAddr=addr;} + void setBroadcast(bool bc){ + if(bc)m_broadcasting=0x8; + else m_broadcasting=0; + } + bool broadcasting(){return (m_broadcasting!=0);} + private: + unsigned m_chipAddr; + unsigned m_broadcasting; + }; + +}; +#endif + diff --git a/rce/rcecalib/config/FEI4/FEI4AFormatter.cc b/rce/rcecalib/config/FEI4/FEI4AFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..74e0f4b7937bd7ba8144770893576a11a519eb52 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AFormatter.cc @@ -0,0 +1,100 @@ +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/scanctrl/RceCallback.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> + +FEI4AFormatter::FEI4AFormatter(int id): + AbsFormatter(id, "FEI4A"), m_hitDiscCnfg(0){ + char name[128], title[128]; + sprintf(name, "Mod_%d_FEI4_Errors", id); + sprintf(title, "Module %d FEI4 Errors", id); + m_errhist=new RceHisto1d<int, int>(name, title, 32, -.5, 31.5); +} +FEI4AFormatter::~FEI4AFormatter(){ + delete m_errhist; + +} +void FEI4AFormatter::configure(boost::property_tree::ptree* config){ + try{ + std::cout<<"hitdiscconfig was "<<m_hitDiscCnfg<<std::endl; + m_hitDiscCnfg=config->get<int>("HitDiscCnfg"); + std::cout<<"Setting hitdiscconfig to "<<m_hitDiscCnfg<<std::endl; + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + m_errhist->clear(); +} + +int FEI4AFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + if(buflen==0)return FEI4::FEI4ARecord::Empty; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4ARecord rec; + //bool header=false; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if (rec.isEmptyRecord()){ + //header=false; + }else if(rec.isData()){ + //if(header==false)return FEI4::FEI4ARecord::NoHeader; + //there are potentially 2 hits in one data record + if(rec.getTotBottom()<0xe || (m_hitDiscCnfg!=0 && rec.getTotBottom()==0xe)){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setToT(decodeToT(rec.getTotBottom())); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()-1); + parsedData[parsedsize++]=fr.getWord(); + } + if(rec.getTotTop()<0xe || (m_hitDiscCnfg!=0 && rec.getTotTop()==0xe)){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setToT(decodeToT(rec.getTotTop())); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()); + parsedData[parsedsize++]=fr.getWord(); + } + // std::cout<<std::hex<<rec.getHeader()<<std::endl; + }else if(rec.isDataHeader()){ + //header=true; + nL1A++; + FormattedRecord fr(FormattedRecord::HEADER); + //printf("Formatter word %x\n",rec.getValue()); + fr.setL1id((rec.getL1id()+1)&0x7f); //make l1id compatible with FEI3 where the first l1id is 1 not 0 + fr.setBxid(rec.getBxid()); + parsedData[parsedsize++]=fr.getWord(); + }else if(rec.isServiceRecord()){ + printf("Service record FE %d. Error code: %d. Count: %d \n", + getId(), rec.getErrorCode(), rec.getErrorCount()); + if(rec.getErrorCode()<32)m_errhist->fill(rec.getErrorCode(), rec.getErrorCount()); + //header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + //printf("Value record: %04x.\n",rec.getValue()); + if(m_rb)m_rb->push_back(rec.getValue()); + //header=false; + }else if(rec.isAddressRecord()){ // address record + std::cout<<"Address record for "; + if(rec.isGlobal())std::cout<<" global register "; + else std::cout<<" shift register "; + std::cout<<rec.getAddress()<<std::endl; + //if(m_rb)m_rb->push_back(rec.getAddress()); + //header=false; + }else{ + std::cout<<"FE "<<getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + return FEI4::FEI4ARecord::BadRecord; + } + bytepointer+=3; + } + return FEI4::FEI4ARecord::OK; +} + +//FEI4 encodes TOT information +int FEI4AFormatter::decodeToT(int raw){ + if(raw==0xe)return 1; + else return raw+m_hitDiscCnfg+1; +} diff --git a/rce/rcecalib/config/FEI4/FEI4AFormatter.hh b/rce/rcecalib/config/FEI4/FEI4AFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..ae3ca5d24f8cf8003543eccf8407109419c37fa6 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AFormatter.hh @@ -0,0 +1,19 @@ +#ifndef FEI4AFORMATTER_HH +#define FEI4AFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/util/RceHisto1d.cc" + +class FEI4AFormatter:public AbsFormatter{ +public: + FEI4AFormatter(int id); + virtual ~FEI4AFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); + int decodeToT(int rawTot); + +private: + int m_hitDiscCnfg; + RceHisto1d<int, int>* m_errhist; +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.cc b/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..39765a592d2c6cc570a62b56409e6aa1b9082313 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.cc @@ -0,0 +1,295 @@ + +#include "rcecalib/config/FEI4/FEI4AGlobalRegister.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/Utils.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + RegisterDef FEI4AGlobalRegister::m_def; + bool FEI4AGlobalRegister::m_initialized=false; + + FEI4AGlobalRegister::FEI4AGlobalRegister(FECommands* commands): + GlobalRegister(commands) { + m_rd=&m_def; + m_def.LOW_REG=2; + m_def.N_REG_REGS=36; + m_def.N_W_REGS=36; + m_def.N_R_REGS=43; + m_def.SRAB_BITS=288; + m_def.SRC_BITS=144; + // initialize static field dictionary + if(!m_initialized)initialize(); + //set up size parameters + + //create registers + m_regw=new unsigned short[m_def.N_W_REGS]; + m_regr=new unsigned short[m_def.N_R_REGS]; + m_srab=new unsigned short[m_def.SRAB_BITS/16]; + m_src=new unsigned short[m_def.SRC_BITS/16]; + //Clear all registers + for(int i=0;i<m_def.N_W_REGS;i++)m_regw[i]=0; + for(int i=0;i<m_def.N_R_REGS;i++)m_regr[i]=0; + for(int i=0;i<m_def.SRAB_BITS/16;i++)m_srab[i]=0; + for(int i=0;i<m_def.SRC_BITS/16;i++)m_src[i]=0; + } + FEI4AGlobalRegister::~FEI4AGlobalRegister(){ + delete [] m_regw; + delete [] m_regr; + delete [] m_srab; + delete [] m_src; + } + + void FEI4AGlobalRegister::initialize(){ + addField("TrigCnt", 2, 12, -1, -1, 4, false); + addField("Conf_AddrEnable", 2, 11, -1, -1, 1, false); + addField("Reg2Spare", 2, 0, -1, -1, 11, false); + addField("ErrMask0", 3, 0, -1, -1, 16, false); + addField("ErrMask1", 4, 0, -1, -1, 16, false); + addField("PrmpVbpRight", 5, 8, 152, -1, 8, true); + addField("Vthin", 5, 0, 144, -1, 8, true); + addField("DisVbn_CPPM", 6, 8, 168, -1, 8, true); + addField("PrmpVbp", 6, 0, 160, -1, 8, true); + addField("TdacVbp", 7, 8, 184, -1, 8, true); + addField("DisVbn", 7, 0, 176, -1, 8, true); + addField("Amp2Vbn", 8, 8, 200, -1, 8, true); + addField("Amp2VbpFol", 8,0,192, -1, 8, true); + addField("PrmpVbpTop", 9, 8, 216, -1, 8, true); + addField("Amp2Vbp", 9, 0, 208, -1, 8, true); + addField("FdacVbn", 10, 8, 232, -1, 8, true); + addField("Amp2Vbpf", 10, 0, 224, -1, 8, true); + addField("PrmpVbnFol", 11, 8, 248, -1, 8, true); + addField("PrmpVbpLeft", 11, 0, 240, -1, 8, true); + addField("PrmpVbpf", 12, 8, 264, -1, 8, true); + addField("PrmpVbnLcc", 12, 0, 256, -1, 8, true); + addField("Reg13Spare", 13, 0, -1, -1, 1, false); + addField("PxStrobes", 13, 1, 273, -1, 13, true); + addField("S0", 13, 14, 286, -1, 1, false); + addField("S1", 13, 15, 287, -1, 1, false); + addField("LVDSDrvIref", 14, 8, 8, -1, 8, true); + addField("BonnDac", 14, 0, 0, -1, 8, true); + addField("PllIbias", 15, 8, 24, -1, 8, true); + addField("LVDSDrvVos", 15, 0, 16, -1, 8, true); + addField("TempSensBias", 16, 8, 40, -1, 8, true); + addField("PllIcp", 16, 0, 32, -1, 8, true); + addField("Reg17Spare", 17, 8, 56, -1, 8, true); + addField("PlsrIdacRamp", 17, 0, 48, -1, 8, true); + addField("Reg18Spare", 18, 8, 72, -1, 8, true); + addField("PlsrVgOPamp", 18, 0, 64, -1, 8, true); + addField("PlsrDacBias", 19, 8, 88, -1, 8, true); + addField("Reg19Spare", 19, 0, 80, -1, 8, true); + addField("Vthin_AltCoarse", 20, 8, 104, -1, 8, true); + addField("Vthin_AltFine", 20, 0, 96, -1, 8, true); + addField("PlsrDAC", 21, 0, 112, -1, 10, true); + addField("DIGHITIN_Sel", 21, 10, 138, -1, 1, false); + addField("DINJ_Override", 21, 11, 139, -1, 1, false); + addField("HITLD_In", 21, 12, 140, -1, 1, false); + addField("Reg21Spare", 21, 13, -1, -1, 3, false); + addField("Reg22Spare2", 22, 0, -1, -1, 2, false); + addField("Colpr_Addr", 22, 2, 124, -1, 6, true); + addField("Colpr_Mode", 22, 8, 130, -1, 2, true); + addField("Reg22Spare1", 22, 10, -1, -1, 6, false); + addField("DisableColumnCnfg0", 23, 0, -1, 0, 16, false); + addField("DisableColumnCnfg1", 24, 0, -1, 16, 16, false); + addField("DisableColumnCnfg2", 25, 0, -1, 32, 8, false); + addField("TrigLat", 25, 8, -1, 40, 8, false); + addField("CMDcnt", 26, 3, -1, 51, 14, false); + addField("StopModeCnfg", 26, 2, -1, 50, 1, false); + addField("HitDiscCnfg", 26, 0, -1, 48, 2, false); + addField("EN_PLL", 27, 15, -1, 79, 1, false); + addField("Efuse_sense", 27, 14, -1, 78, 1, false); + addField("Stop_Clk", 27, 13, -1, 77, 1, false); + addField("ReadErrorReq", 27, 12, -1, 76, 1, false); + addField("ReadSkipped", 27, 11, -1, 75, 1, false); + addField("Reg27Spare", 27, 6, -1, -1, 5, false); + addField("GateHitOr", 27, 5, -1, 69, 1, false); + addField("CalEn", 27, 4, -1, 68, 1, false); + addField("SR_clr", 27, 3, -1, 67, 1, false); + addField("Latch_en", 27, 2, -1, 66, 1, false); + addField("SR_Clock", 27, 1, -1, 65, 1, false); + addField("LVDSDrvSet06", 28, 15, -1, 95, 1, false); + addField("Reg28Spare", 28, 10, -1, -1, 5, false); + addField("EN40M", 28, 9, -1, 89, 1, false); + addField("EN80M", 28, 8, -1, 88, 1, false); + addField("CLK1", 28, 5, -1, 85, 3, false); + addField("CLK0", 28, 2, -1, 82, 3, false); + addField("EN160M", 28, 1, -1, 81, 1, false); + addField("EN320M", 28, 0, -1, 80, 1, false); + addField("Reg29Spare1", 29, 14, -1, -1, 2, false); + addField("no8b10b", 29, 13, -1, 109, 1, false); + addField("Clk2OutCnfg", 29, 12, -1, 108, 1, false); + addField("EmptyRecord", 29, 4, -1, 100, 8, true); + addField("Reg29Spare2", 29, 3, -1, -1, 1, false); + addField("LVDSDrvEn", 29, 2, -1, 98, 1, false); + addField("LVDSDrvSet30", 29, 1, -1, 97, 1, false); + addField("LVDSDrvSet12", 29, 0, -1, 96, 1, false); + addField("PlsrRiseUpTau", 31, 13, -1, 141, 3, false); + addField("PlsrPwr", 31, 12, -1, 140, 1, false); + addField("PlsrDelay", 31, 6, -1, 134, 6, true); + addField("ExtDigCalSW", 31, 5, -1, 133, 1, false); + addField("ExtAnaCalSW", 31, 4, -1, 132, 1, false); + addField("Reg31Spare", 31, 0, -1, -1, 4, false); + addField("SELB0", 32, 0, -1, -1, 16, false); + addField("SELB1", 33, 0, -1, -1, 16, false); + addField("SELB2", 34, 8, -1, -1, 8, false); + addField("EfuseCref", 34, 0, -1, -1, 4, false); + addField("EfuseVref", 34, 4, -1, -1, 4, false); + addField("Chip_SN", 35, 0, -1, -1, 16, false); + + // alternative definitions + addField("CMDcnt_width", 26, 3, -1, 51, 8, false); + addField("CMDcnt_delay", 26, 11, -1, 59, 6, false); + addField("ERRORMASK", 3, 0, -1, -1, 32, false); + addField("DisableColumnCnfg01", 23, 0, -1, 0, 32, false); + addField("SELB01", 32, 0, -1, -1, 32, false); + addField("CLK0_S2", 28, 2, -1, 82, 1, false); + addField("CLK0_S1", 28, 3, -1, 83, 1, false); + addField("CLK0_S0", 28, 4, -1, 84, 1, false); + addField("CLK1_S2", 28, 5, -1, 85, 1, false); + addField("CLK1_S1", 28, 6, -1, 86, 1, false); + addField("CLK1_S0", 28, 7, -1, 87, 1, false); + + + // Translation from scan parameter to Global register field + addParameter("LATENCY", "TrigLat"); + addParameter("GDAC", "Vthin_AltFine"); + addParameter("GDAC_COARSE", "Vthin_AltCoarse"); + addParameter("VCAL", "PlsrDAC"); + addParameter("STROBE_DELAY", "PlsrDelay"); + addParameter("IF", "PrmpVbpf"); + + //Translation from CLKx_S012 parameter to transmission rate + m_def.m_rate[0]=SerialIF::M40; + m_def.m_rate[4]=SerialIF::M320; + m_def.m_rate[2]=SerialIF::M40; + m_def.m_rate[6]=SerialIF::M320; + m_def.m_rate[1]=SerialIF::M160; + m_def.m_rate[5]=SerialIF::M80; + m_def.m_rate[3]=SerialIF::M40; + m_def.m_rate[7]=SerialIF::M160; //Aux clk + + m_def.m_params8b10b=m_def.m_fields["no8b10b"]; + m_def.m_paramsDrate=m_def.m_fields["CLK0"]; + m_def.m_colpr_reg=m_def.m_fields["Colpr_Addr"].reg; + m_def.m_colpr_disable=5<<2; + + m_initialized=true; + } + void FEI4AGlobalRegister::printFields(std::ostream &os){ + os<<"Global Register Fields"<<std::endl; + os<<"======================"<<std::endl; + os<<"TrigCnt "<<getField("TrigCnt")<<std::endl; + os<<"Conf_AddrEnable "<<getField("Conf_AddrEnable")<<std::endl; + os<<"Reg2Spare "<<getField("Reg2Spare")<<std::endl; + os<<"ErrMask0 "<<getField("ErrMask0")<<std::endl; + os<<"ErrMask1 "<<getField("ErrMask1")<<std::endl; + os<<"PrmpVbpRight "<<getField("PrmpVbpRight")<<std::endl; + os<<"Vthin "<<getField("Vthin")<<std::endl; + os<<"DisVbn_CPPM "<<getField("DisVbn_CPPM")<<std::endl; + os<<"PrmpVbp "<<getField("PrmpVbp")<<std::endl; + os<<"TdacVbp "<<getField("TdacVbp")<<std::endl; + os<<"DisVbn "<<getField("DisVbn")<<std::endl; + os<<"Amp2Vbn "<<getField("Amp2Vbn")<<std::endl; + os<<"Amp2VbpFol "<<getField("Amp2VbpFol")<<std::endl; + os<<"PrmpVbpTop "<<getField("PrmpVbpTop")<<std::endl; + os<<"Amp2Vbp "<<getField("Amp2Vbp")<<std::endl; + os<<"FdacVbn "<<getField("FdacVbn")<<std::endl; + os<<"Amp2Vbpf "<<getField("Amp2Vbpf")<<std::endl; + os<<"PrmpVbnFol "<<getField("PrmpVbnFol")<<std::endl; + os<<"PrmpVbpLeft "<<getField("PrmpVbpLeft")<<std::endl; + os<<"PrmpVbpf "<<getField("PrmpVbpf")<<std::endl; + os<<"PrmpVbnLcc "<<getField("PrmpVbnLcc")<<std::endl; + os<<"Reg13Spare "<<getField("Reg13Spare")<<std::endl; + os<<"PxStrobes "<<getField("PxStrobes")<<std::endl; + os<<"S0 "<<getField("S0")<<std::endl; + os<<"S1 "<<getField("S1")<<std::endl; + os<<"LVDSDrvIref "<<getField("LVDSDrvIref")<<std::endl; + os<<"BonnDac "<<getField("BonnDac")<<std::endl; + os<<"PllIbias "<<getField("PllIbias")<<std::endl; + os<<"LVDSDrvVos "<<getField("LVDSDrvVos")<<std::endl; + os<<"TempSensBias "<<getField("TempSensBias")<<std::endl; + os<<"PllIcp "<<getField("PllIcp")<<std::endl; + os<<"Reg17Spare "<<getField("Reg17Spare")<<std::endl; + os<<"PlsrIdacRamp "<<getField("PlsrIdacRamp")<<std::endl; + os<<"Reg18Spare "<<getField("Reg18Spare")<<std::endl; + os<<"PlsrVgOPamp "<<getField("PlsrVgOPamp")<<std::endl; + os<<"PlsrDacBias "<<getField("PlsrDacBias")<<std::endl; + os<<"Reg19Spare "<<getField("Reg19Spare")<<std::endl; + os<<"Vthin_AltCoarse "<<getField("Vthin_AltCoarse")<<std::endl; + os<<"Vthin_AltFine "<<getField("Vthin_AltFine")<<std::endl; + os<<"PlsrDAC "<<getField("PlsrDAC")<<std::endl; + os<<"DIGHITIN_Sel "<<getField("DIGHITIN_Sel")<<std::endl; + os<<"DINJ_Override "<<getField("DINJ_Override")<<std::endl; + os<<"HITLD_In "<<getField("HITLD_In")<<std::endl; + os<<"Reg21Spare "<<getField("Reg21Spare")<<std::endl; + os<<"Reg22Spare2 "<<getField("Reg22Spare2")<<std::endl; + os<<"Colpr_Addr "<<getField("Colpr_Addr")<<std::endl; + os<<"Colpr_Mode "<<getField("Colpr_Mode")<<std::endl; + os<<"Reg22Spare1 "<<getField("Reg22Spare1")<<std::endl; + os<<"DisableColumnCnfg0 "<<getField("DisableColumnCnfg0")<<std::endl; + os<<"DisableColumnCnfg1 "<<getField("DisableColumnCnfg1")<<std::endl; + os<<"DisableColumnCnfg2 "<<getField("DisableColumnCnfg2")<<std::endl; + os<<"TrigLat "<<getField("TrigLat")<<std::endl; + os<<"StopModeCnfg "<<getField("StopModeCnfg")<<std::endl; + os<<"HitDiscCnfg "<<getField("HitDiscCnfg")<<std::endl; + os<<"CMDcnt12 "<<getField("CMDcnt12")<<std::endl; + os<<"EN_PLL "<<getField("EN_PLL")<<std::endl; + os<<"Efuse_sense "<<getField("Efuse_sense")<<std::endl; + os<<"Stop_Clk "<<getField("Stop_Clk")<<std::endl; + os<<"ReadErrorReq "<<getField("ReadErrorReq")<<std::endl; + os<<"ReadSkipped "<<getField("ReadSkipped")<<std::endl; + os<<"Reg27Spare "<<getField("Reg27Spare")<<std::endl; + os<<"GateHitOr "<<getField("GateHitOr")<<std::endl; + os<<"CalEn "<<getField("CalEn")<<std::endl; + os<<"SR_clr "<<getField("SR_clr")<<std::endl; + os<<"Latch_en "<<getField("Latch_en")<<std::endl; + os<<"SR_Clock "<<getField("SR_Clock")<<std::endl; + os<<"LVDSDrvSet06 "<<getField("LVDSDrvSet06")<<std::endl; + os<<"Reg28Spare "<<getField("Reg28Spare")<<std::endl; + os<<"EN40M "<<getField("EN40M")<<std::endl; + os<<"EN80M "<<getField("EN80M")<<std::endl; + os<<"CLK1 "<<getField("CLK1")<<std::endl; + os<<"CLK0 "<<getField("CLK0")<<std::endl; + os<<"EN160M "<<getField("EN160M")<<std::endl; + os<<"EN320M "<<getField("EN320M")<<std::endl; + os<<"Reg29Spare1 "<<getField("Reg29Spare1")<<std::endl; + os<<"no8b10b "<<getField("no8b10b")<<std::endl; + os<<"Clk2OutCnfg "<<getField("Clk2OutCnfg")<<std::endl; + os<<"EmptyRecord "<<getField("EmptyRecord")<<std::endl; + os<<"Reg29Spare2 "<<getField("Reg29Spare2")<<std::endl; + os<<"LVDSDrvEn "<<getField("LVDSDrvEn")<<std::endl; + os<<"LVDSDrvSet30 "<<getField("LVDSDrvSet30")<<std::endl; + os<<"LVDSDrvSet12 "<<getField("LVDSDrvSet12")<<std::endl; + os<<"PlsrRiseUpTau "<<getField("PlsrRiseUpTau")<<std::endl; + os<<"PlsrPwr "<<getField("PlsrPwr")<<std::endl; + os<<"PlsrDelay "<<getField("PlsrDelay")<<std::endl; + os<<"ExtDigCalSW "<<getField("ExtDigCalSW")<<std::endl; + os<<"ExtAnaCalSW "<<getField("ExtAnaCalSW")<<std::endl; + os<<"Reg31Spare "<<getField("Reg31Spare")<<std::endl; + os<<"SELB0 "<<getField("SELB0")<<std::endl; + os<<"SELB1 "<<getField("SELB1")<<std::endl; + os<<"SELB2 "<<getField("SELB2")<<std::endl; + os<<"Efuse_Cref "<<getField("Efuse_Cref")<<std::endl; + os<<"Efuse_Vref "<<getField("Efuse_Vref")<<std::endl; + os<<"Chip_SN "<<getField("Chip_SN")<<std::endl; + + os<<"Alternative Field definitions:"<<std::endl; + // alternative definitions + os<<"CMDcnt_width "<<getField("CMDcnt_width")<<std::endl; + os<<"CMDcnt_delay "<<getField("CMDcnt_delay")<<std::endl; + os<<"ERRORMASK "<<getField("ERRORMASK")<<std::endl; + os<<"DisableColumnCnfg01 "<<getField("DisableColumnCnfg01")<<std::endl; + os<<"SELB01 "<<getField("SELB01")<<std::endl; + os<<"CLK0_S2 "<<getField("CLK0_S2")<<std::endl; + os<<"CLK0_S1 "<<getField("CLK0_S1")<<std::endl; + os<<"CLK0_S0 "<<getField("CLK0_S0")<<std::endl; + os<<"CLK1_S2 "<<getField("CLK1_S2")<<std::endl; + os<<"CLK1_S1 "<<getField("CLK1_S1")<<std::endl; + os<<"CLK1_S0 "<<getField("CLK1_S0")<<std::endl; + } + +}; diff --git a/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.hh b/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..115142d3e635c5ad0a447300c7ffe77510366aeb --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AGlobalRegister.hh @@ -0,0 +1,31 @@ +#ifndef FEI4AGLOBALREGISTER_FEI4_HH +#define FEI4AGLOBALREGISTER_FEI4_HH + +#include <map> +#include <string> +#include <vector> +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/config/FEI4/GlobalRegister.hh" + + +namespace FEI4{ + +class FECommands; + + class FEI4AGlobalRegister: public GlobalRegister{ + public: + FEI4AGlobalRegister(FECommands* commands); + virtual ~FEI4AGlobalRegister(); + void printFields(std::ostream &os); + private: + void initialize(); + static RegisterDef m_def; + static bool m_initialized; + RegisterDef* getDef(){return &m_def;} + + + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4AModule.cc b/rce/rcecalib/config/FEI4/FEI4AModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..6b74f7ed725bc8f05cb6e419a7d8f264cc9b810c --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AModule.cc @@ -0,0 +1,107 @@ +#include "rcecalib/config/FEI4/FEI4AModule.hh" +#include "rcecalib/config/FEI4/FEI4AGlobalRegister.hh" +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/VerifyErrors.hh" +#include <iostream> +#include <fstream> +#include "ers/ers.h" +#include <stdio.h> + +namespace FEI4{ + + + FEI4AModule::FEI4AModule(const char* name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"Module"<<std::endl; + m_commands=new FECommands; + m_global=new FEI4AGlobalRegister(m_commands); + m_pixel=new PixelRegister(m_commands); + m_pixel_readback=new PixelRegister(m_commands); + } + FEI4AModule::~FEI4AModule(){ + delete m_global; + delete m_pixel; + delete m_pixel_readback; + delete m_commands; + //m_timer.Print("Module"); + } + void FEI4AModule::setupGlobalPulseHW(int pulsereg){ + m_global->setField("Efuse_sense",(pulsereg&GlobalRegister::Efuse_sense)!=0, GlobalRegister::SW); + m_global->setField("Stop_Clk",(pulsereg&GlobalRegister::Stop_Clk)!=0, GlobalRegister::SW); + m_global->setField("ReadErrorReq",(pulsereg&GlobalRegister::ReadErrorReq)!=0, GlobalRegister::SW); + m_global->setField("ReadSkipped",(pulsereg&GlobalRegister::ReadSkipped)!=0, GlobalRegister::SW); + m_global->setField("CalEn",(pulsereg&GlobalRegister::CalEn)!=0, GlobalRegister::SW); + m_global->setField("SR_clr",(pulsereg&GlobalRegister::SR_clr)!=0, GlobalRegister::SW); + m_global->setField("Latch_en",(pulsereg&GlobalRegister::Latch_en)!=0, GlobalRegister::SW); + m_global->setField("SR_Clock",(pulsereg&GlobalRegister::SR_Clock)!=0, GlobalRegister::HW); //do one HW write for all fields + } + + // void Frontend::pixelUsrToRaw(BitStream *bs, unsigned bit){ + // } + + void FEI4AModule::resetHW(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + m_commands->globalReset(bs); + SerialIF::send(bs); + delete bs; + } + + + int FEI4AModule::verifyModuleConfigHW(){ + int retval=0; + SerialIF::setChannelInMask(1<<m_inLink); + SerialIF::setChannelOutMask(1<<m_outLink); + std::vector <unsigned> readback; + if(m_formatter){ + // global register + m_formatter->setReadbackPointer(&readback); + std::cout<<"***FE "<<m_id<<"***"<<std::endl; + retval=m_global->verifyConfigHW(readback); + /* + // pixel registers + m_global->setField("Colpr_Mode", 0, GlobalRegister::SW); // only write to 1 column pair + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + int ngoodcol=13; + const int goodcol[]={0,1,2,30,31,32,33,34,35,36,37,38,39}; + for (int dcoli=0;dcoli<ngoodcol;dcoli++){ + int dcol=goodcol[dcoli]; + for (int bit=PixelRegister::N_PIXEL_REGISTER_BITS-1;bit>=0;bit--){ + m_global->setField("Colpr_Addr", dcol, GlobalRegister::HW); + if(bit!=PixelRegister::N_PIXEL_REGISTER_BITS-1){//shift register is last latch bit + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + } + setupS0S1HitldHW(0, 0, 0); + retval|=m_pixel->verifyDoubleColumnHW(bit, dcol, readback); //check double column + } + } + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + delete bs; + */ + m_formatter->setReadbackPointer(0); + }else{ + retval=ModuleVerify::NO_FORMATTER; + } + return retval; + } + + + void FEI4AModule::destroy(){ + delete this; + } + + +}; + diff --git a/rce/rcecalib/config/FEI4/FEI4AModule.hh b/rce/rcecalib/config/FEI4/FEI4AModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..e2025bc0f32aac2769d1795471dae6ff0a9ada81 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4AModule.hh @@ -0,0 +1,25 @@ +#ifndef FEI4__FEI4AMODULE_HH +#define FEI4__FEI4AMODULE_HH + +#include "rcecalib/config/FEI4/Module.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/profiler/Profiler.hh" +#include <string> + +class AbsFormatter; + +namespace FEI4{ + + class FEI4AModule: public Module{ + public: + FEI4AModule(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter *fmt); + virtual ~FEI4AModule(); + void resetHW(); + int verifyModuleConfigHW(); + virtual void destroy(); + void setupGlobalPulseHW(int pulsereg); + +}; + +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4ARecord.hh b/rce/rcecalib/config/FEI4/FEI4ARecord.hh new file mode 100644 index 0000000000000000000000000000000000000000..67eabacfe974370fd8eeda97337eef4c2c87d51c --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4ARecord.hh @@ -0,0 +1,246 @@ +#ifndef FEI4RECORD_HH +#define FEI4RECORD_HH + +#include "rcecalib/config/Endianness.hh" +namespace FEI4{ + + +namespace Size +{ + enum Size + { + UNUSED = 8, + HEADER = 8, + RTYPE = 1, + ADDR = 15, + VALUE = 16, + ERRCODE = 6, + ERRCOUNT = 10, + REMAINDER = 16, + FLAG = 1, + LV1ID = 7, + BXID = 8, + COL = 7, + ROW = 9, + TOT = 4 + }; +} +namespace Key +{ + enum Key + { + ADDR = 0xea, + VALUE = 0xec, + SERVICE = 0xef, + HEADER = 0xe9, + EMPTY = 0x0, + GLOBAL = 0, + SHIFT = 1 + }; +} +/* ---------------------------------------------------------------------- */ + + struct Generic + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int remainder: Size::REMAINDER; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int remainder: Size:: REMAINDER; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + struct Address + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int rtype: Size:: RTYPE; + unsigned int address: Size::ADDR; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int address: Size::ADDR; + unsigned int rtype: Size:: RTYPE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct Value + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int value: Size::VALUE; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int value: Size::VALUE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else +#error ENDIANNESS is not defined +#endif + }; + + struct Service + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int errcode: Size::ERRCODE; + unsigned int errcount: Size::ERRCOUNT; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int errcount: Size::ERRCOUNT; + unsigned int errcode: Size::ERRCODE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct DataHeader + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int flag: Size::FLAG; + unsigned int lv1id: Size::LV1ID; + unsigned int bxid: Size::BXID; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int bxid: Size::BXID; + unsigned int lv1id: Size::LV1ID; + unsigned int flag: Size::FLAG; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct Data + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int col: Size::COL; + unsigned int row: Size::ROW; + unsigned int totbottom: Size::TOT; + unsigned int tottop: Size::TOT; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int tottop: Size::TOT; + unsigned int totbottom: Size::TOT; + unsigned int row: Size::ROW; + unsigned int col: Size::COL; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + + union Record + { + unsigned int ui; + Generic ge; + Address ad; + Value va; + Service se; + DataHeader he; + Data da; + }; + + + class FEI4ARecord{ + public: + enum Status + { + OK = 0, /*!< Clean finish */ + Empty = 1, /*!< Buffer does not contain any record */ + NotGlobal = 2, /*!< Address record is not a global register record */ + WrongAddress = 3, /*!< Address record does not contain the expected address */ + BadAddrValSeq = 4, /*!< Address record not immediately followed by value record */ + NoValue = 5, /*!< Value record missing. */ + NotShift = 6, /*!< Address record is not a shift register record */ + OddNwords = 7, /*!< Odd number of 16 bit words in shift register readback */ + NoHeader = 8, /*!< Data word without a previous header word*/ + BadRecord = 9 /*!< Unknown record type */ + }; + + bool isAddressRecord(){return m_record.ge.header==Key::ADDR;} + bool isValueRecord(){return m_record.ge.header==Key::VALUE;} + bool isServiceRecord(){return m_record.ge.header==Key::SERVICE;} + bool isEmptyRecord(){return m_record.ge.header==Key::EMPTY;} + bool isDataHeader(){return m_record.ge.header==Key::HEADER;} + bool isData(){return (m_record.ge.header&0xc0)!=0xc0;} + unsigned getHeader(){return m_record.ge.header;} + unsigned getAddress(){return m_record.ad.address;} + unsigned getRegisterType(){return m_record.ad.rtype;} + unsigned isGlobal(){return m_record.ad.rtype==Key::GLOBAL;} + unsigned isShift(){return m_record.ad.rtype==Key::SHIFT;} + unsigned getValue(){return m_record.va.value;} + unsigned getUnsigned(){return m_record.ui;} + unsigned getColumn(){return m_record.da.col;} + unsigned getL1id(){return m_record.he.lv1id;} + unsigned getBxid(){return m_record.he.bxid;} + unsigned getRow(){return m_record.da.row;} + unsigned getTotTop(){return m_record.da.tottop;} + unsigned getTotBottom(){return m_record.da.totbottom;} + unsigned getErrorCode(){return m_record.se.errcode;} + unsigned getErrorCount(){return m_record.se.errcount;} +#if ENDIANNESS_IS_BIG + void setRecord(const unsigned char* bytepointer){ + unsigned char* rec=(unsigned char*)&m_record; + rec[1]=*bytepointer; + rec[2]=*(bytepointer+1); + rec[3]=*(bytepointer+2); + } +#elif ENDIANNESS_IS_LITTLE + void setRecord(const unsigned char* bytepointer){ + unsigned char* rec=(unsigned char*)&m_record; + rec[2]=*bytepointer; + rec[1]=*(bytepointer+1); + rec[0]=*(bytepointer+2); + } +#else +#error ENDIANNESS is not defined +#endif + + private: + Record m_record; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4BFormatter.cc b/rce/rcecalib/config/FEI4/FEI4BFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..3b759c625769295272a98a2aa451e42126d7285f --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BFormatter.cc @@ -0,0 +1,117 @@ +#include "rcecalib/config/FEI4/FEI4BFormatter.hh" +#include "rcecalib/config/FEI4/FEI4BRecord.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/scanctrl/RceCallback.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> + +FEI4BFormatter::FEI4BFormatter(int id): + AbsFormatter(id, "FEI4B"), m_hitDiscCnfg(0), m_sr_bcid(0), m_sr_l1id(0){ + char name[128], title[128]; + sprintf(name, "Mod_%d_FEI4_Errors", id); + sprintf(title, "Module %d FEI4 Errors", id); + m_errhist=new RceHisto1d<int, int>(name, title, 32, -.5, 31.5); +} +FEI4BFormatter::~FEI4BFormatter(){ + delete m_errhist; + +} +void FEI4BFormatter::configure(boost::property_tree::ptree* config){ + m_sr_bcid=0; + m_sr_l1id=0; + try{ + std::cout<<"hitdiscconfig was "<<m_hitDiscCnfg<<std::endl; + m_hitDiscCnfg=config->get<int>("HitDiscCnfg"); + std::cout<<"Setting hitdiscconfig to "<<m_hitDiscCnfg<<std::endl; + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + m_errhist->clear(); +} + +int FEI4BFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + if(buflen==0)return FEI4::FEI4BRecord::Empty; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4BRecord rec; + bool header=false; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if (rec.isEmptyRecord()){ + //header=false; + }else if(rec.isData()){ + //if(header==false)return FEI4::FEI4BRecord::NoHeader; + //there are potentially 2 hits in one data record + if(rec.getTotBottom()<0xe || (m_hitDiscCnfg!=0 && rec.getTotBottom()==0xe)){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setToT(decodeToT(rec.getTotBottom())); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()-1); + parsedData[parsedsize++]=fr.getWord(); + } + if(rec.getTotTop()<0xe || (m_hitDiscCnfg!=0 && rec.getTotTop()==0xe)){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setToT(decodeToT(rec.getTotTop())); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()); + parsedData[parsedsize++]=fr.getWord(); + } + // std::cout<<std::hex<<rec.getHeader()<<std::endl; + }else if(rec.isDataHeader()){ + header=true; + nL1A++; + FormattedRecord fr(FormattedRecord::HEADER); + //printf("Formatter word %x\n",rec.getValue()); + fr.setL1id(((rec.getL1id()|(m_sr_l1id<<5))+1)&0xfff); //make l1id compatible with FEI3 where the first l1id is 1 not 0 + fr.setBxid(rec.getBxid()|(m_sr_bcid<<10)); + m_bxidraw=rec.getBxid(); + m_l1idraw=rec.getL1id(); + //std::cout<<"Raw: "<<rec.getL1id()<<" "<<rec.getBxid()<<std::endl; + //std::cout<<"For: "<<fr.getL1id()<<" "<<fr.getBxid()<<std::endl; + parsedData[parsedsize++]=fr.getWord(); + }else if(rec.isServiceRecord()){ + if(rec.getErrorCode()==14){//BCID & L1ID + m_sr_l1id=rec.getErrorCount()>>3; + m_sr_bcid=rec.getErrorCount()&0x7; + //Update current header + if(header==false)std::cout<<"Service record without header"<<std::endl; + else{ + FormattedRecord fr(parsedData[parsedsize-1]); + fr.setL1id(((m_l1idraw|(m_sr_l1id<<5))+1)&0xfff); //make l1id compatible with FEI3 where the first l1id is 1 not 0 + fr.setBxid(m_bxidraw|(m_sr_bcid<<10)); + //std::cout<<"Updated For: "<<fr.getL1id()<<" "<<fr.getBxid()<<std::endl; + } + } + if(rec.getErrorCode()!=14)printf("Service record FE %d. Error code: %d. Count: %d \n", + getId(), rec.getErrorCode(), rec.getErrorCount()); + if(rec.getErrorCode()<32)m_errhist->fill(rec.getErrorCode(), rec.getErrorCount()); + }else if(rec.isValueRecord()){ //val rec without addr rec + //printf("Value record: %04x.\n",rec.getValue()); + if(m_rb)m_rb->push_back(rec.getValue()); + //header=false; + }else if(rec.isAddressRecord()){ // address record + //std::cout<<"Address record for "; + //if(rec.isGlobal())std::cout<<" global register "; + //else std::cout<<" shift register "; + //std::cout<<rec.getAddress()<<std::endl; + //if(m_rb)m_rb->push_back(rec.getAddress()); + //header=false; + }else{ + std::cout<<"FE "<<getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + return FEI4::FEI4BRecord::BadRecord; + } + bytepointer+=3; + } + return FEI4::FEI4BRecord::OK; +} + +//FEI4 encodes TOT information +int FEI4BFormatter::decodeToT(int raw){ + if(raw==0xe)return 1; + else return raw+m_hitDiscCnfg+1; +} diff --git a/rce/rcecalib/config/FEI4/FEI4BFormatter.hh b/rce/rcecalib/config/FEI4/FEI4BFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..afe75cccd60e05b44692f3daeb906e13997b7ffc --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BFormatter.hh @@ -0,0 +1,23 @@ +#ifndef FEI4BFORMATTER_HH +#define FEI4BFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/util/RceHisto1d.cc" + +class FEI4BFormatter:public AbsFormatter{ +public: + FEI4BFormatter(int id); + virtual ~FEI4BFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); + int decodeToT(int rawTot); + +private: + int m_hitDiscCnfg; + RceHisto1d<int, int>* m_errhist; + unsigned m_sr_bcid; + unsigned m_sr_l1id; + unsigned m_bxidraw; + unsigned m_l1idraw; +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.cc b/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..904d8b30e1aab1790cfa27820ea5af67be4f089b --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.cc @@ -0,0 +1,300 @@ + +#include "rcecalib/config/FEI4/FEI4BGlobalRegister.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/Utils.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + RegisterDef FEI4BGlobalRegister::m_def; + bool FEI4BGlobalRegister::m_initialized=false; + + FEI4BGlobalRegister::FEI4BGlobalRegister(FECommands* commands): + GlobalRegister(commands) { + m_rd=&m_def; + m_def.LOW_REG=1; + m_def.N_REG_REGS=36; + m_def.N_W_REGS=36; + m_def.N_R_REGS=43; + m_def.SRAB_BITS=288; + m_def.SRC_BITS=144; + // initialize static field dictionary + if(!m_initialized)initialize(); + //set up size parameters + + //create registers + m_regw=new unsigned short[m_def.N_W_REGS]; + m_regr=new unsigned short[m_def.N_R_REGS]; + m_srab=new unsigned short[m_def.SRAB_BITS/16]; + m_src=new unsigned short[m_def.SRC_BITS/16]; + //Clear all registers + for(int i=0;i<m_def.N_W_REGS;i++)m_regw[i]=0; + for(int i=0;i<m_def.N_R_REGS;i++)m_regr[i]=0; + for(int i=0;i<m_def.SRAB_BITS/16;i++)m_srab[i]=0; + for(int i=0;i<m_def.SRC_BITS/16;i++)m_src[i]=0; + } + FEI4BGlobalRegister::~FEI4BGlobalRegister(){ + delete [] m_regw; + delete [] m_regr; + delete [] m_srab; + delete [] m_src; + } + + void FEI4BGlobalRegister::initialize(){ + addField("TrigCnt", 2, 12, -1, -1, 4, false); + addField("Conf_AddrEnable", 2, 11, -1, -1, 1, false); + addField("Reg2Spare", 2, 0, -1, -1, 11, false); + addField("ErrMask0", 3, 0, -1, -1, 16, false); + addField("ErrMask1", 4, 0, -1, -1, 16, false); + addField("PrmpVbpRight", 5, 8, 152, -1, 8, true); + addField("BufVgOpAmp", 5, 0, 144, -1, 8, true); + addField("Reg6Spare", 6, 8, -1, -1, 8, true); + addField("PrmpVbp", 6, 0, 160, -1, 8, true); + addField("TdacVbp", 7, 8, 184, -1, 8, true); + addField("DisVbn", 7, 0, 176, -1, 8, true); + addField("Amp2Vbn", 8, 8, 200, -1, 8, true); + addField("Amp2VbpFol", 8,0,192, -1, 8, true); + addField("Reg9Spare", 9, 8, -1, -1, 8, true); + addField("Amp2Vbp", 9, 0, 208, -1, 8, true); + addField("FdacVbn", 10, 8, 232, -1, 8, true); + addField("Amp2Vbpf", 10, 0, 224, -1, 8, true); + addField("PrmpVbnFol", 11, 8, 248, -1, 8, true); + addField("PrmpVbpLeft", 11, 0, 240, -1, 8, true); + addField("PrmpVbpf", 12, 8, 264, -1, 8, true); + addField("PrmpVbnLcc", 12, 0, 256, -1, 8, true); + addField("Reg13Spare", 13, 0, -1, -1, 1, false); + addField("PxStrobes", 13, 1, 274, -1, 13, true); + addField("S0", 13, 14, 273, -1, 1, false); + addField("S1", 13, 15, 272, -1, 1, false); + addField("LVDSDrvIref", 14, 8, 8, -1, 8, true); + addField("GADCOpAmp", 14, 0, 0, -1, 8, true); + addField("PllIbias", 15, 8, 24, -1, 8, true); + addField("LVDSDrvVos", 15, 0, 16, -1, 8, true); + addField("TempSensBias", 16, 8, 40, -1, 8, true); + addField("PllIcp", 16, 0, 32, -1, 8, true); + addField("Reg17Spare", 17, 8, -1, -1, 8, true); + addField("PlsrIdacRamp", 17, 0, 48, -1, 8, true); + addField("VrefDigTune", 18, 8, 72, -1, 8, true); + addField("PlsrVgOPamp", 18, 0, 64, -1, 8, true); + addField("PlsrDacBias", 19, 8, 88, -1, 8, true); + addField("VrefAnTune", 19, 0, 80, -1, 8, true); + addField("Vthin_AltCoarse", 20, 8, 104, -1, 8, true); + addField("Vthin_AltFine", 20, 0, 96, -1, 8, true); + addField("PlsrDAC", 21, 0, 112, -1, 10, true); + addField("DIGHITIN_Sel", 21, 10, 143, -1, 1, false); + addField("DINJ_Override", 21, 11, 142, -1, 1, false); + addField("HITLD_In", 21, 12, 141, -1, 1, false); + addField("Reg21Spare", 21, 13, -1, -1, 3, false); + addField("Reg22Spare2", 22, 0, -1, -1, 2, false); + addField("Colpr_Addr", 22, 2, 130, -1, 6, true); + addField("Colpr_Mode", 22, 8, 128, -1, 2, true); + addField("Reg22Spare1", 22, 10, -1, -1, 6, false); + addField("DisableColumnCnfg0", 23, 0, -1, 0, 16, false); + addField("DisableColumnCnfg1", 24, 0, -1, 16, 16, false); + addField("DisableColumnCnfg2", 25, 0, -1, 32, 8, false); + addField("TrigLat", 25, 8, -1, 40, 8, false); + addField("CMDcnt", 26, 3, -1, 51, 14, false); + addField("StopModeCnfg", 26, 2, -1, 50, 1, false); + addField("HitDiscCnfg", 26, 0, -1, 48, 2, false); + addField("EN_PLL", 27, 15, -1, 79, 1, false); + addField("Efuse_sense", 27, 14, -1, 78, 1, false); + addField("Stop_Clk", 27, 13, -1, 77, 1, false); + addField("ReadErrorReq", 27, 12, -1, 76, 1, false); + addField("Reg27Spare1", 27, 11, -1, -1, 1, false); + addField("GADC_Enable", 27, 10, -1, 74, 1, false); + addField("ShiftReadBack", 27, 9, -1, 73, 1, false); + addField("Reg27Spare2", 27, 6, -1, -1, 3, false); + addField("GateHitOr", 27, 5, -1, 69, 1, false); + addField("CalEn", 27, 4, -1, 68, 1, false); + addField("SR_clr", 27, 3, -1, 67, 1, false); + addField("Latch_en", 27, 2, -1, 66, 1, false); + addField("SR_Clock", 27, 1, -1, 65, 1, false); + addField("LVDSDrvSet06", 28, 15, -1, 95, 1, false); + addField("Reg28Spare", 28, 10, -1, -1, 5, false); + addField("EN40M", 28, 9, -1, 89, 1, false); + addField("EN80M", 28, 8, -1, 88, 1, false); + addField("CLK1", 28, 5, -1, 85, 3, false); + addField("CLK0", 28, 2, -1, 82, 3, false); + addField("EN160M", 28, 1, -1, 81, 1, false); + addField("EN320M", 28, 0, -1, 80, 1, false); + addField("Reg29Spare1", 29, 14, -1, -1, 2, false); + addField("no8b10b", 29, 13, -1, 109, 1, false); + addField("Clk2OutCnfg", 29, 12, -1, 108, 1, false); + addField("EmptyRecord", 29, 4, -1, 100, 8, true); + addField("Reg29Spare2", 29, 3, -1, -1, 1, false); + addField("LVDSDrvEn", 29, 2, -1, 98, 1, false); + addField("LVDSDrvSet30", 29, 1, -1, 97, 1, false); + addField("LVDSDrvSet12", 29, 0, -1, 96, 1, false); + addField("TempSensDiodeSel", 30, 14, -1, 126, 2, true); + addField("TempSensDisable", 30, 13, -1, 125, 1, false); + addField("IleakRange", 30, 12, -1, 124, 1, false); + addField("Reg30Spare", 30, 0, -1, -1, 12, false); + addField("PlsrRiseUpTau", 31, 13, -1, 141, 3, false); + addField("PlsrPwr", 31, 12, -1, 140, 1, false); + addField("PlsrDelay", 31, 6, -1, 134, 6, true); + addField("ExtDigCalSW", 31, 5, -1, 133, 1, false); + addField("ExtAnaCalSW", 31, 4, -1, 132, 1, false); + addField("Reg31Spare", 31, 3, -1, -1, 1, false); + addField("GADCSel", 31, 3, -1, 128, 1, false); + addField("SELB0", 32, 0, -1, -1, 16, false); + addField("SELB1", 33, 0, -1, -1, 16, false); + addField("SELB2", 34, 8, -1, -1, 8, false); + addField("Reg34Spare1", 34, 5, -1, -1, 3, false); + addField("PrmpVbpMsnEn", 34, 4, -1, -1, 1, false); + addField("Reg34Spare2", 34, 0, -1, -1, 4, false); + addField("Chip_SN", 35, 0, -1, -1, 16, false); + addField("Reg1Spare", 1, 9, -1, -1, 7, false); + addField("SmallHitErase", 1, 8, -1, -1, 1, false); + addField("Eventlimit", 1, 0, -1, -1, 8, true); + + // alternative definitions + addField("CMDcnt_width", 26, 3, -1, 51, 8, false); + addField("CMDcnt_delay", 26, 11, -1, 59, 6, false); + addField("ERRORMASK", 3, 0, -1, -1, 32, false); + addField("DisableColumnCnfg01", 23, 0, -1, 0, 32, false); + addField("SELB01", 32, 0, -1, -1, 32, false); + addField("CLK0_S2", 28, 2, -1, 82, 1, false); + addField("CLK0_S1", 28, 3, -1, 83, 1, false); + addField("CLK0_S0", 28, 4, -1, 84, 1, false); + addField("CLK1_S2", 28, 5, -1, 85, 1, false); + addField("CLK1_S1", 28, 6, -1, 86, 1, false); + addField("CLK1_S0", 28, 7, -1, 87, 1, false); + + + // Translation from scan parameter to Global register field + addParameter("LATENCY", "TrigLat"); + addParameter("GDAC", "Vthin_AltFine"); + addParameter("GDAC_COARSE", "Vthin_AltCoarse"); + addParameter("VCAL", "PlsrDAC"); + addParameter("STROBE_DELAY", "PlsrDelay"); + addParameter("IF", "PrmpVbpf"); + addParameter("TEMP", "TempSensDiodeSel"); + + //Translation from CLKx_S012 parameter to transmission rate + m_def.m_rate[0]=SerialIF::M40; + m_def.m_rate[4]=SerialIF::M320; + m_def.m_rate[2]=SerialIF::M40; + m_def.m_rate[6]=SerialIF::M320; + m_def.m_rate[1]=SerialIF::M160; + m_def.m_rate[5]=SerialIF::M80; + m_def.m_rate[3]=SerialIF::M40; + m_def.m_rate[7]=SerialIF::M160; //Aux clk + + m_def.m_params8b10b=m_def.m_fields["no8b10b"]; + m_def.m_paramsDrate=m_def.m_fields["CLK0"]; + m_def.m_colpr_reg=m_def.m_fields["Colpr_Addr"].reg; + m_def.m_colpr_disable=5<<2; + + m_initialized=true; + } + void FEI4BGlobalRegister::printFields(std::ostream &os){ + os<<"Global Register Fields"<<std::endl; + os<<"======================"<<std::endl; + os<<"TrigCnt "<<getField("TrigCnt")<<std::endl; + os<<"Conf_AddrEnable "<<getField("Conf_AddrEnable")<<std::endl; + os<<"ErrMask0 "<<getField("ErrMask0")<<std::endl; + os<<"ErrMask1 "<<getField("ErrMask1")<<std::endl; + os<<"PrmpVbpRight "<<getField("PrmpVbpRight")<<std::endl; + os<<"BufVgOpAmp "<<getField("BufVgOpAmp")<<std::endl; + os<<"PrmpVbp "<<getField("PrmpVbp")<<std::endl; + os<<"TdacVbp "<<getField("TdacVbp")<<std::endl; + os<<"DisVbn "<<getField("DisVbn")<<std::endl; + os<<"Amp2Vbn "<<getField("Amp2Vbn")<<std::endl; + os<<"Amp2VbpFol "<<getField("Amp2VbpFol")<<std::endl; + os<<"Amp2Vbp "<<getField("Amp2Vbp")<<std::endl; + os<<"FdacVbn "<<getField("FdacVbn")<<std::endl; + os<<"Amp2Vbpf "<<getField("Amp2Vbpf")<<std::endl; + os<<"PrmpVbnFol "<<getField("PrmpVbnFol")<<std::endl; + os<<"PrmpVbpLeft "<<getField("PrmpVbpLeft")<<std::endl; + os<<"PrmpVbpf "<<getField("PrmpVbpf")<<std::endl; + os<<"PrmpVbnLcc "<<getField("PrmpVbnLcc")<<std::endl; + os<<"PxStrobes "<<getField("PxStrobes")<<std::endl; + os<<"S0 "<<getField("S0")<<std::endl; + os<<"S1 "<<getField("S1")<<std::endl; + os<<"LVDSDrvIref "<<getField("LVDSDrvIref")<<std::endl; + os<<"GADCOpAmp "<<getField("GADCOpAmp")<<std::endl; + os<<"PllIbias "<<getField("PllIbias")<<std::endl; + os<<"LVDSDrvVos "<<getField("LVDSDrvVos")<<std::endl; + os<<"TempSensBias "<<getField("TempSensBias")<<std::endl; + os<<"PllIcp "<<getField("PllIcp")<<std::endl; + os<<"PlsrIdacRamp "<<getField("PlsrIdacRamp")<<std::endl; + os<<"VrefDigTune "<<getField("VrefDigTune")<<std::endl; + os<<"PlsrVgOPamp "<<getField("PlsrVgOPamp")<<std::endl; + os<<"PlsrDacBias "<<getField("PlsrDacBias")<<std::endl; + os<<"VrefAnTune "<<getField("VrefAnTune")<<std::endl; + os<<"Vthin_AltCoarse "<<getField("Vthin_AltCoarse")<<std::endl; + os<<"Vthin_AltFine "<<getField("Vthin_AltFine")<<std::endl; + os<<"PlsrDAC "<<getField("PlsrDAC")<<std::endl; + os<<"DIGHITIN_Sel "<<getField("DIGHITIN_Sel")<<std::endl; + os<<"DINJ_Override "<<getField("DINJ_Override")<<std::endl; + os<<"HITLD_In "<<getField("HITLD_In")<<std::endl; + os<<"Colpr_Addr "<<getField("Colpr_Addr")<<std::endl; + os<<"Colpr_Mode "<<getField("Colpr_Mode")<<std::endl; + os<<"DisableColumnCnfg0 "<<getField("DisableColumnCnfg0")<<std::endl; + os<<"DisableColumnCnfg1 "<<getField("DisableColumnCnfg1")<<std::endl; + os<<"DisableColumnCnfg2 "<<getField("DisableColumnCnfg2")<<std::endl; + os<<"TrigLat "<<getField("TrigLat")<<std::endl; + os<<"CMDcnt "<<getField("CMDcnt")<<std::endl; + os<<"StopModeCnfg "<<getField("StopModeCnfg")<<std::endl; + os<<"HitDiscCnfg "<<getField("HitDiscCnfg")<<std::endl; + os<<"EN_PLL "<<getField("EN_PLL")<<std::endl; + os<<"Efuse_sense "<<getField("Efuse_sense")<<std::endl; + os<<"Stop_Clk "<<getField("Stop_Clk")<<std::endl; + os<<"ReadErrorReq "<<getField("ReadErrorReq")<<std::endl; + os<<"GADC_Enable "<<getField("GADC_Enable")<<std::endl; + os<<"ShiftReadBack "<<getField("ShiftReadBack")<<std::endl; + os<<"GateHitOr "<<getField("GateHitOr")<<std::endl; + os<<"CalEn "<<getField("CalEn")<<std::endl; + os<<"SR_clr "<<getField("SR_clr")<<std::endl; + os<<"Latch_en "<<getField("Latch_en")<<std::endl; + os<<"SR_Clock "<<getField("SR_Clock")<<std::endl; + os<<"LVDSDrvSet06 "<<getField("LVDSDrvSet06")<<std::endl; + os<<"EN40M "<<getField("EN40M")<<std::endl; + os<<"EN80M "<<getField("EN80M")<<std::endl; + os<<"CLK1 "<<getField("CLK1")<<std::endl; + os<<"CLK0 "<<getField("CLK0")<<std::endl; + os<<"EN160M "<<getField("EN160M")<<std::endl; + os<<"EN320M "<<getField("EN320M")<<std::endl; + os<<"no8b10b "<<getField("no8b10b")<<std::endl; + os<<"Clk2OutCnfg "<<getField("Clk2OutCnfg")<<std::endl; + os<<"EmptyRecord "<<getField("EmptyRecord")<<std::endl; + os<<"LVDSDrvEn "<<getField("LVDSDrvEn")<<std::endl; + os<<"LVDSDrvSet30 "<<getField("LVDSDrvSet30")<<std::endl; + os<<"LVDSDrvSet12 "<<getField("LVDSDrvSet12")<<std::endl; + os<<"TempSensDiodeSel "<<getField("TempSensDiodeSel")<<std::endl; + os<<"TempSensDisable "<<getField("TempSensDisable")<<std::endl; + os<<"IleakRange "<<getField("IleakRange")<<std::endl; + os<<"PlsrRiseUpTau "<<getField("PlsrRiseUpTau")<<std::endl; + os<<"PlsrPwr "<<getField("PlsrPwr")<<std::endl; + os<<"PlsrDelay "<<getField("PlsrDelay")<<std::endl; + os<<"ExtDigCalSW "<<getField("ExtDigCalSW")<<std::endl; + os<<"ExtAnaCalSW "<<getField("ExtAnaCalSW")<<std::endl; + os<<"GADCSel "<<getField("GADCSel")<<std::endl; + os<<"SELB0 "<<getField("SELB0")<<std::endl; + os<<"SELB1 "<<getField("SELB1")<<std::endl; + os<<"SELB2 "<<getField("SELB2")<<std::endl; + os<<"PrmpVbpMsnEn "<<getField("PrmpVbpMsnEn")<<std::endl; + os<<"Chip_SN "<<getField("Chip_SN")<<std::endl; + os<<"SmallHitErase "<<getField("SmallHitErase")<<std::endl; + os<<"Eventlimit "<<getField("Eventlimit")<<std::endl; + + os<<"Alternative Field definitions:"<<std::endl; + // alternative definitions + os<<"CMDcnt_width "<<getField("CMDcnt_width")<<std::endl; + os<<"CMDcnt_delay "<<getField("CMDcnt_delay")<<std::endl; + os<<"ERRORMASK "<<getField("ERRORMASK")<<std::endl; + os<<"DisableColumnCnfg01 "<<getField("DisableColumnCnfg01")<<std::endl; + os<<"SELB01 "<<getField("SELB01")<<std::endl; + os<<"CLK0_S2 "<<getField("CLK0_S2")<<std::endl; + os<<"CLK0_S1 "<<getField("CLK0_S1")<<std::endl; + os<<"CLK0_S0 "<<getField("CLK0_S0")<<std::endl; + os<<"CLK1_S2 "<<getField("CLK1_S2")<<std::endl; + os<<"CLK1_S1 "<<getField("CLK1_S1")<<std::endl; + os<<"CLK1_S0 "<<getField("CLK1_S0")<<std::endl; + } + +}; diff --git a/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.hh b/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..0cdbd823190cd66d7844ca4170befc642732dc4e --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BGlobalRegister.hh @@ -0,0 +1,31 @@ +#ifndef FEI4BGLOBALREGISTER_FEI4_HH +#define FEI4BGLOBALREGISTER_FEI4_HH + +#include <map> +#include <string> +#include <vector> +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/config/FEI4/GlobalRegister.hh" + + +namespace FEI4{ + +class FECommands; + + class FEI4BGlobalRegister: public GlobalRegister{ + public: + FEI4BGlobalRegister(FECommands* commands); + virtual ~FEI4BGlobalRegister(); + void printFields(std::ostream &os); + private: + void initialize(); + static RegisterDef m_def; + static bool m_initialized; + RegisterDef* getDef(){return &m_def;} + + + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4BModule.cc b/rce/rcecalib/config/FEI4/FEI4BModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..a990084544ae103d2f73fd1e32e327b3fd451ddf --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BModule.cc @@ -0,0 +1,104 @@ +#include "rcecalib/config/FEI4/FEI4BModule.hh" +#include "rcecalib/config/FEI4/FEI4BGlobalRegister.hh" +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/VerifyErrors.hh" +#include <iostream> +#include <fstream> +#include "ers/ers.h" +#include <stdio.h> + +namespace FEI4{ + + + FEI4BModule::FEI4BModule(const char* name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"Module"<<std::endl; + m_commands=new FECommands; + m_global=new FEI4BGlobalRegister(m_commands); + m_pixel=new PixelRegister(m_commands); + m_pixel_readback=new PixelRegister(m_commands); + } + FEI4BModule::~FEI4BModule(){ + delete m_global; + delete m_pixel; + delete m_pixel_readback; + delete m_commands; + //m_timer.Print("Module"); + } + void FEI4BModule::setupGlobalPulseHW(int pulsereg){ + m_global->setField("Efuse_sense",(pulsereg&GlobalRegister::Efuse_sense)!=0, GlobalRegister::SW); + m_global->setField("Stop_Clk",(pulsereg&GlobalRegister::Stop_Clk)!=0, GlobalRegister::SW); + m_global->setField("ReadErrorReq",(pulsereg&GlobalRegister::ReadErrorReq)!=0, GlobalRegister::SW); + m_global->setField("CalEn",(pulsereg&GlobalRegister::CalEn)!=0, GlobalRegister::SW); + m_global->setField("SR_clr",(pulsereg&GlobalRegister::SR_clr)!=0, GlobalRegister::SW); + m_global->setField("Latch_en",(pulsereg&GlobalRegister::Latch_en)!=0, GlobalRegister::SW); + m_global->setField("GADC_Enable",(pulsereg&GlobalRegister::GADC_Start)!=0, GlobalRegister::SW); + m_global->setField("ShiftReadBack",(pulsereg&GlobalRegister::SR_Read)!=0, GlobalRegister::SW); + m_global->setField("SR_Clock",(pulsereg&GlobalRegister::SR_Clock)!=0, GlobalRegister::HW); //do one HW write for all fields + } + + // void Frontend::pixelUsrToRaw(BitStream *bs, unsigned bit){ + // } + + void FEI4BModule::resetHW(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + m_commands->globalReset(bs); + SerialIF::send(bs); + delete bs; + resetErrorCountersHW(); + } + + + int FEI4BModule::verifyModuleConfigHW(){ + int retval=0; + SerialIF::setChannelInMask(1<<m_inLink); + SerialIF::setChannelOutMask(1<<m_outLink); + std::vector <unsigned> readback; + if(m_formatter){ + // global register + std::cout<<"***FE "<<m_id<<"***"<<std::endl; + m_formatter->setReadbackPointer(&readback); + retval=m_global->verifyConfigHW(readback); + // pixel registers + m_global->setField("Colpr_Mode", 0, GlobalRegister::SW); // only write to 1 column pair + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + for (int dcol=0;dcol<PixelRegister::N_COLS/2;dcol++){ + for (int bit=0;bit<PixelRegister::N_PIXEL_REGISTER_BITS-1;bit++){ + m_global->setField("Colpr_Addr", dcol, GlobalRegister::HW); + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + setupS0S1HitldHW(0, 0, 0); + m_global->setField("ShiftReadBack",1, GlobalRegister::HW); //setupGlobalPulse does the HW write for that register + retval|=m_pixel->verifyDoubleColumnHW(bit, dcol, readback); //check double column + m_global->setField("ShiftReadBack",0, GlobalRegister::SW); //setupGlobalPulse does the HW write for that register + } + } + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + delete bs; + m_formatter->setReadbackPointer(0); + }else{ + retval=ModuleVerify::NO_FORMATTER; + } + return retval; + } + + + void FEI4BModule::destroy(){ + delete this; + } + + +}; + diff --git a/rce/rcecalib/config/FEI4/FEI4BModule.hh b/rce/rcecalib/config/FEI4/FEI4BModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..0df855da4abd29384c78acb1bc82e1a164c68a94 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BModule.hh @@ -0,0 +1,25 @@ +#ifndef FEI4__FEI4BMODULE_HH +#define FEI4__FEI4BMODULE_HH + +#include "rcecalib/config/FEI4/Module.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/profiler/Profiler.hh" +#include <string> + +class AbsFormatter; + +namespace FEI4{ + + class FEI4BModule: public Module{ + public: + FEI4BModule(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter *fmt); + virtual ~FEI4BModule(); + void resetHW(); + int verifyModuleConfigHW(); + virtual void destroy(); + void setupGlobalPulseHW(int pulsereg); + +}; + +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4BRecord.hh b/rce/rcecalib/config/FEI4/FEI4BRecord.hh new file mode 100644 index 0000000000000000000000000000000000000000..879dfc6964a2f2e03a06ed1f27e3a352d352ef46 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4BRecord.hh @@ -0,0 +1,246 @@ +#ifndef FEI4BRECORD_HH +#define FEI4BRECORD_HH + +#include "rcecalib/config/Endianness.hh" +namespace FEI4{ + + +namespace Size +{ + enum Size + { + UNUSED = 8, + HEADER = 8, + RTYPE = 1, + ADDR = 15, + VALUE = 16, + ERRCODE = 6, + ERRCOUNT = 10, + REMAINDER = 16, + FLAG = 1, + LV1ID = 5, + BXID = 10, + COL = 7, + ROW = 9, + TOT = 4 + }; +} +namespace Key +{ + enum Key + { + ADDR = 0xea, + VALUE = 0xec, + SERVICE = 0xef, + HEADER = 0xe9, + EMPTY = 0x0, + GLOBAL = 0, + SHIFT = 1 + }; +} +/* ---------------------------------------------------------------------- */ + + struct Generic + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int remainder: Size::REMAINDER; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int remainder: Size:: REMAINDER; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + struct Address + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int rtype: Size:: RTYPE; + unsigned int address: Size::ADDR; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int address: Size::ADDR; + unsigned int rtype: Size:: RTYPE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct Value + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int value: Size::VALUE; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int value: Size::VALUE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else +#error ENDIANNESS is not defined +#endif + }; + + struct Service + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int errcode: Size::ERRCODE; + unsigned int errcount: Size::ERRCOUNT; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int errcount: Size::ERRCOUNT; + unsigned int errcode: Size::ERRCODE; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct DataHeader + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int header: Size::HEADER; + unsigned int flag: Size::FLAG; + unsigned int lv1id: Size::LV1ID; + unsigned int bxid: Size::BXID; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int bxid: Size::BXID; + unsigned int lv1id: Size::LV1ID; + unsigned int flag: Size::FLAG; + unsigned int header: Size::HEADER; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + struct Data + { +#if ENDIANNESS_IS_BIG + + unsigned int unused: Size::UNUSED; + unsigned int col: Size::COL; + unsigned int row: Size::ROW; + unsigned int totbottom: Size::TOT; + unsigned int tottop: Size::TOT; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int tottop: Size::TOT; + unsigned int totbottom: Size::TOT; + unsigned int row: Size::ROW; + unsigned int col: Size::COL; + unsigned int unused: Size::UNUSED; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + + union Record + { + unsigned int ui; + Generic ge; + Address ad; + Value va; + Service se; + DataHeader he; + Data da; + }; + + + class FEI4BRecord{ + public: + enum Status + { + OK = 0, /*!< Clean finish */ + Empty = 1, /*!< Buffer does not contain any record */ + NotGlobal = 2, /*!< Address record is not a global register record */ + WrongAddress = 3, /*!< Address record does not contain the expected address */ + BadAddrValSeq = 4, /*!< Address record not immediately followed by value record */ + NoValue = 5, /*!< Value record missing. */ + NotShift = 6, /*!< Address record is not a shift register record */ + OddNwords = 7, /*!< Odd number of 16 bit words in shift register readback */ + NoHeader = 8, /*!< Data word without a previous header word*/ + BadRecord = 9 /*!< Unknown record type */ + }; + + bool isAddressRecord(){return m_record.ge.header==Key::ADDR;} + bool isValueRecord(){return m_record.ge.header==Key::VALUE;} + bool isServiceRecord(){return m_record.ge.header==Key::SERVICE;} + bool isEmptyRecord(){return m_record.ge.header==Key::EMPTY;} + bool isDataHeader(){return m_record.ge.header==Key::HEADER;} + bool isData(){return (m_record.ge.header&0xc0)!=0xc0;} + unsigned getHeader(){return m_record.ge.header;} + unsigned getAddress(){return m_record.ad.address;} + unsigned getRegisterType(){return m_record.ad.rtype;} + unsigned isGlobal(){return m_record.ad.rtype==Key::GLOBAL;} + unsigned isShift(){return m_record.ad.rtype==Key::SHIFT;} + unsigned getValue(){return m_record.va.value;} + unsigned getUnsigned(){return m_record.ui;} + unsigned getColumn(){return m_record.da.col;} + unsigned getL1id(){return m_record.he.lv1id;} + unsigned getBxid(){return m_record.he.bxid;} + unsigned getRow(){return m_record.da.row;} + unsigned getTotTop(){return m_record.da.tottop;} + unsigned getTotBottom(){return m_record.da.totbottom;} + unsigned getErrorCode(){return m_record.se.errcode;} + unsigned getErrorCount(){return m_record.se.errcount;} +#if ENDIANNESS_IS_BIG + void setRecord(const unsigned char* bytepointer){ + unsigned char* rec=(unsigned char*)&m_record; + rec[1]=*bytepointer; + rec[2]=*(bytepointer+1); + rec[3]=*(bytepointer+2); + } +#elif ENDIANNESS_IS_LITTLE + void setRecord(const unsigned char* bytepointer){ + unsigned char* rec=(unsigned char*)&m_record; + rec[2]=*bytepointer; + rec[1]=*(bytepointer+1); + rec[0]=*(bytepointer+2); + } +#else +#error ENDIANNESS is not defined +#endif + + private: + Record m_record; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4HitorFormatter.cc b/rce/rcecalib/config/FEI4/FEI4HitorFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..8bb0c8cf350ba66fb6db6a844c41db9211006585 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4HitorFormatter.cc @@ -0,0 +1,63 @@ +#include "rcecalib/config/FEI4/FEI4HitorFormatter.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> + +FEI4HitorFormatter::FEI4HitorFormatter(int id): + AbsFormatter(id){ +} +FEI4HitorFormatter::~FEI4HitorFormatter(){ + +} +void FEI4HitorFormatter::configure(boost::property_tree::ptree* config){ +} + +int FEI4HitorFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + if(buflen==0)return FEI4::FEI4ARecord::Empty; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4ARecord rec; + bool header=false; + nL1A=0; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isDataHeader()){ + header=true; + //printf("Formatter word %x\n",rec.getValue()); + //printf("FEI %d Header.\n",getId()); + }else if (rec.isEmptyRecord()){ + header=false; + }else if(rec.isData()){ + //printf("FEI %d Data.\n",getId()); + if(header==false)return FEI4::FEI4ARecord::NoHeader; + // std::cout<<std::hex<<rec.getHeader()<<std::endl; + }else if(rec.isServiceRecord()){ + //printf("Service record FEI %d. Error code: %d. Count: %d \n", getId(), rec.getErrorCode(), rec.getErrorCount()); + unsigned code=rec.getErrorCode(); + unsigned count=rec.getErrorCount(); + if(code==10){ //HitOr + //printf("Service record FEI %d. Error code: %d. Count: %d \n", getId(), rec.getErrorCode(), rec.getErrorCount()); + nL1A=1; //pretend all triggers came in + if(count>0)parsedData[parsedsize++]=1; //pixel is stuck + return FEI4::FEI4ARecord::OK; + } + header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + //printf("FEI %d: Value record: %04x.\n",getId(), rec.getValue()); + header=false; + }else if(rec.isAddressRecord()){ // address record + //printf("FEI %d: Address record\n",getId()); + header=false; + }else{ + std::cout<<"Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + return FEI4::FEI4ARecord::BadRecord; + } + bytepointer+=3; + } + return FEI4::FEI4ARecord::OK; +} + diff --git a/rce/rcecalib/config/FEI4/FEI4HitorFormatter.hh b/rce/rcecalib/config/FEI4/FEI4HitorFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..2b0a89a8d0619de6aaaa15e6e501cfab0ff05382 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4HitorFormatter.hh @@ -0,0 +1,14 @@ +#ifndef FEI4HITORFORMATTER_HH +#define FEI4HITORFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" + +class FEI4HitorFormatter:public AbsFormatter{ +public: + FEI4HitorFormatter(int id); + virtual ~FEI4HitorFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); + +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FEI4OccFormatter.cc b/rce/rcecalib/config/FEI4/FEI4OccFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..5896dc7b108beef35ef89673f1c640f1c7c0f868 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4OccFormatter.cc @@ -0,0 +1,82 @@ +#include "rcecalib/config/FEI4/FEI4OccFormatter.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> +#include "rcecalib/profiler/Profiler.hh" + +FEI4OccFormatter::FEI4OccFormatter(int id): + AbsFormatter(id){ + char name[128], title[128]; + sprintf(name, "Mod_%d_FEI4_Errors", id); + sprintf(title, "Module %d FEI4 Errors", id); + m_errhist=new RceHisto1d<int, int>(name, title, 32, -.5, 31.5); +} +FEI4OccFormatter::~FEI4OccFormatter(){ + delete m_errhist; + //m_timer.Print("FEI4OccupancyFormatter"); + +} +void FEI4OccFormatter::configure(boost::property_tree::ptree* config){ + m_errhist->clear(); + //m_timer.Reset(); +} + +int FEI4OccFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + if(buflen==0)return FEI4::FEI4ARecord::Empty; + //m_timer.Start(); + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4ARecord rec; + bool header=false; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if (rec.isEmptyRecord()){ + header=false; + }else if(rec.isData()){ + if(header==false)return FEI4::FEI4ARecord::NoHeader; + //there are potentially 2 hits in one data record + if(((rec.getTotBottom())>>1)!=0x7){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()-1); + parsedData[parsedsize++]=fr.getWord(); + + } + if(((rec.getTotTop())>>1)!=0x7){ //above threshold + FormattedRecord fr(FormattedRecord::DATA); + fr.setCol(rec.getColumn()-1); + fr.setRow(rec.getRow()); + parsedData[parsedsize++]=fr.getWord(); + } + } else if(rec.isDataHeader()){ + header=true; + nL1A++; + }else if(rec.isServiceRecord()){ + printf("Service record FE %d. Error code: %d. Count: %d \n", + getId(), rec.getErrorCode(), rec.getErrorCount()); + if( rec.getErrorCode()<32)m_errhist->fill(rec.getErrorCode(), rec.getErrorCount()); + header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + // printf("Value record: %04x.\n",rec.getValue()); + header=false; + }else if(rec.isAddressRecord()){ // address record + std::cout<<"Address record for "; + if(rec.isGlobal())std::cout<<" global register "; + else std::cout<<" shift register "; + std::cout<<rec.getAddress()<<std::endl; + std::cout<<"This should not happen."<<std::endl; + header=false; + }else{ + std::cout<<"Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + return FEI4::FEI4ARecord::BadRecord; + } + bytepointer+=3; + } + // m_timer.Stop(); + return FEI4::FEI4ARecord::OK; +} + diff --git a/rce/rcecalib/config/FEI4/FEI4OccFormatter.hh b/rce/rcecalib/config/FEI4/FEI4OccFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..7d9e267d7d05d53ad6f82313ad5224e9632f6c15 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FEI4OccFormatter.hh @@ -0,0 +1,19 @@ +#ifndef FEI4OCCFORMATTER_HH +#define FEI4OCCFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/util/RceHisto1d.cc" +#include "rcecalib/profiler/Profiler.hh" + +class FEI4OccFormatter:public AbsFormatter{ +public: + FEI4OccFormatter(int id); + virtual ~FEI4OccFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); + +private: + RceHisto1d<int, int>* m_errhist; + Profiler::Timer m_timer; +}; +#endif diff --git a/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.cc b/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..ac0577e1d733c719306d2966174cb36ed694ab01 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.cc @@ -0,0 +1,37 @@ +#include "rcecalib/config/FEI4/FastAnalogMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + FastAnalogMaskStaging::FastAnalogMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + if(type=="FEI4_COL_ANL_40x8")m_nStages=6; + else m_nStages=3; + } + + void FastAnalogMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + const int nColStages=40; + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned dcolStage=maskStage%nColStages; + unsigned stage=maskStage/nColStages; + if((maskStage+nColStages)/nColStages!=(maskStage+nColStages-1)/nColStages){ //need to set up pixel mask + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStage(i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, 0, 0); + } + } + } + // stage 0-5: colpr_mode=2, colpr_addr= 1, 2, 3, 4, 5, 6 + // stage 6-9: colpr_mode=0, colpr_addr= 8, 16, 24, 32 + // stage 10-13: colpr_mode=0, colpr_addr= 7, 15, 23, 31 + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + global->setField("Colpr_Addr", dcolStage , GlobalRegister::HW); +} +}; diff --git a/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.hh b/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..2ebc5dc9c104cb225e268787fc710d5a0bdd1267 --- /dev/null +++ b/rce/rcecalib/config/FEI4/FastAnalogMaskStaging.hh @@ -0,0 +1,20 @@ +#ifndef FEI4FASTANALOGMASKSTAGING_HH +#define FEI4FASTANALOGMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class FastAnalogMaskStaging: public MaskStaging<FEI4::Module>{ + public: + FastAnalogMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.cc b/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..497466a9372aa34790ccc8d1a2707c4f3bd64ce5 --- /dev/null +++ b/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.cc @@ -0,0 +1,97 @@ + +#include "rcecalib/config/FEI4/Fei4RegisterTestTrigger.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + Fei4RegisterTestTrigger::Fei4RegisterTestTrigger():AbsTrigger(){ + } + Fei4RegisterTestTrigger::~Fei4RegisterTestTrigger(){ + } + int Fei4RegisterTestTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + // int calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + int Fei4RegisterTestTrigger::setupParameter(const char* name, int val){ + return 0; + } + + + int Fei4RegisterTestTrigger::sendTrigger(){ + m_triggerStream.clear(); + FECommands commands; + commands.setBroadcast(true); + int triggersPerStage=13*40; + int maskstage=m_i/triggersPerStage; + if(maskstage<2){ //pixel register test + int trigger=m_i%triggersPerStage; + int dcol=trigger/13; + int dcolrev=((dcol&1)<<5) | ((dcol&2)<<3) | ((dcol&4)<<1) | ((dcol&8)>>1) | ((dcol&16)>>3) | ((dcol&32)>>5); + int bit=trigger%13; + dcolrev=dcolrev<<2; + commands.switchMode(&m_triggerStream, FECommands::CONF); + m_triggerStream.push_back(0); + //colpr mode and addr + commands.writeGlobalRegister(&m_triggerStream, 22, dcolrev); + m_triggerStream.push_back(0); + //SR clock + commands.writeGlobalRegister(&m_triggerStream, 27, 0x8002); + m_triggerStream.push_back(0); + //set up strobe bit + commands.writeGlobalRegister(&m_triggerStream, 13, 0xc000|(1<<(13-bit))); + m_triggerStream.push_back(0); + commands.globalPulse(&m_triggerStream, FECommands::PULSE_WIDTH); + SerialIF::send(&m_triggerStream, SerialIF::WAITFORDATA); //global pulse + //clear strobe/S0S1 + commands.writeGlobalRegister(&m_triggerStream, 13, 0); + //setup shift readback + commands.writeGlobalRegister(&m_triggerStream, 27, 0x8200); + m_triggerStream.push_back(0); + commands.feWriteCommand(&m_triggerStream); + for(int i=0;i<21;i++)m_triggerStream.push_back(0); // refill with 0 + m_triggerStream.push_back(0); + commands.writeGlobalRegister(&m_triggerStream, 27, 0x8000); //shift readback to 0 + m_triggerStream.push_back(0); + SerialIF::send(&m_triggerStream, SerialIF::WAITFORDATA); + }else{ //global register readback + commands.switchMode(&m_triggerStream, FECommands::CONF); + m_triggerStream.push_back(0); + for (int i=1;i<=42;i++){ //Has to be 42 because 42 triggers are expected. + int reg=i; + if(reg>35)reg=35; + commands.readGlobalRegister(&m_triggerStream, reg); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + } + SerialIF::send(&m_triggerStream, SerialIF::WAITFORDATA); + + } + + m_i++; + return 0; + } + + int Fei4RegisterTestTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int Fei4RegisterTestTrigger::resetCounters(){ + return 0; + } +}; diff --git a/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.hh b/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..0e3d02a939b74fede590568223822785a74d19d2 --- /dev/null +++ b/rce/rcecalib/config/FEI4/Fei4RegisterTestTrigger.hh @@ -0,0 +1,25 @@ +#ifndef FEI4REGISTERTESTTRIGGER_HH +#define FEI4REGISTERTESTTRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" + +namespace FEI4{ + + class Fei4RegisterTestTrigger: public AbsTrigger{ + public: + Fei4RegisterTestTrigger(); + ~Fei4RegisterTestTrigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + private: + BitStream m_triggerStream; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/GlobalRegister.cc b/rce/rcecalib/config/FEI4/GlobalRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..85cd884e0a0efd934b4c713744487075ce538933 --- /dev/null +++ b/rce/rcecalib/config/FEI4/GlobalRegister.cc @@ -0,0 +1,273 @@ + +#include "rcecalib/config/FEI4/GlobalRegister.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FEI4/Utils.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/util/VerifyErrors.hh" + +namespace FEI4{ + + GlobalRegister::GlobalRegister(FECommands* commands): m_clkOutMode(false), m_commands(commands){ + } + GlobalRegister::~GlobalRegister(){ + } + void GlobalRegister::writeHW(){ + for(int i=m_rd->N_REG_REGS-1;i>=m_rd->LOW_REG;i--){ +// for(int i=LOW_REG;i<N_REG_REGS;i++){ + if(i==20)continue; //threshold register at the end + assert(writeRegisterHW(i, m_regw[i])==0); + } + } + void GlobalRegister::writeRegisterHW(int i){ + assert(writeRegisterHW(i, m_regw[i])==0); + } + void GlobalRegister::disableThresholdHW(bool dis){ + BitStream *bs=new BitStream; + unsigned short val= dis? 0xffff : m_regw[20]; + m_commands->writeGlobalRegister(bs, 20, val); + SerialIF::send(bs, SerialIF::WAITFORDATA); //Write register + delete bs; + } + + void GlobalRegister::enableSrHW(bool on){ + unsigned short val; + if(on)val=m_regw[m_rd->m_colpr_reg]; + else val=m_rd->m_colpr_disable; + BitStream *bs=new BitStream; + m_commands->writeGlobalRegister(bs, m_rd->m_colpr_reg, val); + SerialIF::send(bs, SerialIF::WAITFORDATA); //Write register + delete bs; + } + + unsigned GlobalRegister::writeRegisterHW(int i, unsigned short val){ + unsigned retval=0; + if(i<0 || i>=m_rd->N_W_REGS){ + retval=1; + }else { + m_regw[i]=val; // set register content + + BitStream *bs=new BitStream; + m_commands->writeGlobalRegister(bs, i, val); + + SerialIF::send(bs, SerialIF::WAITFORDATA); //Write register + if (i==m_rd->m_params8b10b.reg || i==m_rd->m_paramsDrate.reg){ + if(i==m_rd->m_paramsDrate.reg){ + SerialIF::setDataRate(m_rd->m_rate[getField("CLK0")]); + } + if(getField("Clk2OutCnfg")==0){ //chip is not in clk output mode + bool mode=getField("no8b10b"); + std::cout<<"Mode is "<<mode<<std::endl; + SerialIF::setOutputMode(mode); + m_clkOutMode=false; + }else{ + m_clkOutMode=true; + } + } + delete bs; + } + return retval; + } + + unsigned GlobalRegister::readRegisterHW(int i, unsigned short& val){ + unsigned retval=0; + if(m_clkOutMode==true){ + retval=11; + }else if(i>=0 && i<m_rd->N_R_REGS){ + BitStream *bs=new BitStream; + std::vector<unsigned> retvec; + m_commands->readGlobalRegister(bs, i); + // SerialIF::send(bs); + std::cout<<"Size "<<retvec.size()<<std::endl; + retval=SerialIF::readBlockData(*bs, retvec); + std::cout<<"Size "<<retvec.size()<<std::endl; + if(retval==0){ + retval=decodeGlobalRecord(retvec,i,val); + } + delete bs; + }else{ + retval=10; + } + return retval; + } + void GlobalRegister::readRegisterHW(int i){ + if(i>=0 && i<m_rd->N_R_REGS){ + BitStream *bs=new BitStream; + m_commands->readGlobalRegister(bs, i); + SerialIF::send(bs, SerialIF::WAITFORDATA); + delete bs; + } + } + int GlobalRegister::verifyConfigHW(std::vector<unsigned> & readback){ + int retval=0; + for(int i=m_rd->LOW_REG;i<m_rd->N_REG_REGS;i++){ + if (i==22)continue; // reg 22 is colpr_mode and colpr_addr. Used to set up pixel reg => will be different in readback + readback.clear(); + readRegisterHW(i); + usleep(100); + if(readback.size()==0){ + std::cout<<"Failed to read back register "<<std::dec<<i<<std::endl; + retval|=ModuleVerify::GLOBAL_READBACK_FAILED; + } else { + m_regr[i]=readback[0]; + if(m_regw[i]!=m_regr[i]){ + std::cout<<"Bad global register readback for register "<<std::dec<<i + <<": Read "<<std::hex<<m_regr[i]<<" should be "<<m_regw[i]<<std::dec<<std::endl; + retval|=ModuleVerify::GLOBAL_READBACK_DIFFERENT; + } + } + } + return retval; + } + + void GlobalRegister::setField(const char* name, unsigned vali, mode t){ + char msg[128]; + sprintf(msg,"parameter %s is invalid",name); + ERS_ASSERT_MSG(m_rd->m_fields.find(name)!=m_rd->m_fields.end(),msg); + FieldParams params=m_rd->m_fields[name]; + // set the proper register first + unsigned val; + if(params.reverse==true)val=flipBits(params.width, vali); + else val=vali; + setFieldFun(&m_regw[params.reg], params.bitpos, params.width, val); + if(t==HW){ + writeRegisterHW(params.reg); + if(params.bitpos+params.width>16)writeRegisterHW(params.reg+1); + } + //if(params.SRABbitpos!=-1) // AB shadow register + // setFieldFun(&m_srab[params.SRABbitpos/16], params.SRABbitpos%16, params.width, val); + //if(params.SRCbitpos!=-1) // C shadow register + // setFieldFun(&m_src[params.SRCbitpos/16], params.SRCbitpos%16, params.width, val); + } + void GlobalRegister::setFieldFun(unsigned short* reg, int bitpos, int width, unsigned val){ + int pwidth=bitpos+width<=16 ? width : 16 - bitpos; + unsigned short mask=(1<<pwidth)-1; + *reg&=~(mask<<bitpos); + *reg|=(val&mask)<<bitpos; + if(pwidth!=width){ // extends over next register + int rwidth=width-pwidth; + mask=(1<<rwidth)-1; + *(reg+1)&=~mask; + *(reg+1)|=(val>>pwidth)&mask; + } + } + + unsigned GlobalRegister::getField(const char* name){ + ERS_ASSERT_MSG(m_rd->m_fields.find(name)!=m_rd->m_fields.end(),"parameter name is invalid"); + FieldParams params=m_rd->m_fields[name]; + unsigned retval=0; + int pwidth=params.bitpos+params.width<=16 ? params.width : 16 - params.bitpos; + unsigned short mask=(1<<pwidth)-1; + retval=(m_regw[params.reg]>>params.bitpos)&mask; + if(pwidth!=params.width){ // extends over next register + int rwidth=params.width-pwidth; + mask=(1<<rwidth)-1; + retval|=(m_regw[params.reg+1]&mask)<<pwidth; + } + if(params.reverse==false) + return retval; + else + return flipBits(params.width, retval); + } + + std::string GlobalRegister::lookupParameter(const char* name){ + // check if this is the last name used, return cached value + if(std::string(name)==m_rd->m_cachedName)return m_rd->m_cachedField; + // Now check if we can translate the name to a field name + if(m_rd->m_parameters.find(name)!=m_rd->m_parameters.end()){ + //cache result + m_rd->m_cachedName=name; + m_rd->m_cachedField=m_rd->m_parameters[name]; + return m_rd->m_cachedField; + // maybe it's a proper field name? + } else if (m_rd->m_fields.find(name)!=m_rd->m_fields.end()){ + m_rd->m_cachedName=name; + m_rd->m_cachedField=name; + return m_rd->m_cachedField; + } + // not found. + else return ""; + } + void GlobalRegister::addParameter(const char* name, const char* field){ + m_rd->m_parameters[name]=field; + } + void GlobalRegister::addField(const char* name, int reg, int bitpos, int srab, int src, int width, bool reverse){ + FieldParams temp; + temp.reg=reg; + temp.bitpos=bitpos; + temp.SRABbitpos=srab; + temp.SRCbitpos=src; + temp.width=width; + temp.reverse=reverse; + m_rd->m_fields[name]=temp; + } + + void GlobalRegister::printRegisters(std::ostream &os){ + os<<"Global Registers:"<<std::endl; + os<<"================="<<std::endl; + char line[128]; + for (int i=0;i<m_rd->N_W_REGS;i++){ + sprintf(line, "Register %d: %04x\n",i, m_regw[i]); + os<<line; + } + } + void GlobalRegister::printShadowRegisterAB(std::ostream &os){ + os<<"Shadow Register AB:"<<std::endl; + os<<"==================="<<std::endl; + char line[128]; + for (int i=0;i<m_rd->SRAB_BITS/16;i++){ + sprintf(line, "Bit %d - Bit %d: %04x\n",i*16+15, i*16, m_srab[i]); + os<<line; + } + } + void GlobalRegister::printShadowRegisterC(std::ostream &os){ + os<<"Shadow Register C:"<<std::endl; + os<<"==================="<<std::endl; + char line[128]; + for (int i=0;i<m_rd->SRC_BITS/16;i++){ + sprintf(line, "Bit %d - Bit %d: %04x\n",i*16+15, i*16, m_src[i]); + os<<line; + } + } + + unsigned GlobalRegister::decodeGlobalRecord(std::vector<unsigned> inpvec, int i, unsigned short& val){ + if(inpvec.size()==0)return FEI4ARecord::Empty; + unsigned char* bytepointer=(unsigned char*)&inpvec[0]; + size_t size=inpvec.size()*sizeof(unsigned); + unsigned char* last=bytepointer+size-3; + val=0xffff; + FEI4ARecord rec; + bool addrrec=false; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isAddressRecord()){ // address record + if(!rec.isGlobal())return FEI4ARecord::NotGlobal; + if(rec.getAddress()!=(unsigned)i)return FEI4ARecord::WrongAddress; + std::cout<<"Read address record"<<std::endl; + addrrec=true; + }else if(addrrec==true){ + if(!rec.isValueRecord())return FEI4ARecord::BadAddrValSeq; // addr not immediately followed by val + std::cout<<"Value Record"<<std::endl; + val=rec.getValue(); + addrrec=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + printf("Value record: %08x\n",rec.getUnsigned()); + val=rec.getValue(); + }else if(rec.isServiceRecord()){ + printf("Service record. Error code: %d. Count: %d \n",rec.getErrorCode(), rec.getErrorCount()); + }else if(rec.isEmptyRecord()){ + // do nothing + }else{ + std::cout<<"Unexpected record type."<<std::endl; + } + bytepointer+=3; + } + if(val==0xffff)return FEI4ARecord::NoValue; // no value record found. + return FEI4ARecord::OK; + } + +}; diff --git a/rce/rcecalib/config/FEI4/GlobalRegister.hh b/rce/rcecalib/config/FEI4/GlobalRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..ec44033a7c6bce205d57136d9dee4812d263d67a --- /dev/null +++ b/rce/rcecalib/config/FEI4/GlobalRegister.hh @@ -0,0 +1,61 @@ +#ifndef GLOBALREGISTER_FEI4_HH +#define GLOBALREGISTER_FEI4_HH + +#include <map> +#include <string> +#include <vector> +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/config/FEI4/RegisterDef.hh" + +namespace FEI4{ + +class FECommands; + + class GlobalRegister{ + public: + enum PulseReg{Efuse_sense=0x1, Stop_Clk=0x2, ReadErrorReq=0x4, ReadSkipped=0x8, + CalEn=0x20, SR_clr=0x40, Latch_en=0x80, SR_Clock=0x100, GADC_Start=0x200, SR_Read=0x400}; + enum mode{SW, HW}; + GlobalRegister(FECommands* commands); + virtual ~GlobalRegister(); + void setField(const char* name, unsigned val, mode t); + void setFieldFun(unsigned short* reg, int bitpos, int width, unsigned val); + unsigned getField(const char* name); + int getRegisterNumber(const char* name){ + if(m_rd->m_fields.find("name")==m_rd->m_fields.end())return -1; + return m_rd->m_fields[name].reg; + } + void writeHW(); + void writeRegisterHW(int i); + unsigned writeRegisterHW(int i, unsigned short val); + void disableThresholdHW(bool dis); + unsigned readRegisterHW(int i, unsigned short &val); + void readRegisterHW(int i); + int verifyConfigHW(std::vector<unsigned> &inpvec); + unsigned decodeGlobalRecord(std::vector<unsigned> inpvec, int i, unsigned short& val); + virtual void printFields(std::ostream &os)=0; + void printRegisters(std::ostream &os); + void printShadowRegisterAB(std::ostream &os); + void printShadowRegisterC(std::ostream &os); + void addField(const char* name, int reg, int bitpos, int srab, int src, int width, bool reverse); + void addParameter(const char* name, const char* field); + void enableSrHW(bool on); + std::string lookupParameter(const char* name); + // accessor function for daughter class's static members + virtual RegisterDef* getDef()=0; + + protected: + unsigned m_chipId; + bool m_clkOutMode; + FECommands* m_commands; + RegisterDef *m_rd; + unsigned short *m_regw;// write registers + unsigned short *m_regr;// readback + unsigned short *m_srab;//shadow register AB + unsigned short *m_src;// shadow register C + + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/IPCFEI4AModule.cc b/rce/rcecalib/config/FEI4/IPCFEI4AModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..9c434d94c0717f0ca6f82aa49b3def6608c335e3 --- /dev/null +++ b/rce/rcecalib/config/FEI4/IPCFEI4AModule.cc @@ -0,0 +1,314 @@ +#ifndef FEI4__IPCMODULE_CC +#define FEI4__IPCMODULE_CC +#include "rcecalib/util/RceName.hh" +#include "rcecalib/config/FEI4/IPCFEI4AModule.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/HW/SerialIF.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace FEI4{ + +template <class TP> +IPCFEI4AModule<TP>::IPCFEI4AModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI4AAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + FEI4AModule(name, id, inLink, outLink, fmt){ + // std::cout<<"IPCFEI4AModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCFEI4AModule<TP>::~IPCFEI4AModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCFEI4AModule<TP>::IPCsetChipAddress(CORBA::ULong addr){ + m_commands->setAddr(addr); +} +template <class TP> +CORBA::Long IPCFEI4AModule<TP>::IPCverifyModuleConfigHW(){ + return verifyModuleConfigHW(); +} +template <class TP> +CORBA::Long IPCFEI4AModule<TP>::IPCdownloadConfig(const ipc::PixelFEI4AConfig &config){ + // geographical address + m_gAddr=config.FECommand.address; + m_commands->setAddr(m_gAddr); + + + const ipc::PixelFEI4AGlobal *cfg=&config.FEGlobal; + // global register + m_global->setField("TrigCnt", cfg->TrigCnt , GlobalRegister::SW); + m_global->setField("Conf_AddrEnable", cfg->Conf_AddrEnable , GlobalRegister::SW); + m_global->setField("Reg2Spare", cfg->Reg2Spare , GlobalRegister::SW); + m_global->setField("ErrMask0", cfg->ErrMask0 , GlobalRegister::SW); + m_global->setField("ErrMask1", cfg->ErrMask1 , GlobalRegister::SW); + m_global->setField("PrmpVbpRight", cfg->PrmpVbpRight , GlobalRegister::SW); + m_global->setField("Vthin", cfg->Vthin , GlobalRegister::SW); + m_global->setField("DisVbn_CPPM", cfg->DisVbn_CPPM , GlobalRegister::SW); + m_global->setField("PrmpVbp", cfg->PrmpVbp , GlobalRegister::SW); + m_global->setField("TdacVbp", cfg->TdacVbp , GlobalRegister::SW); + m_global->setField("DisVbn", cfg->DisVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbn", cfg->Amp2Vbn , GlobalRegister::SW); + m_global->setField("Amp2VbpFol", cfg->Amp2VbpFol , GlobalRegister::SW); + m_global->setField("PrmpVbpTop", cfg->PrmpVbpTop , GlobalRegister::SW); + m_global->setField("Amp2Vbp", cfg->Amp2Vbp , GlobalRegister::SW); + m_global->setField("FdacVbn", cfg->FdacVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbpf", cfg->Amp2Vbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnFol", cfg->PrmpVbnFol , GlobalRegister::SW); + m_global->setField("PrmpVbpLeft", cfg->PrmpVbpLeft , GlobalRegister::SW); + m_global->setField("PrmpVbpf", cfg->PrmpVbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnLcc", cfg->PrmpVbnLcc , GlobalRegister::SW); + m_global->setField("PxStrobes", cfg->PxStrobes , GlobalRegister::SW); + m_global->setField("S0", cfg->S0 , GlobalRegister::SW); + m_global->setField("S1", cfg->S1 , GlobalRegister::SW); + m_global->setField("LVDSDrvIref", cfg->LVDSDrvIref , GlobalRegister::SW); + m_global->setField("BonnDac", cfg->BonnDac , GlobalRegister::SW); + m_global->setField("PllIbias", cfg->PllIbias , GlobalRegister::SW); + m_global->setField("LVDSDrvVos", cfg->LVDSDrvVos , GlobalRegister::SW); + m_global->setField("TempSensBias", cfg->TempSensBias , GlobalRegister::SW); + m_global->setField("PllIcp", cfg->PllIcp , GlobalRegister::SW); + m_global->setField("Reg17Spare", cfg->Reg17Spare , GlobalRegister::SW); + m_global->setField("PlsrIdacRamp", cfg->PlsrIdacRamp , GlobalRegister::SW); + m_global->setField("Reg18Spare", cfg->Reg18Spare , GlobalRegister::SW); + m_global->setField("PlsrVgOPamp", cfg->PlsrVgOPamp , GlobalRegister::SW); + m_global->setField("PlsrDacBias", cfg->PlsrDacBias , GlobalRegister::SW); + m_global->setField("Reg19Spare", cfg->Reg19Spare , GlobalRegister::SW); + m_global->setField("Vthin_AltCoarse", cfg->Vthin_AltCoarse , GlobalRegister::SW); + m_global->setField("Vthin_AltFine", cfg->Vthin_AltFine , GlobalRegister::SW); + m_global->setField("PlsrDAC", cfg->PlsrDAC , GlobalRegister::SW); + m_global->setField("DIGHITIN_Sel", cfg->DIGHITIN_Sel , GlobalRegister::SW); + m_global->setField("DINJ_Override", cfg->DINJ_Override , GlobalRegister::SW); + m_global->setField("HITLD_In", cfg->HITLD_In , GlobalRegister::SW); + m_global->setField("Reg21Spare", cfg->Reg21Spare , GlobalRegister::SW); + m_global->setField("Reg22Spare2", cfg->Reg22Spare2 , GlobalRegister::SW); + m_global->setField("Colpr_Addr", cfg->Colpr_Addr , GlobalRegister::SW); + m_global->setField("Colpr_Mode", cfg->Colpr_Mode , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg0", cfg->DisableColumnCnfg0 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg1", cfg->DisableColumnCnfg1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg2", cfg->DisableColumnCnfg2 , GlobalRegister::SW); + m_global->setField("TrigLat", cfg->TrigLat , GlobalRegister::SW); + m_global->setField("CMDcnt", cfg->CMDcnt , GlobalRegister::SW); + m_global->setField("StopModeCnfg", cfg->StopModeCnfg , GlobalRegister::SW); + m_global->setField("HitDiscCnfg", cfg->HitDiscCnfg , GlobalRegister::SW); + m_global->setField("EN_PLL", cfg->EN_PLL , GlobalRegister::SW); + m_global->setField("Efuse_sense", cfg->Efuse_sense , GlobalRegister::SW); + m_global->setField("Stop_Clk", cfg->Stop_Clk , GlobalRegister::SW); + m_global->setField("ReadErrorReq", cfg->ReadErrorReq , GlobalRegister::SW); + m_global->setField("ReadSkipped", cfg->ReadSkipped , GlobalRegister::SW); + m_global->setField("Reg27Spare", cfg->Reg27Spare , GlobalRegister::SW); + m_global->setField("GateHitOr", cfg->GateHitOr , GlobalRegister::SW); + m_global->setField("CalEn", cfg->CalEn , GlobalRegister::SW); + m_global->setField("SR_clr", cfg->SR_clr , GlobalRegister::SW); + m_global->setField("Latch_en", cfg->Latch_en , GlobalRegister::SW); + m_global->setField("SR_Clock", cfg->SR_Clock , GlobalRegister::SW); + m_global->setField("LVDSDrvSet06", cfg->LVDSDrvSet06 , GlobalRegister::SW); + m_global->setField("Reg28Spare", cfg->Reg28Spare , GlobalRegister::SW); + m_global->setField("EN40M", cfg->EN40M , GlobalRegister::SW); + m_global->setField("EN80M", cfg->EN80M , GlobalRegister::SW); + m_global->setField("CLK1", cfg->CLK1 , GlobalRegister::SW); + m_global->setField("CLK0", cfg->CLK0 , GlobalRegister::SW); + m_global->setField("EN160M", cfg->EN160M , GlobalRegister::SW); + m_global->setField("EN320M", cfg->EN320M , GlobalRegister::SW); + m_global->setField("Reg29Spare1", cfg->Reg29Spare1 , GlobalRegister::SW); + m_global->setField("no8b10b", cfg->no8b10b , GlobalRegister::SW); + m_global->setField("Clk2OutCnfg", cfg->Clk2OutCnfg , GlobalRegister::SW); + m_global->setField("EmptyRecord", cfg->EmptyRecord , GlobalRegister::SW); + m_global->setField("Reg29Spare2", cfg->Reg29Spare2 , GlobalRegister::SW); + m_global->setField("LVDSDrvEn", cfg->LVDSDrvEn , GlobalRegister::SW); + m_global->setField("LVDSDrvSet30", cfg->LVDSDrvSet30 , GlobalRegister::SW); + m_global->setField("LVDSDrvSet12", cfg->LVDSDrvSet12 , GlobalRegister::SW); + m_global->setField("PlsrRiseUpTau", cfg->PlsrRiseUpTau , GlobalRegister::SW); + m_global->setField("PlsrPwr", cfg->PlsrPwr , GlobalRegister::SW); + m_global->setField("PlsrDelay", cfg->PlsrDelay , GlobalRegister::SW); + m_global->setField("ExtDigCalSW", cfg->ExtDigCalSW , GlobalRegister::SW); + m_global->setField("ExtAnaCalSW", cfg->ExtAnaCalSW , GlobalRegister::SW); + m_global->setField("Reg31Spare", cfg->Reg31Spare , GlobalRegister::SW); + m_global->setField("SELB0", cfg->SELB0 , GlobalRegister::SW); + m_global->setField("SELB1", cfg->SELB1 , GlobalRegister::SW); + m_global->setField("SELB2", cfg->SELB2 , GlobalRegister::SW); + m_global->setField("EfuseCref", cfg->EfuseCref , GlobalRegister::SW); + m_global->setField("Chip_SN", cfg->Chip_SN , GlobalRegister::SW); + + setVcalCoeff(0, config.FECalib.vcalCoeff[0]); + setVcalCoeff(1, config.FECalib.vcalCoeff[1]); + setVcalCoeff(2, config.FECalib.vcalCoeff[2]); + setVcalCoeff(3, config.FECalib.vcalCoeff[3]); + setCapVal(0, config.FECalib.cinjLo); + setCapVal(1, config.FECalib.cinjHi); + + + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + //Pixel DACs + m_pixel->setField(PixelRegister::tdac, j+1, i+1, config.FETrims.dacThresholdTrim[i][j]); + m_pixel->setField(PixelRegister::fdac, j+1, i+1, config.FETrims.dacFeedbackTrim[i][j]); + //Mask bits + m_pixel->setField(PixelRegister::enable, j+1, i+1, config.FEMasks[i][j]>>ipc::enable); + m_pixel->setField(PixelRegister::largeCap, j+1, i+1, config.FEMasks[i][j]>>ipc::largeCap); + m_pixel->setField(PixelRegister::smallCap, j+1, i+1, config.FEMasks[i][j]>>ipc::smallCap); + m_pixel->setField(PixelRegister::hitbus, j+1, i+1, config.FEMasks[i][j]>>ipc::hitbus); + } + } + // Configure the formatter + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + pt->put("HitDiscCnfg",cfg->HitDiscCnfg); + AbsFormatter* fmt=getFormatter(); + if(fmt){ + std::cout<<"%%%%%%%%% Configuring Formatter"<<std::endl; + fmt->configure(pt); + } + delete pt; + + std::cout<<"Configure done"<<std::endl; + //dumpConfig(); + return 0; +} + +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val){ + switchModeHW(FECommands::CONF); + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->writeRegisterHW(reg, val); +} + +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->readRegisterHW(reg, val); +} +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCclearPixelLatches(){ + SerialIF::setChannelInMask(1<<getInLink()); + // choose double column + m_global->setField("Colpr_Addr", 0, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 3, GlobalRegister::HW); // all columns + setupS0S1HitldHW(0, 0, 0); + setupGlobalPulseHW(GlobalRegister::SR_clr); //latch enable + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + //now clear latches + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + setupPixelStrobesHW(0x1fff); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + setupPixelStrobesHW(0);//clear register + setupGlobalPulseHW(0); //clear register + delete bs; + return 0; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv){ + // clear pixel latches + //IPCclearPixelLatches(); + //retv=new ipc::uvec; + //return 0; + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + + if(data.length()!=PixelRegister::DROW_WORDS)return BAD_SIZE; //wrong amount of data + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + + switchModeHW(FECommands::CONF); + + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)&data[0], retvec); + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs); //global pulse + delete bs; + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + } + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4AModule<TP>::IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + if(dcol>=PixelRegister::N_COLS/2)return BAD_DCOL; + // set config mode + switchModeHW(FECommands::CONF); + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + SerialIF::send(bs); //global pulse + delete bs; + } + //shift out bits and refill with config register. + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)m_pixel->getDoubleColumn(bit, dcol), retvec); + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + +template <class TP> +void IPCFEI4AModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCFEI4AModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/IPCFEI4AModule.hh b/rce/rcecalib/config/FEI4/IPCFEI4AModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..5df47ea3d10e82b62e897bb48b8188d8af98e25f --- /dev/null +++ b/rce/rcecalib/config/FEI4/IPCFEI4AModule.hh @@ -0,0 +1,32 @@ +#ifndef IPCFEI4AMODULE_HH +#define IPCFEI4AMODULE_HH + +#include "rcecalib/config/FEI4/FEI4AModule.hh" +#include "ipc/object.h" +#include "IPCFEI4AAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI4{ +template <class TP = ipc::single_thread> +class IPCFEI4AModule: public IPCNamedObject<POA_ipc::IPCFEI4AAdapter,TP>, public FEI4::FEI4AModule { +public: + IPCFEI4AModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + ~IPCFEI4AModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelFEI4AConfig &config); + void IPCsetChipAddress(CORBA::ULong addr); + CORBA::ULong IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val); + CORBA::ULong IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val); + CORBA::ULong IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv); + CORBA::ULong IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv); + CORBA::ULong IPCclearPixelLatches(); + CORBA::Long IPCverifyModuleConfigHW(); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/rcecalib/config/FEI4/IPCFEI4BModule.cc b/rce/rcecalib/config/FEI4/IPCFEI4BModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..e8cbe8d0586d749cc694c366931d244d1831fc82 --- /dev/null +++ b/rce/rcecalib/config/FEI4/IPCFEI4BModule.cc @@ -0,0 +1,331 @@ +#ifndef FEI4__FEI4BIPCMODULE_CC +#define FEI4__FEI4BIPCMODULE_CC +#include "rcecalib/util/RceName.hh" +#include "rcecalib/config/FEI4/IPCFEI4BModule.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/HW/SerialIF.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + + +namespace FEI4{ + +template <class TP> +IPCFEI4BModule<TP>::IPCFEI4BModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCFEI4BAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + FEI4BModule(name, id, inLink, outLink, fmt){ + // std::cout<<"IPCFEI4BModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCFEI4BModule<TP>::~IPCFEI4BModule(){ + try { + IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCFEI4BModule<TP>::IPCsetChipAddress(CORBA::ULong addr){ + m_commands->setAddr(addr); +} +template <class TP> +CORBA::Long IPCFEI4BModule<TP>::IPCverifyModuleConfigHW(){ + return verifyModuleConfigHW(); +} +template <class TP> +CORBA::Long IPCFEI4BModule<TP>::IPCdownloadConfig(const ipc::PixelFEI4BConfig &config){ + // geographical address + m_gAddr=config.FECommand.address; + m_commands->setAddr(m_gAddr); + + const ipc::PixelFEI4BGlobal *cfg=&config.FEGlobal; + // global register + m_global->setField("TrigCnt", cfg->TrigCnt , GlobalRegister::SW); + m_global->setField("Conf_AddrEnable", cfg->Conf_AddrEnable , GlobalRegister::SW); + m_global->setField("Reg2Spare", cfg->Reg2Spare , GlobalRegister::SW); + m_global->setField("ErrMask0", cfg->ErrMask0 , GlobalRegister::SW); + m_global->setField("ErrMask1", cfg->ErrMask1 , GlobalRegister::SW); + m_global->setField("PrmpVbpRight", cfg->PrmpVbpRight , GlobalRegister::SW); + m_global->setField("BufVgOpAmp", cfg->BufVgOpAmp , GlobalRegister::SW); + m_global->setField("Reg6Spare", cfg->Reg6Spare , GlobalRegister::SW); + m_global->setField("PrmpVbp", cfg->PrmpVbp , GlobalRegister::SW); + m_global->setField("TdacVbp", cfg->TdacVbp , GlobalRegister::SW); + m_global->setField("DisVbn", cfg->DisVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbn", cfg->Amp2Vbn , GlobalRegister::SW); + m_global->setField("Amp2VbpFol", cfg->Amp2VbpFol , GlobalRegister::SW); + m_global->setField("Reg9Spare", cfg->Reg9Spare , GlobalRegister::SW); + m_global->setField("Amp2Vbp", cfg->Amp2Vbp , GlobalRegister::SW); + m_global->setField("FdacVbn", cfg->FdacVbn , GlobalRegister::SW); + m_global->setField("Amp2Vbpf", cfg->Amp2Vbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnFol", cfg->PrmpVbnFol , GlobalRegister::SW); + m_global->setField("PrmpVbpLeft", cfg->PrmpVbpLeft , GlobalRegister::SW); + m_global->setField("PrmpVbpf", cfg->PrmpVbpf , GlobalRegister::SW); + m_global->setField("PrmpVbnLcc", cfg->PrmpVbnLcc , GlobalRegister::SW); + m_global->setField("Reg13Spare", cfg->Reg13Spare , GlobalRegister::SW); + m_global->setField("PxStrobes", cfg->PxStrobes , GlobalRegister::SW); + m_global->setField("S0", cfg->S0 , GlobalRegister::SW); + m_global->setField("S1", cfg->S1 , GlobalRegister::SW); + m_global->setField("LVDSDrvIref", cfg->LVDSDrvIref , GlobalRegister::SW); + m_global->setField("GADCOpAmp", cfg->GADCOpAmp , GlobalRegister::SW); + m_global->setField("PllIbias", cfg->PllIbias , GlobalRegister::SW); + m_global->setField("LVDSDrvVos", cfg->LVDSDrvVos , GlobalRegister::SW); + m_global->setField("TempSensBias", cfg->TempSensBias , GlobalRegister::SW); + m_global->setField("PllIcp", cfg->PllIcp , GlobalRegister::SW); + m_global->setField("Reg17Spare", cfg->Reg17Spare , GlobalRegister::SW); + m_global->setField("PlsrIdacRamp", cfg->PlsrIdacRamp , GlobalRegister::SW); + m_global->setField("VrefDigTune", cfg->VrefDigTune , GlobalRegister::SW); + m_global->setField("PlsrVgOPamp", cfg->PlsrVgOPamp , GlobalRegister::SW); + m_global->setField("PlsrDacBias", cfg->PlsrDacBias , GlobalRegister::SW); + m_global->setField("VrefAnTune", cfg->VrefAnTune , GlobalRegister::SW); + m_global->setField("Vthin_AltCoarse", cfg->Vthin_AltCoarse , GlobalRegister::SW); + m_global->setField("Vthin_AltFine", cfg->Vthin_AltFine , GlobalRegister::SW); + m_global->setField("PlsrDAC", cfg->PlsrDAC , GlobalRegister::SW); + m_global->setField("DIGHITIN_Sel", cfg->DIGHITIN_Sel , GlobalRegister::SW); + m_global->setField("DINJ_Override", cfg->DINJ_Override , GlobalRegister::SW); + m_global->setField("HITLD_In", cfg->HITLD_In , GlobalRegister::SW); + m_global->setField("Reg21Spare", cfg->Reg21Spare , GlobalRegister::SW); + m_global->setField("Reg22Spare2", cfg->Reg22Spare2 , GlobalRegister::SW); + m_global->setField("Colpr_Addr", cfg->Colpr_Addr , GlobalRegister::SW); + m_global->setField("Colpr_Mode", cfg->Colpr_Mode , GlobalRegister::SW); + m_global->setField("Reg22Spare1", cfg->Reg22Spare1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg0", cfg->DisableColumnCnfg0 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg1", cfg->DisableColumnCnfg1 , GlobalRegister::SW); + m_global->setField("DisableColumnCnfg2", cfg->DisableColumnCnfg2 , GlobalRegister::SW); + m_global->setField("TrigLat", cfg->TrigLat , GlobalRegister::SW); + m_global->setField("CMDcnt", cfg->CMDcnt , GlobalRegister::SW); + m_global->setField("StopModeCnfg", cfg->StopModeCnfg , GlobalRegister::SW); + m_global->setField("HitDiscCnfg", cfg->HitDiscCnfg , GlobalRegister::SW); + m_global->setField("EN_PLL", cfg->EN_PLL , GlobalRegister::SW); + m_global->setField("Efuse_sense", cfg->Efuse_sense , GlobalRegister::SW); + m_global->setField("Stop_Clk", cfg->Stop_Clk , GlobalRegister::SW); + m_global->setField("ReadErrorReq", cfg->ReadErrorReq , GlobalRegister::SW); + m_global->setField("Reg27Spare1", cfg->Reg27Spare1 , GlobalRegister::SW); + m_global->setField("GADC_Enable", cfg->GADC_Enable , GlobalRegister::SW); + m_global->setField("ShiftReadBack", cfg->ShiftReadBack , GlobalRegister::SW); + m_global->setField("Reg27Spare2", cfg->Reg27Spare2 , GlobalRegister::SW); + m_global->setField("GateHitOr", cfg->GateHitOr , GlobalRegister::SW); + m_global->setField("CalEn", cfg->CalEn , GlobalRegister::SW); + m_global->setField("SR_clr", cfg->SR_clr , GlobalRegister::SW); + m_global->setField("Latch_en", cfg->Latch_en , GlobalRegister::SW); + m_global->setField("SR_Clock", cfg->SR_Clock , GlobalRegister::SW); + m_global->setField("LVDSDrvSet06", cfg->LVDSDrvSet06 , GlobalRegister::SW); + m_global->setField("Reg28Spare", cfg->Reg28Spare , GlobalRegister::SW); + m_global->setField("EN40M", cfg->EN40M , GlobalRegister::SW); + m_global->setField("EN80M", cfg->EN80M , GlobalRegister::SW); + m_global->setField("CLK1", cfg->CLK1 , GlobalRegister::SW); + m_global->setField("CLK0", cfg->CLK0 , GlobalRegister::SW); + m_global->setField("EN160M", cfg->EN160M , GlobalRegister::SW); + m_global->setField("EN320M", cfg->EN320M , GlobalRegister::SW); + m_global->setField("Reg29Spare1", cfg->Reg29Spare1 , GlobalRegister::SW); + m_global->setField("no8b10b", cfg->no8b10b , GlobalRegister::SW); + m_global->setField("Clk2OutCnfg", cfg->Clk2OutCnfg , GlobalRegister::SW); + m_global->setField("EmptyRecord", cfg->EmptyRecord , GlobalRegister::SW); + m_global->setField("Reg29Spare2", cfg->Reg29Spare2 , GlobalRegister::SW); + m_global->setField("LVDSDrvEn", cfg->LVDSDrvEn , GlobalRegister::SW); + m_global->setField("LVDSDrvSet30", cfg->LVDSDrvSet30 , GlobalRegister::SW); + m_global->setField("LVDSDrvSet12", cfg->LVDSDrvSet12 , GlobalRegister::SW); + m_global->setField("TempSensDiodeSel", cfg->TempSensDiodeSel , GlobalRegister::SW); + m_global->setField("TempSensDisable", cfg->TempSensDisable , GlobalRegister::SW); + m_global->setField("IleakRange", cfg->IleakRange , GlobalRegister::SW); + m_global->setField("Reg30Spare", cfg->Reg30Spare , GlobalRegister::SW); + m_global->setField("PlsrRiseUpTau", cfg->PlsrRiseUpTau , GlobalRegister::SW); + m_global->setField("PlsrPwr", cfg->PlsrPwr , GlobalRegister::SW); + m_global->setField("PlsrDelay", cfg->PlsrDelay , GlobalRegister::SW); + m_global->setField("ExtDigCalSW", cfg->ExtDigCalSW , GlobalRegister::SW); + m_global->setField("ExtAnaCalSW", cfg->ExtAnaCalSW , GlobalRegister::SW); + m_global->setField("Reg31Spare", cfg->Reg31Spare , GlobalRegister::SW); + m_global->setField("GADCSel", cfg->GADCSel , GlobalRegister::SW); + m_global->setField("SELB0", cfg->SELB0 , GlobalRegister::SW); + m_global->setField("SELB1", cfg->SELB1 , GlobalRegister::SW); + m_global->setField("SELB2", cfg->SELB2 , GlobalRegister::SW); + m_global->setField("Reg34Spare1", cfg->Reg34Spare1 , GlobalRegister::SW); + m_global->setField("PrmpVbpMsnEn", cfg->PrmpVbpMsnEn , GlobalRegister::SW); + m_global->setField("Reg34Spare2", cfg->Reg34Spare2 , GlobalRegister::SW); + m_global->setField("Chip_SN", cfg->Chip_SN , GlobalRegister::SW); + m_global->setField("Reg1Spare", cfg->Reg1Spare , GlobalRegister::SW); + m_global->setField("SmallHitErase", cfg->SmallHitErase , GlobalRegister::SW); + m_global->setField("Eventlimit", cfg->Eventlimit , GlobalRegister::SW); + + setVcalCoeff(0, config.FECalib.vcalCoeff[0]); + setVcalCoeff(1, config.FECalib.vcalCoeff[1]); + setVcalCoeff(2, config.FECalib.vcalCoeff[2]); + setVcalCoeff(3, config.FECalib.vcalCoeff[3]); + setCapVal(0, config.FECalib.cinjLo); + setCapVal(1, config.FECalib.cinjHi); + + + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + //Pixel DACs + m_pixel->setField(PixelRegister::tdac, j+1, i+1, config.FETrims.dacThresholdTrim[i][j]); + m_pixel->setField(PixelRegister::fdac, j+1, i+1, config.FETrims.dacFeedbackTrim[i][j]); + //Mask bits + m_pixel->setField(PixelRegister::enable, j+1, i+1, config.FEMasks[i][j]>>ipc::enable); + m_pixel->setField(PixelRegister::largeCap, j+1, i+1, config.FEMasks[i][j]>>ipc::largeCap); + m_pixel->setField(PixelRegister::smallCap, j+1, i+1, config.FEMasks[i][j]>>ipc::smallCap); + m_pixel->setField(PixelRegister::hitbus, j+1, i+1, config.FEMasks[i][j]>>ipc::hitbus); + } + } + // Configure the formatter + AbsFormatter* fmt=getFormatter(); + if(fmt){ + std::cout<<"%%%%%%%%% Configuring Formatter"<<std::endl; + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + pt->put("HitDiscCnfg",cfg->HitDiscCnfg); + fmt->configure(pt); + delete pt; + } + + std::cout<<"Configure done"<<std::endl; + //dumpConfig(std::cout); + return 0; +} + +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val){ + switchModeHW(FECommands::CONF); + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->writeRegisterHW(reg, val); +} + +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + return m_global->readRegisterHW(reg, val); +} +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCclearPixelLatches(){ + SerialIF::setChannelInMask(1<<getInLink()); + // choose double column + m_global->setField("Colpr_Addr", 0, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 3, GlobalRegister::HW); // all columns + setupS0S1HitldHW(0, 0, 0); + setupGlobalPulseHW(GlobalRegister::SR_clr); //latch enable + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + //now clear latches + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + setupPixelStrobesHW(0x1fff); + SerialIF::send(bs, SerialIF::DONT_CLEAR); //global pulse + setupPixelStrobesHW(0);//clear register + setupGlobalPulseHW(0); //clear register + delete bs; + return 0; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv){ + // clear pixel latches + //IPCclearPixelLatches(); + //retv=new ipc::uvec; + //return 0; + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + + if(data.length()!=PixelRegister::DROW_WORDS)return BAD_SIZE; //wrong amount of data + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + + switchModeHW(FECommands::CONF); + + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + m_global->setField("ShiftReadBack",0, GlobalRegister::HW); + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)&data[0], retvec); + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + bs->push_back(0); + SerialIF::send(bs); //global pulse + delete bs; + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + } + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + + // Function to be called directly from Linux for debugging purposes. +template <class TP> +CORBA::ULong IPCFEI4BModule<TP>::IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv){ + SerialIF::setChannelInMask(1<<getInLink()); + SerialIF::setChannelOutMask(1<<getOutLink()); + std::vector<unsigned> retvec; + if(bit>=PixelRegister::N_PIXEL_REGISTER_BITS)return BAD_PIXREG; + if(dcol>=PixelRegister::N_COLS/2)return BAD_DCOL; + // set config mode + switchModeHW(FECommands::CONF); + // choose double column + m_global->setField("Colpr_Addr", dcol, GlobalRegister::SW); + m_global->setField("Colpr_Mode", 0, GlobalRegister::HW); // only write to 1 column pair + m_global->setField("ShiftReadBack",1, GlobalRegister::HW); //enable readback + if(bit!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + setupS0S1HitldHW(1, 1, 0); + setupGlobalPulseHW(GlobalRegister::SR_Clock); //SR clock + //set up strobe bit + setupPixelStrobesHW(1<<bit); + BitStream *bs=new BitStream; + bs->push_back(0); + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + SerialIF::send(bs); //global pulse + delete bs; + } + //shift out bits and refill with config register. + m_global->setField("ShiftReadBack",0, GlobalRegister::SW); //setupGlobalPulse does the HW write for that register + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + setupS0S1HitldHW(0, 0, 0); + unsigned stat=m_pixel->writeDoubleColumnHW((const unsigned*)m_pixel->getDoubleColumn(bit, dcol), retvec); + retv=new ipc::uvec; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return stat; +} + +template <class TP> +void IPCFEI4BModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCFEI4BModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/IPCFEI4BModule.hh b/rce/rcecalib/config/FEI4/IPCFEI4BModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..d521b2760436c206de19e72ece5babc67a16858c --- /dev/null +++ b/rce/rcecalib/config/FEI4/IPCFEI4BModule.hh @@ -0,0 +1,32 @@ +#ifndef IPCFEI4BMODULE_HH +#define IPCFEI4BMODULE_HH + +#include "rcecalib/config/FEI4/FEI4BModule.hh" +#include "ipc/object.h" +#include "IPCFEI4BAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace FEI4{ +template <class TP = ipc::single_thread> +class IPCFEI4BModule: public IPCNamedObject<POA_ipc::IPCFEI4BAdapter,TP>, public FEI4::FEI4BModule { +public: + IPCFEI4BModule(IPCPartition & p, const char * name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + ~IPCFEI4BModule(); + CORBA::Long IPCdownloadConfig(const ipc::PixelFEI4BConfig &config); + void IPCsetChipAddress(CORBA::ULong addr); + CORBA::ULong IPCwriteHWglobalRegister(CORBA::Long reg, CORBA::UShort val); + CORBA::ULong IPCreadHWglobalRegister(CORBA::Long reg, CORBA::UShort &val); + CORBA::ULong IPCwriteDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, const ipc::uvec & data, ipc::uvec_out retv); + CORBA::ULong IPCreadDoubleColumnHW(CORBA::ULong bit, CORBA::ULong dcol, ipc::uvec_out retv); + CORBA::ULong IPCclearPixelLatches(); + CORBA::Long IPCverifyModuleConfigHW(); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/rcecalib/config/FEI4/MaskStageFactory.cc b/rce/rcecalib/config/FEI4/MaskStageFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..1f34bc28feacc9715d46dd0848b6bbc4acfab473 --- /dev/null +++ b/rce/rcecalib/config/FEI4/MaskStageFactory.cc @@ -0,0 +1,149 @@ +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/config/FEI4/Module.hh" +#include "rcecalib/config/FEI4/PixelRegister.hh" +#include "rcecalib/config/FEI4/AnalogMaskStaging.hh" +#include "rcecalib/config/FEI4/FastAnalogMaskStaging.hh" +#include "rcecalib/config/FEI4/AnalogSingleMaskStaging.hh" +#include "rcecalib/config/FEI4/AnalogColprMaskStaging.hh" +#include "rcecalib/config/FEI4/AnalogSimpleColprMaskStaging.hh" +#include "rcecalib/config/FEI4/AnalogColpr2MaskStagingFei4a.hh" +#include "rcecalib/config/FEI4/DigitalMaskStaging.hh" +#include "rcecalib/config/FEI4/DigStepMaskStaging.hh" +#include "rcecalib/config/FEI4/CrosstalkMaskStaging.hh" +#include "rcecalib/config/FEI4/CrosstalkFastMaskStaging.hh" +#include "rcecalib/config/FEI4/NoiseMaskStaging.hh" +#include "rcecalib/config/FEI4/DiffusionMaskStaging.hh" +#include "rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.hh" +#include "rcecalib/config/FEI4/MaskStaging26880.hh" +#include "rcecalib/config/FEI4/PatternMaskStaging.hh" +#include "rcecalib/config/Masks.hh" +#include <assert.h> +#include <string> + +using namespace FEI4; + +template<> Masks MaskStageFactory::createIOmasks<FEI4::Module>(const char* maskStagingMode){ + Masks m; + m.oMask=m.iMask=m.xtalk_on=m.xtalk_off=m.crosstalking=0; + std::string stagingMode(maskStagingMode); + if(stagingMode=="FEI4_ENA_NOCAP"){ + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]); + } else if(std::string(stagingMode)=="FEI4_ENA_SCAP"){ + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]); + } else if(std::string(stagingMode)=="FEI4_ENA_LCAP"){ + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + } else if(std::string(stagingMode)=="FEI4_ENA_BCAP"){ + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + } else if(std::string(stagingMode)=="FEI4_ENA_HITBUS_DIG"){ + PixelRegister::setHitBusMode(1); + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + } else if(std::string(stagingMode)=="FEI4_ENA_HITBUS"){ + PixelRegister::setHitBusMode(1); + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + } else if(std::string(stagingMode)=="FEI4_MONLEAK"){ + PixelRegister::setHitBusMode(0); + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]); + } else if(std::string(stagingMode)=="FEI4_XTALK"){ + m.crosstalking = 1; + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::hitbus]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + + m.xtalk_off=(1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]); + m.xtalk_on=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]); + } else if(std::string(stagingMode)=="FEI4_NOISE"){ + m.oMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::largeCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::smallCap]) + | (1<<PixelRegisterFields::fieldPos[PixelRegister::diginj]); + + m.iMask=(1<<PixelRegisterFields::fieldPos[PixelRegister::enable]); + }else{ + std::cout<<"Mask stage mode "<<stagingMode<<" does not exist."<<std::endl; + m.oMask=0; + m.iMask=0; + } + return m; +} + +template<> +MaskStaging<FEI4::Module>* MaskStageFactory::createMaskStaging(FEI4::Module* mod, const char* maskStagingType, const char* maskStagingMode){ + Masks iomask=createIOmasks<FEI4::Module>(maskStagingMode); + std::string stagingType(maskStagingType); + if(stagingType=="FEI4_COL_ANL_40" || stagingType=="FEI4_COL_ANL_40x8") + return new FEI4::AnalogMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_COL_DIG_40") + return new FEI4::DigitalMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_26880") + return new FEI4::MaskStaging26880(mod, iomask, stagingType); + else if(stagingType.substr(0,6)=="STEPS_") + return new FEI4::DigStepMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_XTALK_26880") + return new FEI4::CrosstalkMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_XTALK_40x8") + return new FEI4::CrosstalkFastMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_DIFFUSION") + return new FEI4::DiffusionMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_ALLCOLS") + return new FEI4::NoiseMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_COL_ANL_1") + return new FEI4::AnalogSingleMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_COLPR2x6FEI4A") + return new FEI4::AnalogColpr2MaskStagingFei4a(mod, iomask, stagingType); + else if(stagingType.substr(0,10)=="FEI4_COLPR") + return new FEI4::AnalogColprMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_MODULECROSSTALK") + return new FEI4::ModuleCrosstalkMaskStaging(mod, iomask, stagingType); + else if(stagingType=="FEI4_PATTERN") + return new FEI4::PatternMaskStaging(mod, iomask, stagingType); + else{ + std::cout<<"Wrong staging type "<<stagingType<<std::endl; + assert(0); + } +} diff --git a/rce/rcecalib/config/FEI4/MaskStaging.cc b/rce/rcecalib/config/FEI4/MaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..3b69ae2596ac4dc0449338536d96be8a2180a031 --- /dev/null +++ b/rce/rcecalib/config/FEI4/MaskStaging.cc @@ -0,0 +1,27 @@ +#include "rcecalib/config/MaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +using namespace FEI4; + +template<> bool MaskStaging<FEI4::Module>::cLow(){ + if (m_masks.crosstalking==0) + return (m_masks.iMask&(1<<FEI4::PixelRegisterFields::fieldPos[FEI4::PixelRegister::smallCap]))!=0; + else + return (m_masks.xtalk_off&(1<<FEI4::PixelRegisterFields::fieldPos[FEI4::PixelRegister::smallCap]))!=0; +} +template<> bool MaskStaging<FEI4::Module>::cHigh(){ + if(m_masks.crosstalking==0) + return (m_masks.iMask&(1<<FEI4::PixelRegisterFields::fieldPos[FEI4::PixelRegister::largeCap]))!=0; + else + return (m_masks.xtalk_off&(1<<FEI4::PixelRegisterFields::fieldPos[FEI4::PixelRegister::largeCap]))!=0; +} + +template<> void MaskStaging<FEI4::Module>::clearBitsHW(){ + m_module->global()->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.oMask&(1<<i)){ + m_module->pixel()->setBitAll(i,0); + m_module->writeDoubleColumnHW(i,i,0,0); + } + } +} diff --git a/rce/rcecalib/config/FEI4/MaskStaging26880.cc b/rce/rcecalib/config/FEI4/MaskStaging26880.cc new file mode 100644 index 0000000000000000000000000000000000000000..0834ba1e77a5a9c295c3ca5c5271608c535f2f5c --- /dev/null +++ b/rce/rcecalib/config/FEI4/MaskStaging26880.cc @@ -0,0 +1,33 @@ +#include "rcecalib/config/FEI4/MaskStaging26880.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + MaskStaging26880::MaskStaging26880(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + } + + void MaskStaging26880::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + unsigned rowstage=maskStage%PixelRegister::N_ROWS; + unsigned colstage=maskStage/PixelRegister::N_ROWS; + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + if(rowstage==0&&colstage!=0){ + pixel->setBitCol(colstage, i, 0); + m_module->writeDoubleColumnHW(i, i, (colstage-1)/2, (colstage-1)/2); + } + pixel->setupMaskStageCol(colstage+1, i, rowstage, PixelRegister::N_ROWS); + // m_pixel->dumpDoubleColumn(i,colstage/2,std::cout); + m_module->writeDoubleColumnHW(i, i, colstage/2, colstage/2); + } + } + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + } +} diff --git a/rce/rcecalib/config/FEI4/MaskStaging26880.hh b/rce/rcecalib/config/FEI4/MaskStaging26880.hh new file mode 100644 index 0000000000000000000000000000000000000000..0961badced3bbd79ae07f3008572dbea302e5010 --- /dev/null +++ b/rce/rcecalib/config/FEI4/MaskStaging26880.hh @@ -0,0 +1,16 @@ +#ifndef FEI426880MASKSTAGING_HH +#define FEI426880MASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + class Module; + class MaskStaging26880: public MaskStaging<FEI4::Module>{ + public: + MaskStaging26880(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/Module.cc b/rce/rcecalib/config/FEI4/Module.cc new file mode 100644 index 0000000000000000000000000000000000000000..8b84e4e8fc6814e0ae2f0146deb3572205bcc704 --- /dev/null +++ b/rce/rcecalib/config/FEI4/Module.cc @@ -0,0 +1,332 @@ +#include "rcecalib/config/FEI4/Module.hh" +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/MaskStageFactory.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include <iostream> +#include <fstream> +#include "ers/ers.h" +#include <stdio.h> + +namespace FEI4{ + + Module::Module(const char* name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + AbsModule(name, id, inlink, outlink, fmt), m_mode(FRAMED), m_maskStaging(0), m_gAddr(-1), m_oneByOne(false){ + // std::cout<<"Module"<<std::endl; + } + Module::~Module(){ + delete m_maskStaging; + //m_timer.Print("Module"); + } + void Module::setupS0S1HitldHW(int s0, int s1, int hitld){ + m_global->setField("S0",s0, GlobalRegister::SW); + m_global->setField("S1",s1, GlobalRegister::HW); //S0 is in the same register + if(m_oneByOne)m_global->setField("HITLD_In",hitld, GlobalRegister::HW); + } + + void Module::setupPixelStrobesHW(unsigned bitmask){ + m_global->setField("PxStrobes",bitmask, GlobalRegister::HW); + } + + // void Frontend::pixelUsrToRaw(BitStream *bs, unsigned bit){ + // } + void Module::setVcalCoeff(unsigned i, float val){ + if(i<4)m_vcalCoeff[i]=val; + } + void Module::setCapVal(unsigned i, float val){ + if(i<2)m_capVal[i]=val; + } + float Module::getVcalCoeff(unsigned i){ + if(i<4)return m_vcalCoeff[i]; + else return -999; + } + float Module::getCapVal(unsigned i){ + if(i<2)return m_capVal[i]; + else return -999; + } + + // TODO: get rid of float + const float Module::dacToElectrons(int fe, int dac){ + if(fe!=0)return -1; + float capacity=6241 * (m_capVal[1]*m_maskStaging->cHigh() + m_capVal[0]*m_maskStaging->cLow()); + float fldac=(float)dac; + //std::cout<<"dac "<<dac<<" electrons "<<capacity*(m_vcalCoeff[0] + (m_vcalCoeff[1] + (m_vcalCoeff[2] + m_vcalCoeff[3]*fldac)*fldac)*fldac)<<std::endl; + return capacity*(m_vcalCoeff[0] + (m_vcalCoeff[1] + (m_vcalCoeff[2] + m_vcalCoeff[3]*fldac)*fldac)*fldac); + } + const int Module::electronsToDac(float ne) { + float min=10000.; + int mini=-1; + for(int i=0;i<1024;i++) { + float diff=(ne-dacToElectrons(0, i)); + if(diff<0.) diff=-diff; + if(diff<min) { + min=diff;mini=i; + } + } + if(mini==-1){ + std::cout<<"WARNING: electronsToDac returning -1 !!"<<std::endl; + } + return mini; + } + + void Module::enableSrHW(bool on){ + //std::cout<<"Switched SR to "<<on<<" for FE "<<getId()<<std::endl; + m_global->enableSrHW(on); + } + + void Module::configureHW(){ + //std::cout<<"Configured HW FE "<<getId()<<std::endl; + // m_global->printFields(std::cout); + resetHW(); + m_global->disableThresholdHW(true); + m_global->writeHW(); + m_global->setField("Colpr_Mode", 0, GlobalRegister::SW); // only write to 1 column pair at a time + writeDoubleColumnHW(0, PixelRegister::N_PIXEL_REGISTER_BITS-1, 0, PixelRegister::N_COLS/2-1); + m_global->disableThresholdHW(false); + //std::ofstream dump("/nfs/cosmicData/out.log"); + //dumpConfig(dump); + //dump.close(); + //SerialIF::writeRegister(13,1); + } + + void Module::resetFE(){ + resetHW(); + } + void Module::resetErrorCountersHW(){ + //std::cout<<"Reset error counters FE "<<getId()<<std::endl; + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + setupGlobalPulseHW(GlobalRegister::ReadErrorReq); //Read and clear errors + SerialIF::send(bs, SerialIF::WAITFORDATA); //global pulse + setupGlobalPulseHW(0); //Clear + delete bs; + } + + void Module::enableDataTakingHW(){ + //std::cout<<"Enabled data taking FE "<<getId()<<std::endl; + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + m_commands->switchMode(bs, FECommands::RUN); + m_commands->sendECR(bs); + m_commands->sendBCR(bs); + SerialIF::send(bs); + delete bs; + } + + void Module::switchToConfigModeHW(){ + //std::cout<<"Switched to Config Mode FE "<<getId()<<std::endl; + switchModeHW(FECommands::CONF); + } + + void Module::switchModeHW(FECommands::MODE mode){ + BitStream *bs=new BitStream; + m_commands->switchMode(bs, mode); + bs->push_back(0); + SerialIF::send(bs, SerialIF::WAITFORDATA); + delete bs; + } + + void Module::writeDoubleColumnHW(unsigned bitLow, unsigned bitHigh, unsigned dcolLow, unsigned dcolHigh){ + BitStream *bs=new BitStream; + m_commands->globalPulse(bs, FECommands::PULSE_WIDTH); + setupS0S1HitldHW(0, 0, 0); + setupGlobalPulseHW(GlobalRegister::Latch_en); //latch enable + for (unsigned i=bitLow; i<=bitHigh;i++){ + //set up strobe bit + setupPixelStrobesHW(1<<i); + for(unsigned j=dcolLow; j<=dcolHigh; j++){ + // std::cout<<"Dcol "<<j<<std::endl; + //set up dcol + m_global->setField("Colpr_Addr", j, GlobalRegister::HW); + m_commands->setAddr(m_gAddr|0x8); + m_pixel->writeDoubleColumnHW(i, j); + m_commands->setAddr(m_gAddr); + if(i!=PixelRegisterFields::fieldPos[PixelRegister::diginj]){ //no latching for diginj + SerialIF::send(bs, SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); //global pulse + } + } + } + setupGlobalPulseHW(0); //clear + setupPixelStrobesHW(0); //clear + + delete bs; + } + + + void Module::setupMaskStageHW(int maskStage) { + //std::cout<<"Mask stage "<<maskStage<<" FE "<<getId()<<std::endl; + if(m_oneByOne==false && maskStage==0 && m_global->getField("HITLD_In")==1){ //HITLD_In is a problem with broadcast + std::cout<<"Module with ID="<<m_id<<" has HITLD_In enabled. Either disable the field or run in one-by-one mode."<<std::endl; + assert(0); + } + //m_global->disableThresholdHW(true); + m_maskStaging->setupMaskStageHW(maskStage); + //m_global->disableThresholdHW(false); + + } + + //set the value in the register but not in the frontend + Module::PAR Module::setParameter(const char* name, int val, GlobalRegister::mode t){ + std::string par=m_global->lookupParameter(name); + if(par!=""){ //it's a global variable + m_global->setField(par.c_str(), val, t); + return GLOBAL; + } + PixelRegister::Field fpar=PixelRegister::lookupParameter(name); + if(fpar!=PixelRegister::not_found){ //it's a pixel variable + setPixelRegisterParameterHW(fpar, val, t); + return PIXEL; + } + if(std::string(name)=="CHARGE"){ + m_global->setField("PlsrDAC", electronsToDac(val), t); + return SPECIAL; + } + if (std::string(name)=="NO_PAR"){ + return SPECIAL; + } + //we have tested all options + char error_message[128]; + sprintf(error_message, "parameter %s was not found.",name); + ERS_ASSERT_MSG(666==NOT_FOUND, error_message); + return NOT_FOUND; + } + + void Module::setPixelRegisterParameterHW(PixelRegister::Field field, unsigned val, GlobalRegister::mode t){ + m_pixel->setFieldAll(field, val); + if(t==GlobalRegister::HW){ + unsigned mode=m_global->getField("Colpr_Mode"); + unsigned addr=m_global->getField("Colpr_Addr"); + m_global->setField("Colpr_Mode", 3, GlobalRegister::SW); // all double columns have the same value, write all at once + writeDoubleColumnHW(PixelRegisterFields::fieldPos[field], PixelRegisterFields::fieldPos[field+1]-1, 0, 0); + m_global->setField("Colpr_Mode", mode, GlobalRegister::SW); + m_global->setField("Colpr_Addr", addr, GlobalRegister::SW); + } + } + + // set a parameter (global or MCC) in the frontend + int Module::setupParameterHW(const char* name, int val){ + //std::cout<<"Setup parameter "<<name<<" val="<<val<<" FE "<<getId()<<std::endl; + //m_timer.Start(); + int retval=0; + PAR rv; + //m_global->disableThresholdHW(true); + rv=setParameter(name, val, GlobalRegister::HW); + //m_global->disableThresholdHW(false); + if(rv==NOT_FOUND)retval=-1; + //m_timer.Stop(); + return retval; + } + + int Module::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + //m_timer.Reset(); + bool isTel=false; + if(getName().substr(0,9)=="Telescope"){ + std::cout<<"Module "<<getId()<<" is a telescope module"<<std::endl; + isTel=true; + } + try{ + // trigger mode + std::string triggerMode=scanOptions->get<std::string>("trigOpt.triggerMode"); + //std::cout<<"trigger Mode is "<<triggerMode<<std::endl; + int xselftrg=0; // 1 for module crosstalk + if(triggerMode=="MIXED"){ + int moduleTrgMask=scanOptions->get<int>("trigOpt.moduleTrgMask"); + xselftrg=(moduleTrgMask&(1<<getOutLink()))!=0; + std::cout<<"xselftrg "<<xselftrg<<" "<<moduleTrgMask<<" "<<getOutLink()<<std::endl; + setParameter("GateHitOr",xselftrg,GlobalRegister::SW); + if(xselftrg==1)std::cout<<"Configuring module "<<getId()<<" with SELFTRIGGER"<<std::endl; + else std::cout<<"Configuring module "<<getId()<<" with regular trigger"<<std::endl; + } else if(triggerMode=="INTERNAL_SELF") setParameter("GateHitOr",1,GlobalRegister::SW); + else setParameter("GateHitOr",0,GlobalRegister::SW); + int diginject=scanOptions->get("trigOpt.optionsMask.DIGITAL_INJECT", 0); + if(diginject)setParameter("DIGHITIN_Sel",1,GlobalRegister::SW); + else setParameter("DIGHITIN_Sel",0,GlobalRegister::SW); + + std::string type = scanOptions->get<std::string>("scanType"); + int override = scanOptions->get("trigOpt.optionsMask.OVERRIDE_LATENCY", 0); + if(type!="CosmicData" || override==true){ //For cosmic data the latency comes from a file unless override is set. + if(!xselftrg) { + if(isTel)setParameter("TrigLat",scanOptions->get<int>("trigOpt.Lvl1_Latency_Secondary"),GlobalRegister::SW); + else setParameter("TrigLat",scanOptions->get<int>("trigOpt.Lvl1_Latency"),GlobalRegister::SW); + } else { + setParameter("TrigLat",scanOptions->get<int>("trigOpt.Lvl1_Latency_Secondary"),GlobalRegister::SW); + std::cout<<"Configured with secondary latency "<<scanOptions->get<int>("trigOpt.Lvl1_Latency_Secondary")<<std::endl; + } + int nev; + if(isTel)nev=scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + else nev=scanOptions->get<int>("trigOpt.nL1AperEvent"); + if(nev==16)nev=0; + setParameter("TrigCnt",nev ,GlobalRegister::SW); + if(override==true){ + if(isTel){ + std::cout<<"Module "<<getId()<<": Overriding latency with "<< + scanOptions->get<int>("trigOpt.Lvl1_Latency_Secondary")<<std::endl; + std::cout<<"Module "<<getId()<<": Overriding conseq triggers with "<< + scanOptions->get<int>("trigOpt.nTriggersPerGroup")<<std::endl; + }else{ + std::cout<<"Module "<<getId()<<": Overriding latency with "<< + scanOptions->get<int>("trigOpt.Lvl1_Latency")<<std::endl; + std::cout<<"Module "<<getId()<<": Overriding conseq triggers with "<< + scanOptions->get<int>("trigOpt.nL1AperEvent")<<std::endl; + } + } + } + setParameter("CMDcnt_delay",scanOptions->get<int>("trigOpt.strobeMCCDelay"),GlobalRegister::SW); + setParameter("CMDcnt_width",scanOptions->get<int>("trigOpt.strobeDuration"),GlobalRegister::SW); + //setParameter("enables",0xffff); + // Global regs + std::string stagingMode=scanOptions->get<std::string>("stagingMode"); + std::string maskStages=scanOptions->get<std::string>("maskStages"); + MaskStageFactory msf; + delete m_maskStaging; + m_maskStaging=msf.createMaskStaging(this, maskStages.c_str(), stagingMode.c_str()); + // set Vcal + std::string par="PlsrDAC"; + if(scanOptions->get("trigOpt.optionsMask.SPECIFY_CHARGE_NOT_VCAL", 0)==1)par="CHARGE"; + setParameter(par.c_str(),scanOptions->get<int>("trigOpt.vcal_charge"),GlobalRegister::SW); + m_oneByOne=scanOptions->get("trigOpt.optionsMask.ONE_BY_ONE", 0); + if(scanOptions->get("trigOpt.optionsMask.SETUP_THRESHOLD", 0)==1){ + unsigned short threshold=scanOptions->get<int>("trigOpt.threshold"); + std::cout<<"Setting threshold to "<<threshold<<std::endl; + setParameter("Vthin_AltFine", threshold, GlobalRegister::SW); + } + if(scanOptions->get<std::string>("DataProc")=="RawFei4Occupancy"){ + std::cout<<m_id<<": RawFei4Occupancy dataproc. Setting HitDiscCnfg to 0"<<std::endl; + setParameter("HitDiscCnfg", 0, GlobalRegister::SW); + } + if(scanOptions->get("trigOpt.optionsMask.CLEAR_MASKS", 0)==1){ + m_pixel->setBitAll(PixelRegister::enable, 1); + m_pixel->setBitAll(PixelRegister::hitbus, 1); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + retval=1; + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + return retval; + } + + + ModuleInfo Module::getModuleInfo(){ + return ModuleInfo(m_name, m_id,m_inLink, m_outLink,Module::N_FRONTENDS,PixelRegister::N_ROWS,PixelRegister::N_COLS, m_formatter); + } + + void Module::dumpConfig(std::ostream &os){ + m_global->printFields(os); + m_pixel->dumpPixelRegister(os); + os<<"Charge injection parameters:"<<std::endl; + os<<"----------------------------"<<std::endl; + os<<"vcalCoeff[0]: "<<getVcalCoeff(0)<<std::endl; + os<<"vcalCoeff[1]: "<<getVcalCoeff(1)<<std::endl; + os<<"vcalCoeff[2]: "<<getVcalCoeff(2)<<std::endl; + os<<"vcalCoeff[3]: "<<getVcalCoeff(3)<<std::endl; + os<<"capValLo: "<<getCapVal(0)<<std::endl; + os<<"capValHi: "<<getCapVal(1)<<std::endl; + } + +}; + diff --git a/rce/rcecalib/config/FEI4/Module.hh b/rce/rcecalib/config/FEI4/Module.hh new file mode 100644 index 0000000000000000000000000000000000000000..6ec6c75d619e73dd730aa712dac27dfe5f9a8f98 --- /dev/null +++ b/rce/rcecalib/config/FEI4/Module.hh @@ -0,0 +1,73 @@ +#ifndef FEI4__MODULE_HH +#define FEI4__MODULE_HH + +#include "rcecalib/config/AbsModule.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/FEI4/GlobalRegister.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/PixelRegister.hh" +#include "rcecalib/config/MaskStaging.hh" +#include "rcecalib/profiler/Profiler.hh" +#include <string> + +class AbsFormatter; + +namespace FEI4{ + + class Module: public AbsModule{ + public: + Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter *fmt); + virtual ~Module(); + enum {N_FRONTENDS=1}; + enum PAR {NOT_FOUND, GLOBAL, PIXEL, SPECIAL}; + enum READOUT_MODE {RAW, FRAMED}; + enum Errors{BAD_SIZE=222, BAD_PIXREG=333, BAD_DCOL=444}; + void configureHW(); + virtual void resetHW()=0; + void resetFE(); + void setupMaskStageHW(int stage); + void setupMaskStageInjHW(int stage); + void enableSrHW(bool on); + void setPixelRegisterParameterHW(PixelRegister::Field field, unsigned val, GlobalRegister::mode t); + void enableDataTakingHW(); + void resetErrorCountersHW(); + virtual int verifyModuleConfigHW()=0; + void switchModeHW(FECommands::MODE mode); + void switchToConfigModeHW(); + int setupParameterHW(const char* name, int val); //HW setup + PAR setParameter(const char* name, int val, GlobalRegister::mode t); // HW or SW + int configureScan(boost::property_tree::ptree* scanOptions); + ModuleInfo getModuleInfo(); + const float dacToElectrons(int fe, int dac); + const int electronsToDac(float ne); + virtual void destroy()=0; + void setVcalCoeff(unsigned i, float val); + void setCapVal(unsigned i, float val); + float getVcalCoeff(unsigned i); + float getCapVal(unsigned i); + void writeDoubleColumnHW(unsigned bitLow, unsigned bitHigh, unsigned dcolLow, unsigned dcolHigh); + void writeGlobalRegisterHW(); + void setupS0S1HitldHW(int s0, int s1, int hitld); + virtual void setupGlobalPulseHW(int pulsereg)=0; + void setupPixelStrobesHW(unsigned bitmask); + void dumpConfig(std::ostream &os); + PixelRegister* pixel(){return m_pixel;} + GlobalRegister* global(){return m_global;} + void setBroadcast(bool on){m_commands->setBroadcast(on);} + +protected: + READOUT_MODE m_mode; + GlobalRegister *m_global; + PixelRegister *m_pixel; + PixelRegister *m_pixel_readback; + FECommands *m_commands; + float m_vcalCoeff[4]; + float m_capVal[2]; + MaskStaging<FEI4::Module> *m_maskStaging; + Profiler::Timer m_timer; + int m_gAddr; + int m_oneByOne; +}; + +}; +#endif diff --git a/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.cc b/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..17203cecc2694c3fa90d510cc5de99aada3cdefe --- /dev/null +++ b/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.cc @@ -0,0 +1,50 @@ +#include "rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + ModuleCrosstalkMaskStaging::ModuleCrosstalkMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + m_nStages=3; + } + + void ModuleCrosstalkMaskStaging::setupMaskStageHW(int maskStage){ + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + // std::cout<<"Setting up mask stage "<<maskStage<<std::endl; + if(global->getField("GateHitOr")==1){ + //std::cout<<"Disabling injection "<<std::endl; + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + global->setField("Colpr_Addr", 40, GlobalRegister::SW); // switch off injection into module + return; + } + //std::cout<<"Injecting "<<std::endl; + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + unsigned dcolStage=maskStage/m_nStages; + unsigned stage=maskStage%m_nStages; + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + pixel->setupMaskStageCol(dcolStage*2+1, i, stage, m_nStages); + if(dcolStage==39)pixel->setupMaskStageCol(80, i, stage, m_nStages); + m_module->writeDoubleColumnHW(i, i, dcolStage, dcolStage); + //m_pixel->setBitCol(maskStage*2+1, i, 1); //enable bit in double column + if(dcolStage!=0){ + if(stage==0)pixel->setBitCol(dcolStage*2-1, i, 0); //disable previous column + //m_pixel->setBitCol(maskStage*2, i, 1); //enable bit in double column + pixel->setupMaskStageCol(dcolStage*2, i, stage, m_nStages); + //if(maskStage==39)m_pixel->setBitCol(80, i, 1); //column 80 is special + m_module->writeDoubleColumnHW(i, i, dcolStage-1, dcolStage-1); + if(dcolStage>1){ + if(stage==0)pixel->setBitCol(dcolStage*2-2, i, 0); + m_module->writeDoubleColumnHW(i, i, dcolStage-2, dcolStage-2); + } + global->setField("Colpr_Addr", dcolStage, GlobalRegister::HW); + } + } + } + } +} diff --git a/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.hh b/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..940685b47429325b09dd3d311798149d5baed1b3 --- /dev/null +++ b/rce/rcecalib/config/FEI4/ModuleCrosstalkMaskStaging.hh @@ -0,0 +1,20 @@ +#ifndef FEI4MODULECROSSTALKMASKSTAGING_HH +#define FEI4MODULECROSSTALKMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class ModuleCrosstalkMaskStaging: public MaskStaging<FEI4::Module>{ + public: + ModuleCrosstalkMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + int m_nStages; + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/ModuleGroup.cc b/rce/rcecalib/config/FEI4/ModuleGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..146bef853bdd0b7d9e6040b76fc9e71294615f3c --- /dev/null +++ b/rce/rcecalib/config/FEI4/ModuleGroup.cc @@ -0,0 +1,210 @@ + +#include <boost/property_tree/ptree.hpp> +#include <stdio.h> +#include "rcecalib/config/FEI4/Module.hh" +#include "rcecalib/config/FEI4/ModuleGroup.hh" +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include "rcecalib/HW/SerialIF.hh" + +namespace FEI4{ + +void ModuleGroup::addModule(Module* module){ + m_modules.push_back(module); + m_channelInMask|=1<<module->getInLink(); + m_channelOutMask|=1<<module->getOutLink(); +} + +void ModuleGroup::deleteModules(){ + for (unsigned i=0; i<m_modules.size();i++){ + //cannot call delete directly because IPC modules need to call _destroy() instead. + m_modules[i]->destroy(); + } + m_modules.clear(); + m_channelInMask=0; + m_channelOutMask=0; +} + +int ModuleGroup::setupParameterHW(const char* name, int val, bool bcOK){ + int retval=0; + int oneByOne=m_oneByOne; + if(bcOK==false)m_oneByOne=true; //always go one by one in certain cases + bool pixelReg=(PixelRegister::lookupParameter(name)!=PixelRegister::not_found); + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + switchToConfigModeHW(); + if(pixelReg==true){ + enableSrHW(false); //disable SR in case it's a pixel reg parameter + }else if(m_oneByOne==false){ + m_modules[0]->setBroadcast(false); + } + if(pixelReg==false || m_oneByOne==true){ // one by one + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + retval+=m_modules[i]->setupParameterHW(name,val); + } + }else{ //it's a pixel param and oneByOne is false => broadcast + m_modules[0]->setupParameterHW(name,val); + } + if(pixelReg==true){ + enableSrHW(true); //enable + if(m_oneByOne==false)m_modules[0]->setBroadcast(false); + } + disableAllInChannels(); + if(bcOK==false)m_oneByOne=oneByOne; //restore value + return retval; +} + +int ModuleGroup::setupMaskStageHW(int stage){ + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + switchToConfigModeHW(); + if(m_oneByOne==true){ + enableSrHW(false); //disable + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->setupMaskStageHW(stage); + m_modules[i]->enableSrHW(false); + } + enableSrHW(true);//enable + }else{ //broadcast + m_modules[0]->setupMaskStageHW(stage); + m_modules[0]->setBroadcast(false); + } + if(stage==0)SerialIF::sendCommand(0x10); //phase calibration + disableAllInChannels(); + return 0; +} + +void ModuleGroup::configureModulesHW(){ + //std::cout<<"Configure Modules HW"<<std::endl; + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + switchToConfigModeHW(); + enableSrHW(false); //disable + if(m_oneByOne==false)m_modules[0]->setBroadcast(false); + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->configureHW(); + m_modules[i]->enableSrHW(false); //disable SR + } + SerialIF::sendCommand(0x10); //phase calibration + disableAllInChannels(); +} + +int ModuleGroup::verifyModuleConfigHW(){ + int retval=0; + bool oneByOne=m_oneByOne; + m_oneByOne=true; // always go one by one + switchToConfigModeHW(); + enableSrHW(false); //disable + for (unsigned int i=0;i<m_modules.size();i++){ + std::cout<<"Frontend with outlink "<<m_modules[i]->getOutLink()<<std::endl; + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + retval|=m_modules[i]->verifyModuleConfigHW(); + m_modules[i]->enableSrHW(false); //disable SR + } + m_oneByOne=oneByOne; //restore value + return retval; +} + +void ModuleGroup::resetFE(){ + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + switchToConfigModeHW(); + if(m_oneByOne==true){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->resetFE(); + } + }else{ //broadcast + m_modules[0]->resetFE(); + m_modules[0]->setBroadcast(false); + } + disableAllInChannels(); +} + +void ModuleGroup::resetErrorCountersHW(){ + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + switchToConfigModeHW(); + if(m_oneByOne==true){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->resetErrorCountersHW(); + } + }else{ //broadcast + m_modules[0]->resetErrorCountersHW(); + m_modules[0]->setBroadcast(false); + } + //disableAllInChannels(); +} + +void ModuleGroup::enableDataTakingHW(){ + //std::cout<<"ConfigIF enabled data taking"<<std::endl; + if(m_oneByOne==false){ + m_modules[0]->setBroadcast(true); + setChannelInMask(); + } + if(m_oneByOne==true){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->enableDataTakingHW(); + } + }else{ //broadcast + m_modules[0]->enableDataTakingHW(); + m_modules[0]->setBroadcast(false); + } + disableAllInChannels(); +} + +void ModuleGroup::switchToConfigModeHW(){ + //std::cout<<"ConfigIF switch config mode"<<std::endl; + if(m_oneByOne == true){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->switchToConfigModeHW(); + } + }else{ //broadcast + m_modules[0]->switchToConfigModeHW(); + } +} + +void ModuleGroup::enableSrHW(bool on){ //not used in broadcast mode + //std::cout<<"ConfigIF switch config mode"<<std::endl; + if(m_oneByOne == true){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->enableSrHW(on); + } + }else{ //broadcast + m_modules[0]->enableSrHW(on); + } +} + +int ModuleGroup::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + try{ + m_oneByOne=scanOptions->get("trigOpt.optionsMask.ONE_BY_ONE", 0); + for (unsigned int i=0;i<m_modules.size();i++){ + retval+=m_modules[i]->configureScan(scanOptions); + } + } catch(boost::property_tree::ptree_bad_path ex){ + retval=1; + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + return retval; +} + +} diff --git a/rce/rcecalib/config/FEI4/ModuleGroup.hh b/rce/rcecalib/config/FEI4/ModuleGroup.hh new file mode 100644 index 0000000000000000000000000000000000000000..f917921dbaa64ec0850f50ad602f3978283e1989 --- /dev/null +++ b/rce/rcecalib/config/FEI4/ModuleGroup.hh @@ -0,0 +1,35 @@ +#ifndef MODULEGROUPFEI4_HH +#define MODULEGROUPFEI4_HH +#include "rcecalib/config/AbsModuleGroup.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <vector> + +namespace FEI4{ + + class Module; + +class ModuleGroup: public AbsModuleGroup{ +public: + ModuleGroup():AbsModuleGroup(), m_oneByOne(false){}; + virtual ~ModuleGroup(){} + void addModule(FEI4::Module* module); + void deleteModules(); + int setupParameterHW(const char* name, int val, bool bcok); + int setupMaskStageHW(int stage); + void configureModulesHW(); + int verifyModuleConfigHW(); + void resetErrorCountersHW(); + int configureScan(boost::property_tree::ptree *scanOptions); + void resetFE(); + void enableDataTakingHW(); + unsigned getNmodules(){return m_modules.size();} +private: + void enableSrHW(bool on); + void switchToConfigModeHW(); + std::vector<FEI4::Module*> m_modules; + bool m_oneByOne; + +}; +} + +#endif diff --git a/rce/rcecalib/config/FEI4/MonleakTrigger.cc b/rce/rcecalib/config/FEI4/MonleakTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..27fefe1a3ef2dfa22e3a1abe5b81ad5942ef3054 --- /dev/null +++ b/rce/rcecalib/config/FEI4/MonleakTrigger.cc @@ -0,0 +1,77 @@ + +#include "rcecalib/config/FEI4/MonleakTrigger.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + MonleakTrigger::MonleakTrigger():AbsTrigger(){ + } + MonleakTrigger::~MonleakTrigger(){ + } + int MonleakTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + // int calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + setupTriggerStream(); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + int MonleakTrigger::setupParameter(const char* name, int val){ + return 0; + } + + void MonleakTrigger::setupTriggerStream(){ + m_triggerStream.clear(); + FECommands commands; + commands.setBroadcast(true); + + commands.switchMode(&m_triggerStream, FECommands::CONF); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + //Set GADCSel to 7, which indicates that GADC will return the leakage current + //Also sets PlsrRiseUpTau to 7 and enables PlsrPwr + commands.writeGlobalRegister(&m_triggerStream, 31, 0xf007); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + //enables GADCStart, which means that when a GlobalPulse is sent, it will be sent + //to the GADC. Also, enables EN_PLL bit. + commands.writeGlobalRegister(&m_triggerStream, 27, 0x8400); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.globalPulse(&m_triggerStream, 63); + for(int i=0;i<16;i++)m_triggerStream.push_back(0); + //readout GADC value. + commands.readGlobalRegister(&m_triggerStream, 40); + } + + int MonleakTrigger::sendTrigger(){ + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); + m_i++; + return 0; + } + + int MonleakTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int MonleakTrigger::resetCounters(){ + return 0; + } +}; diff --git a/rce/rcecalib/config/FEI4/MonleakTrigger.hh b/rce/rcecalib/config/FEI4/MonleakTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..1f44e42f290a32e10b0c7707404bfdcf89adce95 --- /dev/null +++ b/rce/rcecalib/config/FEI4/MonleakTrigger.hh @@ -0,0 +1,26 @@ +#ifndef MONLEAKTRIGGER_HH +#define MONLEAKTRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" + +namespace FEI4{ + + class MonleakTrigger: public AbsTrigger{ + public: + MonleakTrigger(); + ~MonleakTrigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + private: + BitStream m_triggerStream; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/NoiseMaskStaging.cc b/rce/rcecalib/config/FEI4/NoiseMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..65d424a9101668f8c019ffd7b92f8a01b6ea1d4b --- /dev/null +++ b/rce/rcecalib/config/FEI4/NoiseMaskStaging.cc @@ -0,0 +1,54 @@ +#include "rcecalib/config/FEI4/NoiseMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + NoiseMaskStaging::NoiseMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + } + + void NoiseMaskStaging::setupMaskStageHW(int maskStage){ + if(m_initialized==false || maskStage==0){ + clearBitsHW(); + m_initialized=true; + } + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + global->setField("Colpr_Mode", 0, GlobalRegister::SW); + + /* + this is the code to reset bits. Don't understand everything it's doing + m_module->global()->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.oMask&(1<<i)){ + m_module->pixel()->setBitAll(i,0); + m_module->writeDoubleColumnHW(i,i,0,0); + } + } + */ + + + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + if(m_masks.iMask&(1<<i)){ + + //turn on this bit for every pixel on the FE + for(int dcolStage=0; dcolStage<40; dcolStage++){ + + pixel->setupMaskStageCol(dcolStage*2+1, i, 0, 1); + if(dcolStage==39)pixel->setupMaskStageCol(80, i, 0, 1); + + m_module->writeDoubleColumnHW(i, i, dcolStage, dcolStage); + + if(dcolStage!=0){ + pixel->setupMaskStageCol(dcolStage*2, i, 0, 1); + m_module->writeDoubleColumnHW(i, i, dcolStage-1, dcolStage-1); + global->setField("Colpr_Addr", dcolStage, GlobalRegister::HW); //this line not necessary, since not injecting + } + } + + } //end if(m_masks.iMask&(1<<i)) + } //end for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++) + + } + +} diff --git a/rce/rcecalib/config/FEI4/NoiseMaskStaging.hh b/rce/rcecalib/config/FEI4/NoiseMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..559942041b2b03581e403806e12da63b65dd3367 --- /dev/null +++ b/rce/rcecalib/config/FEI4/NoiseMaskStaging.hh @@ -0,0 +1,20 @@ +#ifndef FEI4NOISEMASKSTAGING_HH +#define FEI4NOISEMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class NoiseMaskStaging: public MaskStaging<FEI4::Module>{ + public: + NoiseMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + private: + + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/PatternMaskStaging.cc b/rce/rcecalib/config/FEI4/PatternMaskStaging.cc new file mode 100644 index 0000000000000000000000000000000000000000..310e778b5f4425acaea690421feb16f87500eb0b --- /dev/null +++ b/rce/rcecalib/config/FEI4/PatternMaskStaging.cc @@ -0,0 +1,23 @@ +#include "rcecalib/config/FEI4/PatternMaskStaging.hh" +#include "rcecalib/config/FEI4/Module.hh" + +namespace FEI4{ + + PatternMaskStaging::PatternMaskStaging(FEI4::Module* mod, Masks masks, std::string type) + :MaskStaging<FEI4::Module>(mod, masks, type){ + std::cout<<"Set up pattern mask staging"<<std::endl; + PixelRegister::setHitBusMode(1); + } + + void PatternMaskStaging::setupMaskStageHW(int maskStage){ + PixelRegister* pixel=m_module->pixel(); + GlobalRegister* global=m_module->global(); + global->setField("Conf_AddrEnable", 1, GlobalRegister::HW); + global->setField("Colpr_Mode", 3, GlobalRegister::SW); + for(int i=0;i<PixelRegister::N_PIXEL_REGISTER_BITS;i++){ + int thestage= (unsigned)i==PixelRegisterFields::fieldPos[PixelRegister::hitbus]? maskStage : 1-maskStage; + pixel->setupMaskStage(i, thestage, 2); + m_module->writeDoubleColumnHW(i, i, 0, 0); + } + } +} diff --git a/rce/rcecalib/config/FEI4/PatternMaskStaging.hh b/rce/rcecalib/config/FEI4/PatternMaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..f2c906b2a4ae5ae1784ea0a69a61f5b44964230a --- /dev/null +++ b/rce/rcecalib/config/FEI4/PatternMaskStaging.hh @@ -0,0 +1,18 @@ +#ifndef FEI4PATTERNMASKSTAGING_HH +#define FEI4PATTERNMASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +namespace FEI4{ + + class Module; + + class PatternMaskStaging: public MaskStaging<FEI4::Module>{ + public: + PatternMaskStaging(FEI4::Module* module, Masks masks, std::string type); + void setupMaskStageHW(int maskStage); + }; + +} +#endif diff --git a/rce/rcecalib/config/FEI4/PixelRegister.cc b/rce/rcecalib/config/FEI4/PixelRegister.cc new file mode 100644 index 0000000000000000000000000000000000000000..a3257212bdbd93edde027c6059dac59c9e6852e7 --- /dev/null +++ b/rce/rcecalib/config/FEI4/PixelRegister.cc @@ -0,0 +1,261 @@ +#include "rcecalib/config/FEI4/PixelRegister.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/util/VerifyErrors.hh" +//#include "PixelRegister.hh" +#include <iostream> +#include <stdio.h> +#include <unistd.h> /* for usleep */ + +namespace FEI4{ + std::string PixelRegister::m_cachedName; + PixelRegister::Field PixelRegister::m_cachedField(not_found); + std::map<std::string, PixelRegister::Field> PixelRegister::m_parameters; + bool PixelRegister::m_initialized = false; + int PixelRegister::m_hitbusMode = 0; + + PixelRegister::PixelRegister(FECommands* commands):m_commands(commands){ + // initialize static field dictionay + if(!m_initialized)initialize(); + //Clear all registers + for (int i=0;i<N_PIXEL_REGISTER_BITS;i++){ + for(int k=0;k<N_COLS/2;k++){ + for (int j=0;j<DROW_WORDS;j++){ + m_pixreg[i][k][j]=0; + } + } + } + } + PixelRegister::~PixelRegister(){ + } + void PixelRegister::initialize(){ + // Translation from scan parameter to Global register field + m_parameters["TDACS"]=tdac; + m_parameters["FDACS"]=fdac; + m_initialized=true; + } + + + void PixelRegister::setDoubleColumn(unsigned bit, unsigned dcol, unsigned *data){ + if(bit<N_PIXEL_REGISTER_BITS && dcol<N_COLS/2){ + for(int i=0;i<DROW_WORDS;i++){ + m_pixreg[bit][dcol][i]=data[i]; + } + } + } + void PixelRegister::setFieldAll(Field field, unsigned val){ + unsigned bitpos=PixelRegisterFields::fieldPos[field]; + unsigned mask=PixelRegisterFields::fieldMask[field]; + unsigned v=val; + if(field==tdac)v=flipBits(5, val);// tdac has reverse bit order + while(mask&1){ + setBitAll(bitpos, v&0x1); + mask>>=1; + v>>=1; + bitpos++; + } + } + + void PixelRegister::setBitAll(int bit, int on){ + if( (unsigned)bit==PixelRegisterFields::fieldPos[hitbus] && m_hitbusMode==1)on=!on; + unsigned setword=0; + if(on)setword=0xffffffff; + for (int j=0;j<N_COLS/2;j++){ + for(int k=0;k<DROW_WORDS;k++){ + m_pixreg[bit][j][k]=setword; + } + } + } + void PixelRegister::setBitDcol(unsigned dcol, int bit, int on){ + if((unsigned)bit==PixelRegisterFields::fieldPos[hitbus] && m_hitbusMode==1)on=!on; + if(dcol>=N_COLS/2){ + std::cout<<"Error: Trying to set double column "<<dcol<<std::endl; + return; + } + unsigned setword=0; + if(on)setword=0xffffffff; + for(int k=0;k<DROW_WORDS;k++){ + m_pixreg[bit][dcol][k]=setword; + } + } + void PixelRegister::setBitCol(unsigned col, int bit, int on){ + if((unsigned)bit==PixelRegisterFields::fieldPos[hitbus] && m_hitbusMode==1)on=!on; + if(col>N_COLS || col==0){ + std::cout<<"Error: Trying to set column "<<col<<std::endl; + return; + } + unsigned dcol=(col-1)/2; + unsigned setword=0; + if(on)setword=0xffffffff; + unsigned offset=0; + if(col%2==1)offset=DROW_WORDS/2+1; + for(unsigned k=offset;k<offset+DROW_WORDS/2;k++){ + m_pixreg[bit][dcol][k]=setword; + } + unsigned mask=0x0000ffff; + if(col%2==0)mask=0xffff0000; + if(on)m_pixreg[bit][dcol][10]|=mask; + else m_pixreg[bit][dcol][10]&=~mask; + } + + + void PixelRegister::setupMaskStage(int bit, int maskStage, unsigned nMaskStages){ + setBitAll(bit, 0); //clear the bit + int on=1; + if((unsigned)bit==PixelRegisterFields::fieldPos[hitbus] && m_hitbusMode==1)on=0; + for (int j=1;j<=N_COLS;j++){ + for(int k=maskStage+1;k<=N_ROWS;k+=nMaskStages){ + setBit(bit, k, j, on); + } + } + } + void PixelRegister::setupMaskStageCol(unsigned col, int bit, int maskStage, unsigned nMaskStages){ + setBitCol(col, bit, 0); //clear the bit + int on=1; + if((unsigned)bit==PixelRegisterFields::fieldPos[hitbus] && m_hitbusMode==1)on=0; + for(int k=maskStage+1;k<=N_ROWS;k+=nMaskStages){ + setBit(bit, k, col, on); + } + } + void PixelRegister::dumpPixelRegister(std::ostream &os){ + char line[512]; + for (int i=0;i<N_PIXEL_REGISTER_BITS;i++){ + sprintf(line, "BIT %d:\n",i); + os<<line; + for (int j=0;j<N_COLS/2;j++){ + sprintf(line, "Double Col: %02d: ", j); + os<<line; + for(int k=0;k<DROW_WORDS;k++){ + sprintf (line, "%08x ",m_pixreg[i][j][k]); + os<<line; + } + os<<std::endl; + } + } + } + + void PixelRegister::dumpDoubleColumn(unsigned bit, unsigned dcol, std::ostream &os){ + char line[512]; + sprintf(line, "BIT %d:\n",bit); + os<<line; + sprintf(line, "Double Col: %02d: ", dcol); + os<<line; + for(int k=0;k<DROW_WORDS;k++){ + sprintf (line, "%08x ",m_pixreg[bit][dcol][k]); + os<<line; + } + os<<std::endl; + } + + int PixelRegister::verifyDoubleColumnHW(int bit, unsigned dcol, std::vector<unsigned> &readback){ + readback.clear(); + BitStream *bs=new BitStream; + m_commands->feWriteCommand(bs); + for(int i=0;i<DROW_WORDS;i++)bs->push_back(0); // refill with 0 + bs->push_back(0); + SerialIF::send(bs, SerialIF::WAITFORDATA); + delete bs; + usleep(100); + if(readback.size()!=2*DROW_WORDS){ + std::cout<<std::dec<<"Dcol "<<dcol<<" bit "<<bit<<" Expecting 42 val records, received "<<readback.size()<<std::endl; + return ModuleVerify::PIXEL_WRONG_N_WORDS; + }else{ + for(int i=0;i<2*DROW_WORDS;i++){ + if(((~readback[i])&0xffff)!=((m_pixreg[bit][dcol][i/2]>>(16*((i+1)%2)))&0xffff)){ + std::cout<<std::dec<<"Dcol "<<dcol<<" bit "<<bit<<" bad readback "<<std::endl; + std::cout<<std::hex<<"Is "<<((~readback[i])&0xffff)<<" should be "<<((m_pixreg[bit][dcol][i/2]>>(16*((i+1)%2)))&0xffff)<<std::dec<<std::endl; + return ModuleVerify::PIXEL_READBACK_DIFFERENT; + } + } + } + return 0; + } + unsigned PixelRegister::writeDoubleColumnHW(unsigned bit, unsigned dcol){ + BitStream *bs=new BitStream; + m_commands->feWriteCommand(bs); + for(int i=0;i<DROW_WORDS;i++)bs->push_back(m_pixreg[bit][dcol][i]); + bs->push_back(0); + // for(size_t i=0;i<bs->size();i++)std::cout<<"input "<<std::hex<<(*bs)[i]<<std::dec<<std::endl; + SerialIF::send(bs, SerialIF::WAITFORDATA); + delete bs; + return 0; + } + unsigned PixelRegister::writeDoubleColumnHW(const unsigned* data, std::vector<unsigned>& readback){ + BitStream *bs=new BitStream; + m_commands->feWriteCommand(bs); + for(int i=0;i<DROW_WORDS;i++)bs->push_back(data[i]); + bs->push_back(0); + //for(size_t i=0;i<bs->size();i++)std::cout<<"input "<<std::hex<<(*bs)[i]<<std::dec<<std::endl; + std::vector<unsigned char> shiftin; + unsigned stat=SerialIF::writeBlockData(*bs); + usleep(1000); + stat=SerialIF::readBuffers(shiftin); + std::cout<<"Stat "<<stat<<" size "<<shiftin.size()<<std::endl; + + if (stat>0)stat=decodePixelRecord(shiftin, readback); + /* + if(stat>0){ + while (shiftin.size()%4!=0)shiftin.push_back(0); + for(int i=0;i<shiftin.size();i+=4){ + readback.push_back(shiftin[i]<<24|shiftin[i+1]<<16|shiftin[i+2]<<8|shiftin[i+3]); + std::cout<<std::hex<<readback[readback.size()-1]<<std::dec<<" "<<std::endl; + } + std::cout<<std::endl; + } + */ + delete bs; + return stat; + } + + unsigned PixelRegister::decodePixelRecord(std::vector<unsigned char>& shiftin, std::vector<unsigned>& readback){ + if(shiftin.size()==0)return FEI4ARecord::Empty; + unsigned char* bytepointer=(unsigned char*)&shiftin[0]; + size_t size=shiftin.size(); + unsigned char* last=bytepointer+size-3; + FEI4ARecord rec; + bool odd=true; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + printf("Record: %08x\n",rec.getUnsigned()&0xffffff); + if(rec.isServiceRecord()){ // service record + printf("Service record. Error code: %d. Count: %d \n",rec.getErrorCode(), rec.getErrorCount()); + } else if(rec.isAddressRecord()){ // address record + if(!rec.isShift())return FEI4ARecord::NotShift; + std::cout<<"Read address record with address "<<rec.getAddress()<<std::endl; + } else if(rec.isValueRecord()){ // value record + unsigned val; + printf("Value record: %08x\n",rec.getUnsigned()&0xffffff); + if(odd==true)val=rec.getValue()<<16; + else { + val|=rec.getValue(); + readback.push_back(val); + } + odd=!odd; + } + bytepointer+=3; + } + std::cout<<"Return vector"<<std::endl; + for(size_t i=0;i<readback.size();i++)std::cout<<std::hex<<readback[i]<<std::dec<<std::endl; + if(!odd)return FEI4ARecord::OddNwords; + return FEI4ARecord::OK; + } + + PixelRegister::Field PixelRegister::lookupParameter(const char* name){ + // check if this is the last name used, return cached value + if(std::string(name)==m_cachedName)return m_cachedField; + // Now check if we can translate the name to a field name + if(m_parameters.find(name)!=m_parameters.end()){ + //cache result + m_cachedName=name; + m_cachedField=m_parameters[name]; + return m_cachedField; + }else return not_found; + } + + void PixelRegister::setHitBusMode(int value){ + m_hitbusMode=value; + std::cout<<"Set HitBus mode to "<<m_hitbusMode<<std::endl; + } + +} diff --git a/rce/rcecalib/config/FEI4/PixelRegister.hh b/rce/rcecalib/config/FEI4/PixelRegister.hh new file mode 100644 index 0000000000000000000000000000000000000000..2ceb7c787c857e96eb0fc560176a90768234c9a6 --- /dev/null +++ b/rce/rcecalib/config/FEI4/PixelRegister.hh @@ -0,0 +1,106 @@ +#ifndef PIXEL_REGISTER_FEI4_HH +#define PIXEL_REGISTER_FEI4_HH + +#include <vector> +#include <map> +#include "rcecalib/config/FEI4/Utils.hh" +#include <iostream> + +namespace FEI4{ + class FECommands; + + namespace PixelRegisterFields{ + static const unsigned fieldPos[]={0,1,6,7,8,9,13,14}; + static const unsigned fieldMask[]={1,0x1f,1,1,1,0xf,1}; + } + class PixelRegister{ + public: + enum{N_COLS=80, N_ROWS=336 ,N_PIXEL_REGISTER_BITS=14, DROW_WORDS=N_ROWS*2/32}; + enum Field{enable, tdac, largeCap, smallCap, hitbus, fdac, diginj, Nfields, not_found}; + PixelRegister(FECommands* commands); + ~PixelRegister(); + unsigned getBit(unsigned bit, unsigned row, unsigned col){ + int drow; + int dcol=(col-1)/2;// column numbering starts with 1, array with 0. dcol is double column + if(col%2==0){ + drow = row+335; + }else{ + drow = 336-row; + } + return (m_pixreg[bit][dcol][DROW_WORDS-1-drow/32] >> (drow%32))&0x1; + } + + void setBit(unsigned bit, unsigned row, unsigned col, bool val){ + int drow; + int dcol=(col-1)/2;// column numbering starts with 1, array with 0. Array is by double columns. + if(col%2==0){ + drow = row+335; //even column is in forward order 336 - 671 + }else{ + drow = 336-row; //odd column is in backward order 0 - 335 + } + if(val){ + m_pixreg[bit][dcol][DROW_WORDS-1-drow/32] |= (1<<(drow%32)); + }else{ + m_pixreg[bit][dcol][DROW_WORDS-1-drow/32] &= ~(1<<(drow%32)); + } + } + void setFieldAll(Field f, unsigned val); + void setField(Field f, unsigned row, unsigned col, unsigned val){ + unsigned bitpos=PixelRegisterFields::fieldPos[f]; + unsigned mask=PixelRegisterFields::fieldMask[f]; + unsigned v=val; + if(f==tdac)v=flipBits(5, val);// tdac has reverse bit order + while(mask&1){ + setBit(bitpos, row, col, v&0x1); + mask>>=1; + v>>=1; + bitpos++; + } + } + unsigned getField(Field f, unsigned row, unsigned col){ + unsigned bitpos=PixelRegisterFields::fieldPos[f+1]-1; + unsigned mask=PixelRegisterFields::fieldMask[f]; + unsigned val=0; + while(mask&1){ + unsigned bit=getBit(bitpos, row, col); + mask>>=1; + val<<=1; + val|=bit; + bitpos--; + } + if(f==tdac)return flipBits(5, val); // word is flipped, reverse for fdac + else return val; + } + unsigned *getDoubleColumn(unsigned bit, unsigned dcol){ + if(bit<N_PIXEL_REGISTER_BITS && dcol<N_COLS/2)return m_pixreg[bit][dcol]; + else return 0; + } + void setDoubleColumn(unsigned bit, unsigned dcol, unsigned* data); + unsigned writeDoubleColumnHW(unsigned bit, unsigned dcol); + unsigned writeDoubleColumnHW(const unsigned *data, std::vector<unsigned>& readback); + void dumpPixelRegister(std::ostream &os); + void dumpDoubleColumn(unsigned bit, unsigned dcol, std::ostream &os); + unsigned decodePixelRecord(std::vector<unsigned char>& shiftin, std::vector<unsigned>& readback); + int verifyDoubleColumnHW(int bit, unsigned dcol, std::vector<unsigned>& readback); + void setBitAll(int bit, int on); + void setBitDcol(unsigned dcol, int bit, int on); + void setBitCol(unsigned col, int bit, int on); + void setupMaskStage(int bit, int maskStage, unsigned nMaskStages); + void setupMaskStageCol(unsigned col, int bit, int maskStage, unsigned nMaskStages); + static Field lookupParameter(const char* name); + static void setHitBusMode(int value); + + private: + static std::string m_cachedName; + static Field m_cachedField; + static std::map<std::string, Field> m_parameters; + static bool m_initialized; + static void initialize(); + static int m_hitbusMode; //0 for monleak scan, 1 for hitbus scan + FECommands* m_commands; + unsigned m_pixreg[N_PIXEL_REGISTER_BITS][N_COLS/2][DROW_WORDS]; // by double column + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/RegisterDef.hh b/rce/rcecalib/config/FEI4/RegisterDef.hh new file mode 100644 index 0000000000000000000000000000000000000000..1cd30a4f71aabb6e005dbb03ddee1c9ad2d3e5c1 --- /dev/null +++ b/rce/rcecalib/config/FEI4/RegisterDef.hh @@ -0,0 +1,29 @@ +#ifndef FEI4__REGISTERDEF_HH +#define FEI4__REGISTERDEF_HH + +namespace FEI4{ + + struct FieldParams{ + int reg; + int bitpos; + int SRABbitpos; + int SRCbitpos; + int width; + bool reverse; + }; + + struct RegisterDef{ + int LOW_REG, N_REG_REGS, N_W_REGS, N_R_REGS, SRAB_BITS, SRC_BITS; + std::map<std::string, FieldParams> m_fields; + std::map<std::string, std::string> m_parameters; + std::string m_cachedName, m_cachedField; + std::map<int, SerialIF::Rate> m_rate; + FieldParams m_params8b10b; + FieldParams m_paramsDrate; + int m_colpr_reg; + unsigned short m_colpr_disable; + }; +} + + +#endif diff --git a/rce/rcecalib/config/FEI4/SNTrigger.cc b/rce/rcecalib/config/FEI4/SNTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..ccea7e7cce37ed02b1085dcbc3d7aa11c66f2ea0 --- /dev/null +++ b/rce/rcecalib/config/FEI4/SNTrigger.cc @@ -0,0 +1,67 @@ + +#include "rcecalib/config/FEI4/SNTrigger.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + SNTrigger::SNTrigger():AbsTrigger(){ + } + SNTrigger::~SNTrigger(){ + } + int SNTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + // int calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + setupTriggerStream(); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + int SNTrigger::setupParameter(const char* name, int val){ + return 0; + } + + void SNTrigger::setupTriggerStream(){ + m_triggerStream.clear(); + FECommands commands; + commands.setBroadcast(true); + + commands.switchMode(&m_triggerStream, FECommands::CONF); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.writeGlobalRegister(&m_triggerStream, 27, 0xc000); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.globalPulse(&m_triggerStream, 63); + for(int i=0;i<128;i++)m_triggerStream.push_back(0); + commands.readGlobalRegister(&m_triggerStream, 35); + } + + int SNTrigger::sendTrigger(){ + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); + m_i++; + return 0; + } + + int SNTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int SNTrigger::resetCounters(){ + return 0; + } +}; diff --git a/rce/rcecalib/config/FEI4/SNTrigger.hh b/rce/rcecalib/config/FEI4/SNTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..1312044de208fa06777f29fd7ef1d4f841683331 --- /dev/null +++ b/rce/rcecalib/config/FEI4/SNTrigger.hh @@ -0,0 +1,26 @@ +#ifndef SNTRIGGER_HH +#define SNTRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" + +namespace FEI4{ + + class SNTrigger: public AbsTrigger{ + public: + SNTrigger(); + ~SNTrigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + private: + BitStream m_triggerStream; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/TemperatureTrigger.cc b/rce/rcecalib/config/FEI4/TemperatureTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..4f1c8f7ab1d36d5e4c5559c4ca0003f898e934cc --- /dev/null +++ b/rce/rcecalib/config/FEI4/TemperatureTrigger.cc @@ -0,0 +1,72 @@ + +#include "rcecalib/config/FEI4/TemperatureTrigger.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" + +namespace FEI4{ + + TemperatureTrigger::TemperatureTrigger():AbsTrigger(){ + } + TemperatureTrigger::~TemperatureTrigger(){ + } + int TemperatureTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + // int calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + setupTriggerStream(); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + int TemperatureTrigger::setupParameter(const char* name, int val){ + return 0; + } + + void TemperatureTrigger::setupTriggerStream(){ + m_triggerStream.clear(); + FECommands commands; + commands.setBroadcast(true); + + commands.switchMode(&m_triggerStream, FECommands::CONF); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.writeGlobalRegister(&m_triggerStream, 31, 0xf000); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.writeGlobalRegister(&m_triggerStream, 27, 0x8400); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + m_triggerStream.push_back(0); + commands.globalPulse(&m_triggerStream, 63); + for(int i=0;i<128;i++)m_triggerStream.push_back(0); + commands.readGlobalRegister(&m_triggerStream, 40); + } + + int TemperatureTrigger::sendTrigger(){ + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); + m_i++; + return 0; + } + + int TemperatureTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int TemperatureTrigger::resetCounters(){ + return 0; + } +}; diff --git a/rce/rcecalib/config/FEI4/TemperatureTrigger.hh b/rce/rcecalib/config/FEI4/TemperatureTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..7f40397c1261e9eb9cab587efa1b6419a64357eb --- /dev/null +++ b/rce/rcecalib/config/FEI4/TemperatureTrigger.hh @@ -0,0 +1,26 @@ +#ifndef TEMPERATURETRIGGER_HH +#define TEMPERATURETRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" + +namespace FEI4{ + + class TemperatureTrigger: public AbsTrigger{ + public: + TemperatureTrigger(); + ~TemperatureTrigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + private: + BitStream m_triggerStream; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/FEI4/Utils.hh b/rce/rcecalib/config/FEI4/Utils.hh new file mode 100644 index 0000000000000000000000000000000000000000..0ce31e1085932aad27ad6c2cab76e838e9b73653 --- /dev/null +++ b/rce/rcecalib/config/FEI4/Utils.hh @@ -0,0 +1,14 @@ +#ifndef UTILS_HH +#define UTILS_HH + +inline unsigned flipBits(int nbits, unsigned val){ + unsigned tmp=0; + unsigned old=val; + for (int i=0;i<nbits;i++){ + tmp|=(old&0x1)<<(nbits-i-1); + old>>=1; + } + return tmp; +} + +#endif diff --git a/rce/rcecalib/config/FormattedRecord.hh b/rce/rcecalib/config/FormattedRecord.hh new file mode 100644 index 0000000000000000000000000000000000000000..111ff8bfb3d67401c07e24c3616503205cd916fa --- /dev/null +++ b/rce/rcecalib/config/FormattedRecord.hh @@ -0,0 +1,158 @@ +#ifndef FORMATTEDRECORD_HH +#define FORMATTEDRECORD_HH + +#include "rcecalib/config/Endianness.hh" + + +/* ---------------------------------------------------------------------- */ + + class FormattedRecord{ + public: + struct Generic + { +#if ENDIANNESS_IS_BIG + + unsigned int datakey: 1; + unsigned int headertwokey: 1; + unsigned int headerkey: 1; + unsigned int unused2: 29; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int unused2: 29; + unsigned int headerkey: 1; + unsigned int headertwokey: 1; + unsigned int datakey: 1; + +#else + +#error ENDIANNESS is not defined +#endif + }; + struct Header + { +#if ENDIANNESS_IS_BIG + + unsigned int unused1: 2; + unsigned int key: 1; + unsigned int link: 4; + unsigned int l1id: 12; + unsigned int bxid: 13; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int bxid: 13; + unsigned int l1id: 12; + unsigned int link: 4; + unsigned int key: 1; + unsigned int unused1: 2; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + + struct HeaderTwo + { +#if ENDIANNESS_IS_BIG + + unsigned int unused1: 1; + unsigned int key: 1; + unsigned int unused2: 22; + unsigned int rce: 8; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int rce: 8; + unsigned int unused2: 22; + unsigned int key: 1; + unsigned int unused1: 1; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + + struct Data + { +#if ENDIANNESS_IS_BIG + + unsigned int key: 1; + unsigned int unused1: 2; + unsigned int dataflag: 1; + unsigned int fe: 4; + unsigned int tot: 8; + unsigned int col: 7; + unsigned int row: 9; + +#elif ENDIANNESS_IS_LITTLE + + unsigned int row: 9; + unsigned int col: 7; + unsigned int tot: 8; + unsigned int fe: 4; + unsigned int dataflag: 1; + unsigned int unused1: 2; + unsigned int key: 1; + +#else + +#error ENDIANNESS is not defined +#endif + }; + + + union Record + { + unsigned int ui; + Generic ge; + Header he; + Data da; + HeaderTwo ht; + }; + + enum type{HEADER=0x20000000, HEADERTWO=0x40000000, DATA=0x80000000}; + + FormattedRecord(FormattedRecord::type ty){ + m_record.ui=ty; + } + FormattedRecord(unsigned& wd){ + m_record.ui=wd; + } + + bool isHeader(){return m_record.ge.headerkey;} + bool isHeaderTwo(){return m_record.ge.headertwokey;} + bool isData(){return m_record.ge.datakey;} + + unsigned getLink(){return m_record.he.link;} + void setLink(unsigned link){m_record.he.link=link;} + unsigned getBxid(){return m_record.he.bxid;} + void setBxid(unsigned bxid){m_record.he.bxid=bxid;} + unsigned getL1id(){return m_record.he.l1id;} + void setL1id(unsigned l1id){m_record.he.l1id=l1id;} + + unsigned getRCE(){return m_record.ht.rce;} + void setRCE(unsigned rce){m_record.ht.rce=rce;} + + unsigned getFE(){return m_record.da.fe;} + void setFE(unsigned fe){m_record.da.fe=fe;} + unsigned getToT(){return m_record.da.tot;} + void setToT(unsigned tot){m_record.da.tot=tot;} + unsigned getCol(){return m_record.da.col;} + void setCol(unsigned col){m_record.da.col=col;} + unsigned getRow(){return m_record.da.row;} + void setRow(unsigned row){m_record.da.row=row;} + unsigned getDataflag(){return m_record.da.dataflag;} + void setDataflag(unsigned fl){m_record.da.dataflag=fl;} + + unsigned getWord(){return m_record.ui;} + + private: + Record m_record; + }; + +#endif diff --git a/rce/rcecalib/config/HitorTrigger.cc b/rce/rcecalib/config/HitorTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..060f3c03b6f1afe787f4449ab4caccf0ee3f9cb7 --- /dev/null +++ b/rce/rcecalib/config/HitorTrigger.cc @@ -0,0 +1,29 @@ + +#include "rcecalib/config/HitorTrigger.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/util/exceptions.hh" +#include <iostream> +#include <fstream> +#include <stdlib.h> + + +HitorTrigger::HitorTrigger(ConfigIF* cif):AbsTrigger(), m_configIF(cif){ + //std::cout<<"Hitor trigger"<<std::endl; + } + +int HitorTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + return 0; +} + +int HitorTrigger::sendTrigger(){ + + // read errors + m_configIF->resetErrorCountersHW(); + m_i++; + return 0; +} + + diff --git a/rce/rcecalib/config/HitorTrigger.hh b/rce/rcecalib/config/HitorTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..81b46f7db5d8a01769c3fce8c3523759dcddae2d --- /dev/null +++ b/rce/rcecalib/config/HitorTrigger.hh @@ -0,0 +1,22 @@ +#ifndef HITORTRIGGER_HH +#define HITORTRIGGER_HH + +#include "rcecalib/config/AbsTrigger.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <string> + +class ConfigIF; + + class HitorTrigger: public AbsTrigger{ + public: + HitorTrigger(ConfigIF* cif); + ~HitorTrigger(){}; + int sendTrigger(); + int enableTrigger(bool on){return 0;} + int configureScan(boost::property_tree::ptree* scanOptions); + private: + ConfigIF* m_configIF; + }; + + +#endif diff --git a/rce/rcecalib/config/IPCConfigIF.cc b/rce/rcecalib/config/IPCConfigIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..ac9b9e0614ad0fd84c401df36e394ad47062233a --- /dev/null +++ b/rce/rcecalib/config/IPCConfigIF.cc @@ -0,0 +1,140 @@ +#ifndef IPCCONFIGIF_CC +#define IPCCONFIGIF_CC + +#include "rcecalib/config/IPCConfigIF.hh" + +template <class TP> +IPCConfigIF<TP>::IPCConfigIF(IPCPartition & p, const char * name, ModuleFactory* mf): + IPCNamedObject<POA_ipc::IPCConfigIFAdapter, TP>( p, name ) , ConfigIF(mf){ + try { + IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCConfigIF<TP>::~IPCConfigIF(){ + try { + IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +//template <class TP> +//void IPCConfigIF<TP>::IPCsetupParameter(const char* name, CORBA::Long val){ +// setupParameter(name, val); +//} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCsetupParameter(const char* name, CORBA::Long val){ + setupParameter(name, val, false); //do not enable data taking because chip may be unconfigured + return 0; +} +template <class TP> +void IPCConfigIF<TP>::IPCsetupMaskStage(CORBA::Long stage){ + setupMaskStage(stage); +} +template <class TP> +void IPCConfigIF<TP>::IPCsendTrigger(){ + sendTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCenableTrigger(){ + enableTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCdisableTrigger(){ + disableTrigger(); +} +template <class TP> +void IPCConfigIF<TP>::IPCresetFE(){ + resetFE(); +} +template <class TP> +void IPCConfigIF<TP>::IPCconfigureModulesHW(){ + configureModulesHW(); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCverifyModuleConfigHW(CORBA::Long id){ + return verifyModuleConfigHW(id); +} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCwriteHWregister(CORBA::ULong addr, CORBA::ULong val){ + return writeHWregister(addr,val); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWregister(CORBA::ULong addr, CORBA::ULong& val){ + return readHWregister(addr, (unsigned int&)val); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCsendHWcommand(CORBA::Octet opcode){ + return sendHWcommand(opcode); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCwriteHWblockData(const ipc::blockdata& data){ + std::vector<unsigned> bldat; + for(size_t i=0;i<data.length();i++)bldat.push_back(data[i]); + return writeHWblockData(bldat); +} + +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWblockData(const ipc::blockdata& data, ipc::blockdata_out retv){ + std::vector<unsigned> bldat; + for(size_t i=0;i<data.length();i++)bldat.push_back(data[i]); + std::vector<unsigned> retvec; + unsigned retval=readHWblockData(bldat, retvec); + retv=new ipc::blockdata; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::ULong)retvec[i]; + return retval; +} +template <class TP> +CORBA::ULong IPCConfigIF<TP>::IPCreadHWbuffers(ipc::chardata_out retv){ + std::vector<unsigned char> retvec; + unsigned retval=readHWbuffers(retvec); + retv=new ipc::chardata; + retv->length(retvec.size()); + for(size_t i=0;i<retvec.size();i++)retv[i]=(CORBA::Octet)retvec[i]; + return retval; +} + +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCnTrigger(){ + return nTrigger(); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCsetupTriggerIF(const char* type){ + setupTriggerIF(type); + return 0; +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCsetupModule(const char* name, const char* type, const ipc::ModSetup& par, const char* formatter){ + //std::cout<<"IPCsetupModule"<<std::endl; + return setupModule(name, type, par.id, par.inLink, par.outLink, formatter); +} +template <class TP> +CORBA::Long IPCConfigIF<TP>::IPCdeleteModules(){ + deleteModules(); + return 0; +} +template <class TP> +void IPCConfigIF<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/rcecalib/config/IPCConfigIF.hh b/rce/rcecalib/config/IPCConfigIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..eb9f8d3fdc511449922789a3647d0f3bfbb8c0b3 --- /dev/null +++ b/rce/rcecalib/config/IPCConfigIF.hh @@ -0,0 +1,41 @@ +#ifndef IPCCONFIGIF_HH +#define IPCCONFIGIF_HH + +#include "IPCConfigIFAdapter.hh" +#include "ipc/object.h" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/ModuleFactory.hh" +#include <omnithread.h> + +class IPCPartition; + +template <class TP = ipc::single_thread> +class IPCConfigIF: public IPCNamedObject<POA_ipc::IPCConfigIFAdapter,TP>, public ConfigIF { +public: + IPCConfigIF(IPCPartition & p, const char * name, ModuleFactory* mf); + ~IPCConfigIF(); + void IPCsendTrigger(); + //void IPCsetupParameter(const char* name, CORBA::Long val); + CORBA::ULong IPCsetupParameter(const char* name, CORBA::Long val); + void IPCsetupMaskStage(CORBA::Long stage); + void IPCenableTrigger(); + void IPCdisableTrigger(); + void IPCresetFE(); + void IPCconfigureModulesHW(); + CORBA::Long IPCverifyModuleConfigHW(CORBA::Long id); + CORBA::ULong IPCwriteHWregister(CORBA::ULong addr, CORBA::ULong val); + CORBA::ULong IPCsendHWcommand(CORBA::Octet opcode); + CORBA::ULong IPCwriteHWblockData(const ipc::blockdata& data); + CORBA::ULong IPCreadHWblockData(const ipc::blockdata & data, ipc::blockdata_out retv); + CORBA::ULong IPCreadHWbuffers(ipc::chardata_out retv); + CORBA::ULong IPCreadHWregister(CORBA::ULong addr, CORBA::ULong &val); + CORBA::Long IPCdeleteModules(); + CORBA::Long IPCnTrigger(); + CORBA::Long IPCsetupTriggerIF(const char* type); + CORBA::Long IPCsetupModule(const char* name, const char* type, const ipc::ModSetup& par, const char* formatter); + void shutdown(); + +}; + + +#endif diff --git a/rce/rcecalib/config/IPCModuleFactory.cc b/rce/rcecalib/config/IPCModuleFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..525989943c4f380bef253ba5bc421911ff1aad55 --- /dev/null +++ b/rce/rcecalib/config/IPCModuleFactory.cc @@ -0,0 +1,146 @@ +#include "rcecalib/config/IPCModuleFactory.hh" +#include "rcecalib/config/DummyFormatter.hh" +#include "rcecalib/config/FEI3/JJFormatter.hh" +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FEI4/FEI4BFormatter.hh" +#include "rcecalib/config/FEI4/FEI4HitorFormatter.hh" +#include "rcecalib/config/FEI4/FEI4OccFormatter.hh" +#include "rcecalib/config/FEI3/Module.hh" +#include "rcecalib/config/FEI3/IPCModule.cc" +#include "rcecalib/config/FEI4/IPCFEI4AModule.cc" +#include "rcecalib/config/FEI4/IPCFEI4BModule.cc" +#include "rcecalib/config/hitbus/IPCModule.cc" +#include "rcecalib/config/afp-hptdc/IPCModule.cc" +#include "rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh" +#include "rcecalib/config/Trigger.hh" +#include "rcecalib/config/MultiTrigger.hh" +#include "rcecalib/config/EventFromFileTrigger.hh" +#include "rcecalib/config/MeasurementTrigger.hh" +#include "rcecalib/config/MultiShotTrigger.hh" +#include "rcecalib/config/HitorTrigger.hh" +#include "rcecalib/config/FEI4/TemperatureTrigger.hh" +#include "rcecalib/config/FEI4/MonleakTrigger.hh" +#include "rcecalib/config/FEI4/SNTrigger.hh" +#include "rcecalib/config/FEI4/Fei4RegisterTestTrigger.hh" +#include "rcecalib/util/exceptions.hh" +#include "stdio.h" +#include <iostream> + +IPCModuleFactory::IPCModuleFactory(IPCPartition& p):ModuleFactory(),m_partition(p){ + m_modulegroups.push_back(&m_modgroupi3); + m_modulegroups.push_back(&m_modgroupi4a); + m_modulegroups.push_back(&m_modgroupi4b); + m_modulegroups.push_back(&m_modgrouphitbus); + m_modulegroups.push_back(&m_modgroupafphptdc); +} + + +AbsFormatter* IPCModuleFactory::createFormatter(const char* formatter, int id){ + + // create formatter first + if(std::string(formatter)=="JJ") + return new JJFormatter(id); + else if(std::string(formatter)=="") + return 0; + else if(std::string(formatter)=="FEI4A") + return new FEI4AFormatter(id); + else if(std::string(formatter)=="FEI4B") + return new FEI4BFormatter(id); + else if(std::string(formatter)=="FEI4Hitor") + return new FEI4HitorFormatter(id); + else if(std::string(formatter)=="FEI4Occ") + return new FEI4OccFormatter(id); + else if(std::string(formatter)=="AFPHPTDC") + return new AFPHPTDCFormatter(id); + else if(std::string(formatter)=="Dummy") + return new DummyFormatter(id); + else{ + std::cout<<"Unknown formatter "<<formatter<<std::endl; + assert(0); + } +} + +AbsModule* IPCModuleFactory::createModule(const char* name, const char* type, unsigned id, unsigned inLink, unsigned outLink, const char* formatter){ + AbsFormatter* theformatter=createFormatter(formatter, id); + if(std::string(type)=="FEI3"){ + FEI3::Module *mod= new FEI3::Module(name, id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI3_singleThread"){ + FEI3::Module *mod= new FEI3::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI3_multiThread"){ + FEI3::Module *mod= new FEI3::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi3.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4A_singleThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4AModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4a.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4A_multiThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4AModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4a.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4B_singleThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4BModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4b.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_FEI4B_multiThread"){ + FEI4::Module *mod= new FEI4::IPCFEI4BModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupi4b.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_Hitbus_singleThread"){ + Hitbus::Module *mod= new Hitbus::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgrouphitbus.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_Hitbus_multiThread"){ + Hitbus::Module *mod= new Hitbus::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgrouphitbus.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_AFPHPTDC_singleThread"){ + afphptdc::Module *mod= new afphptdc::IPCModule<ipc::single_thread>(m_partition, name,id, inLink, outLink, theformatter); + m_modgroupafphptdc.addModule(mod); + return mod; + } + if(std::string(type)=="IPC_AFPHPTDC_multiThread"){ + std::cout<<"Adding module"<<std::endl; + afphptdc::Module *mod= new afphptdc::IPCModule<ipc::multi_thread>(m_partition, name,id, inLink, outLink, theformatter); + std::cout<<"Added module"<<std::endl; + m_modgroupafphptdc.addModule(mod); + return mod; + } + std::cout<<"Unknown module type "<<type<<std::endl; + rcecalib::Unknown_Module_Type issue(ERS_HERE,type); + throw issue; + return 0; +} + +AbsTrigger* IPCModuleFactory::createTriggerIF(const char* type, ConfigIF* cif){ + // std::cout << "Creating trigger of type " << type << std::endl; + if(std::string(type)=="default") return new FEI3::Trigger; + else if(std::string(type)=="FEI3")return new FEI3::Trigger; + else if(std::string(type)=="EventFromFile")return new EventFromFileTrigger; + else if(std::string(type)=="MultiShot")return new MultiShotTrigger; + else if(std::string(type)=="MultiTrigger")return new MultiTrigger; + else if(std::string(type)=="Hitor")return new HitorTrigger(cif); + else if(std::string(type)=="Temperature")return new FEI4::TemperatureTrigger; + else if(std::string(type)=="Monleak")return new FEI4::MonleakTrigger; + else if(std::string(type)=="SerialNumber")return new FEI4::SNTrigger; + else if(std::string(type)=="Fei4RegisterTest")return new FEI4::Fei4RegisterTestTrigger; +#ifdef __rtems__ + else if(std::string(type)=="Measurement")return new MeasurementTrigger; +#endif + char msg[128]; + sprintf(msg, "No Trigger type %s",type); + ERS_ASSERT_MSG(0,msg); +} diff --git a/rce/rcecalib/config/IPCModuleFactory.hh b/rce/rcecalib/config/IPCModuleFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..3b593aa3158e95598ce04757d0890fb938736366 --- /dev/null +++ b/rce/rcecalib/config/IPCModuleFactory.hh @@ -0,0 +1,32 @@ +#ifndef IPCMODULEFACTORY_HH +#define IPCMODULEFACTORY_HH + +#include "ipc/partition.h" + +#include "rcecalib/config/ModuleFactory.hh" +#include "rcecalib/config/FEI3/ModuleGroup.hh" +#include "rcecalib/config/FEI4/ModuleGroup.hh" +#include "rcecalib/config/hitbus/ModuleGroup.hh" +#include "rcecalib/config/afp-hptdc/ModuleGroup.hh" + +class ConfigIF; +class AbsFormatter; + +class IPCModuleFactory: public ModuleFactory { +public: + IPCModuleFactory(IPCPartition &p); + AbsModule* createModule(const char* name, const char* type, unsigned id, unsigned inpos, unsigned outPos, const char* formatter); + AbsFormatter* createFormatter(const char* formatter, int id); + AbsTrigger* createTriggerIF(const char* type, ConfigIF* cif); +private: + IPCPartition &m_partition; + FEI3::ModuleGroup m_modgroupi3; + FEI4::ModuleGroup m_modgroupi4a; + FEI4::ModuleGroup m_modgroupi4b; + Hitbus::ModuleGroup m_modgrouphitbus; + afphptdc::ModuleGroup m_modgroupafphptdc; + +}; + + +#endif diff --git a/rce/rcecalib/config/Makefile b/rce/rcecalib/config/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/rcecalib/config/Makefile @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/rcecalib/config/MaskStageFactory.hh b/rce/rcecalib/config/MaskStageFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..1bb714f18c07e7fd409031e25ca3e4d707121b5a --- /dev/null +++ b/rce/rcecalib/config/MaskStageFactory.hh @@ -0,0 +1,17 @@ +#ifndef MASKSTAGEFACTORY_HH +#define MASKSTAGEFACTORY_HH + +#include "rcecalib/config/Masks.hh" +#include "rcecalib/config/MaskStaging.hh" + +class MaskStageFactory{ +public: + MaskStageFactory(){} + ~MaskStageFactory(){} + template <typename T> + MaskStaging<T>* createMaskStaging(T* mod, const char* maskStagingType, const char* maskStagingMode); + template <typename T> + Masks createIOmasks(const char* maskStagingMode); +}; + +#endif diff --git a/rce/rcecalib/config/MaskStaging.hh b/rce/rcecalib/config/MaskStaging.hh new file mode 100644 index 0000000000000000000000000000000000000000..f4e7a7879d96ee9699fbbbdb7b7d502026b68ac4 --- /dev/null +++ b/rce/rcecalib/config/MaskStaging.hh @@ -0,0 +1,29 @@ +#ifndef MASKSTAGING_HH +#define MASKSTAGING_HH + +#include "rcecalib/config/Masks.hh" +#include <string> + +template <typename T> +class MaskStaging{ +public: + MaskStaging(T *module, Masks masks, std::string stagingType): + m_masks(masks), m_module(module), m_type(stagingType), m_initialized(false){} + virtual void setupMaskStageHW(int maskStage)=0; + virtual void clearBitsHW(); + virtual bool cLow(); + virtual bool cHigh(); + void setClow(bool i){m_clow=i;} + void setChigh(bool i){m_chigh=i;} + bool initialized(){return m_initialized;} +protected: + Masks m_masks; + T* m_module; + std::string m_type; + bool m_clow; + bool m_chigh; + bool m_initialized; +}; + + +#endif diff --git a/rce/rcecalib/config/Masks.hh b/rce/rcecalib/config/Masks.hh new file mode 100644 index 0000000000000000000000000000000000000000..13af206c4d95670708dd86374418ff823f0bf34d --- /dev/null +++ b/rce/rcecalib/config/Masks.hh @@ -0,0 +1,12 @@ +#ifndef MASKS_HH +#define MASKS_HH + + struct Masks{ + unsigned short oMask; + unsigned short iMask; + unsigned short xtalk_on; + unsigned short xtalk_off; + bool crosstalking; + }; + +#endif diff --git a/rce/rcecalib/config/MeasurementTrigger.cc b/rce/rcecalib/config/MeasurementTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..77630777b2909e59e9bf4bbe291d4dca0055c40b --- /dev/null +++ b/rce/rcecalib/config/MeasurementTrigger.cc @@ -0,0 +1,29 @@ + +#include "rcecalib/config/MeasurementTrigger.hh" +#include <boost/property_tree/ptree.hpp> +#include <boost/regex.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/config/TriggerReceiverIF.hh" +#include <iostream> +#include <fstream> +#include <stdlib.h> + + +MeasurementTrigger::MeasurementTrigger():AbsTrigger(){ + //std::cout<<"Measurement trigger"<<std::endl; + } + +int MeasurementTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + // number of triggers + m_i=0; + return 0; +} + +int MeasurementTrigger::sendTrigger(){ + //trigger the measurement + TriggerReceiverIF::receive(0, 0); + m_i++; + return 0; +} + + diff --git a/rce/rcecalib/config/MeasurementTrigger.hh b/rce/rcecalib/config/MeasurementTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..bc4e744759be3d1cd8de162ff55fe7757015fcfd --- /dev/null +++ b/rce/rcecalib/config/MeasurementTrigger.hh @@ -0,0 +1,18 @@ +#ifndef MEASUREMENTTRIGGER_HH +#define MEASUREMENTTRIGGER_HH + +#include "rcecalib/config/AbsTrigger.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <string> + + class MeasurementTrigger: public AbsTrigger{ + public: + MeasurementTrigger(); + ~MeasurementTrigger(){}; + int sendTrigger(); + int enableTrigger(bool on){return 0;} + int configureScan(boost::property_tree::ptree* scanOptions); + }; + + +#endif diff --git a/rce/rcecalib/config/ModuleFactory.hh b/rce/rcecalib/config/ModuleFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..9b01340a13817d606dd7429050c235d704d029bc --- /dev/null +++ b/rce/rcecalib/config/ModuleFactory.hh @@ -0,0 +1,22 @@ +#ifndef MODULEFACTORY_HH +#define MODULEFACTORY_HH + +#include "rcecalib/config/AbsModule.hh" +#include "rcecalib/config/AbsModuleGroup.hh" +#include "rcecalib/config/AbsTrigger.hh" + +class ConfigIF; + +class ModuleFactory{ +public: + ModuleFactory(){}; + virtual ~ModuleFactory(){}; + virtual AbsModule* createModule(const char* name, const char* type, unsigned id, unsigned inlink, unsigned outlink, const char* formatter)=0; + virtual AbsTrigger* createTriggerIF(const char* type, ConfigIF* cif)=0; + std::vector<AbsModuleGroup*> &getModuleGroups(){return m_modulegroups;} +protected: + std::vector<AbsModuleGroup*> m_modulegroups; +}; + + +#endif diff --git a/rce/rcecalib/config/ModuleInfo.hh b/rce/rcecalib/config/ModuleInfo.hh new file mode 100644 index 0000000000000000000000000000000000000000..4cd1f5defd88d84c200d5fb5f2f4a42d3e3eb1a3 --- /dev/null +++ b/rce/rcecalib/config/ModuleInfo.hh @@ -0,0 +1,32 @@ +#ifndef MODULEINFO_HH +#define MODULEINFO_HH + +class AbsFormatter; + +class ModuleInfo{ +public: + ModuleInfo(std::string name, int id, int inLink, int outLink, + int nFE, int nRow, int nCol, AbsFormatter* fmt): + m_name(name), m_id(id),m_inLink(inLink),m_outLink(outLink), + m_nFE(nFE), m_nRow(nRow), m_nCol(nCol), m_formatter(fmt){} + std::string getName(){return m_name;} + int getId(){return m_id;} + int getInLink(){return m_inLink;} + int getOutLink(){return m_outLink;} + int getNFrontends(){return m_nFE;} + int getNRows(){return m_nRow;} + int getNColumns(){return m_nCol;} + AbsFormatter* getFormatter(){return m_formatter;} + +private: + std::string m_name; + int m_id; + int m_inLink; + int m_outLink; + int m_nFE; + int m_nRow; + int m_nCol; + AbsFormatter* m_formatter; +}; + +#endif diff --git a/rce/rcecalib/config/MultiShotTrigger.cc b/rce/rcecalib/config/MultiShotTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..8a7919406ec3741ef3cca12bb298094696df8ab1 --- /dev/null +++ b/rce/rcecalib/config/MultiShotTrigger.cc @@ -0,0 +1,78 @@ + +#include "rcecalib/config/MultiShotTrigger.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" + + +MultiShotTrigger::MultiShotTrigger():AbsTrigger(),m_ntrig(0), m_interval(0){ + m_parameters.push_back("TRIGGER_DELAY"); +} +int MultiShotTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + m_ntrig = scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + m_leading0 = scanOptions->get<int>("trigOpt.CalL1ADelay"); + m_interval=scanOptions->get<int>("trigOpt.Lvl1_Latency_Secondary"); + std::cout<<"Setting up "<<m_ntrig<<" Triggers with an interval of "<<m_interval<<std::endl; + setupTriggerStream(); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; +} +int MultiShotTrigger::setupParameter(const char* name, int val){ + return 0; +} + +void MultiShotTrigger::setupTriggerStream(){ + m_triggerStream.clear(); + int totallength=m_leading0+m_ntrig*5+(m_ntrig-1)*(m_interval-5); + for(int i=0;i<totallength/32;i++)m_triggerStream.push_back(0); + if(totallength%32!=0)m_triggerStream.push_back(0); + for(int i=0;i<5;i++){ + if(i==3)continue; + for(int j=0;j<m_ntrig;j++){ + int bit=m_leading0+i+j*m_interval; + setBit(m_triggerStream,bit); + } + } + SerialIF::writeRegister(19,0); + for (size_t i=0;i<m_triggerStream.size();i++){ + SerialIF::writeRegister(18,m_triggerStream[i]); + std::cout<<std::hex<<m_triggerStream[i]<<std::dec<<std::endl; + } + SerialIF::writeRegister(27,1); +} +void MultiShotTrigger::setBit(std::vector<unsigned> &vec, int bit){ + int wordpos=bit/32; + int bitpos=31-bit%32; + if(vec.size()<=(unsigned)wordpos)return; + vec[wordpos]|=1<<bitpos; +} + +int MultiShotTrigger::sendTrigger(){ + //std::cout<<"Trigger::Trigger "<<m_i<<std::endl; + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); + m_i++; + return 0; +} + +int MultiShotTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; +} +int MultiShotTrigger::resetCounters(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FEI3::FECommands::sendECR(bs); + FEI3::FECommands::sendBCR(bs); + SerialIF::send(bs,SerialIF::WAITFORDATA); + delete bs; + return 0; +} diff --git a/rce/rcecalib/config/MultiShotTrigger.hh b/rce/rcecalib/config/MultiShotTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..e669397c6fc5d0a3fbe2fb37cdc6915f8b1cf767 --- /dev/null +++ b/rce/rcecalib/config/MultiShotTrigger.hh @@ -0,0 +1,28 @@ +#ifndef MULTISHOTTRIGGER_HH +#define MULTISHOTTRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" + + + class MultiShotTrigger: public AbsTrigger{ + public: + MultiShotTrigger(); + ~MultiShotTrigger(){}; + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + void setBit(std::vector<unsigned> &vec, int bit); + private: + BitStream m_triggerStream; + int m_ntrig; + int m_interval; + int m_leading0; + }; + + +#endif diff --git a/rce/rcecalib/config/MultiTrigger.cc b/rce/rcecalib/config/MultiTrigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..c87bd2f4da153f80c8e7310f43be96d80cae6443 --- /dev/null +++ b/rce/rcecalib/config/MultiTrigger.cc @@ -0,0 +1,277 @@ + +#include "rcecalib/config/MultiTrigger.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" +#ifdef __rtems__ +#include "rcecalib/HW/Headers.hh" +#include "rcecalib/HW/RCDImaster.hh" +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, pic, Tds.hh) +#include DAT_PUBLIC( oldPpi, pic, Pool.hh) +#include DAT_PUBLIC( oldPpi, pgp, Driver.hh) +#include DAT_PUBLIC( oldPpi, pgp, DriverList.hh) +#else +#include "rce/pic/Pool.hh" +#include "rce/pgp/Driver.hh" +#include "rce/pgp/DriverList.hh" +#include "rce/pic/Tds.hh" +#endif +#include "namespace_aliases.hh" +using namespace PgpTrans; +#endif + + + MultiTrigger::MultiTrigger():AbsTrigger(), + m_calL1ADelay(-1),m_repetitions(0),m_interval(0),m_nIntervals(0),m_injectForTrigger(1){ + m_parameters.push_back("TRIGGER_DELAY"); + m_parameters.push_back("MULTITRIG_INTERVAL"); +#ifdef __rtems__ + const RcePic::Params Tx = { + RcePic::NonContiguous, + 16, // Header + 64*132, // Payload + 1 // Number of buffers + }; + + m_pool = new RcePic::Pool::Pool(Tx); + m_tds=m_pool->allocate(); + assert (m_tds!=0); + char* header=(char*)m_tds->header(); + int headersize=m_tds->headersize(); + for (int i=0;i<headersize;i++)header[i]=0; + new(m_tds->header())BlockWriteTxHeader(0); +#endif + } + MultiTrigger::~MultiTrigger(){ +#ifdef __rtems__ + m_pool->deallocate(m_tds); + delete m_pool; +#endif + } + int MultiTrigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + m_calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + m_repetitions = scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + m_injectForTrigger = scanOptions->get<int>("trigOpt.injectForTrigger"); + + std::cout<<"I'm here right?"<<std::endl; + m_nIntervals = scanOptions->get<int>("scanLoop_0.nPoints"); + std::cout<<"intervals = "<<m_nIntervals<<std::endl; + m_intervals.clear(); + + /* + char pointname[100]; + for(int ii=0; ii<m_nIntervals; ii++){ + sprintf(pointname,"scanLoop_1.dataPoints.P_%d",ii); + int interval = scanOptions->get<int>(pointname); + m_intervals.push_back(interval); + std::cout<<"interval_"<<ii<<" = "<<interval<<std::endl; + } + */ + + m_interval = 241; // m_intervals[0]; + std::cout<<"interval = "<<m_interval<<std::endl; + + setupTriggerStream(); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + + int MultiTrigger::setupParameter(const char* name, int val){ + + if(std::string(name)=="MULTITRIG_INTERVAL"){ + if(val!=m_interval){ // have to redo trigger stream + std::cout<<"Remaking trigger stream with interval "<<val<<std::endl; + m_interval=val; + setupTriggerStream(); + } + } + else if(std::string(name)=="TRIGGER_DELAY"){ + if(val!=m_calL1ADelay){ // have to redo trigger stream + // std::cout<<"Setting up trigger stream. Delay is "<<val<<std::endl; + m_calL1ADelay=val; + setupTriggerStream(); + } + } + return 0; + } + + void MultiTrigger::setupTriggerStream(){ +#ifdef __rtems__ + unsigned* payload=(unsigned*)m_tds->payload(); +#endif + m_triggerStream.clear(); + //prepend 4 zeroes a la NewDsp + BitStreamUtils::prependZeros(&m_triggerStream); + std::vector<char> bytestream; + + /*Create trigger stream */ + /*m_repetitions number of CAL commands, each separated by m_interval zeros. */ + /*Then there is a delay, followed by m_repetitions number of L1A commands. */ + /*The L1A commands are separated by (m_interval+4) zeros, since the L1A commands */ + /*are shorter than CAL commands. */ + /*The delay between the CAL commands and the L1A commands is set by m_calL1ADelay, */ + /*which is the delay between end of the first CAL and end of the first L1A command. */ + /* CAL is a slow command with 9 bits 101100100, L1A is 5 bits 11101*/ + + /*This code only works for m_repetitions=2. */ + + /*WARNING: If m_interval has the wrong value, then */ + /*trigger stream won't make sense, because the CAL command will overlap */ + /*with the L1A's command */ + /*For two-trigger case, this means*/ + /*m_interval <= (m_calL1ADelay-14) or m_interval >= m_calL1ADelay. */ + + std::cout<<"MultiTrigger setup: calL1ADelay = "<<m_calL1ADelay<<" ; interval = "<<m_interval<<" ; repetitions = "<<m_repetitions<<std::endl; + + if(m_repetitions!=2){ + std::cout<<"MultiTrigger currently only implemented for two-trigger case. Ignoring m_repetitions = "<<m_repetitions<<std::endl; + } + + if(m_interval>m_calL1ADelay-14 && m_interval < m_calL1ADelay){ + std::cout<<"ERROR in MultiTrigger.cc: m_interval = "<<m_interval<<" has a forbidden value!"<<std::endl; + std::cout<<"Cannot allow CAL commands and L1A commands to overlap!"<<std::endl; + } + + + int totalLen = 16 + m_interval + 9 + m_calL1ADelay; + int numChars = totalLen/8; + if(totalLen%8 !=0){ + numChars++; + } + + std::cout<<"Making bytestream "<<numChars<<" bytes long."<<std::endl; + + std::vector<char> bytestream1(numChars, 0); + std::vector<char> bytestream2(numChars, 0); + std::vector<char> bytestream3(numChars, 0); + std::vector<char> bytestream4(numChars, 0); + + //m_injectForTrigger is a bit mask. if bit 0 is enabled, then inject on first trigger. + //if bit 1 is enabled, then inject on second trigger. + + if( m_injectForTrigger&1 ){ + //do a pulse injection for the first trigger + createByteStream(bytestream1,0x0164,9,7); /* 101100100 (9bits) = CAL */ + } + // else{ + // //don't do a pulse injection for the first trigger + // createByteStream(bytestream1,0x0000,9,7); + // } + + if( m_injectForTrigger&2 ){ + //do a pulse injection for the second trigger + createByteStream(bytestream2,0x0164,9,16+m_interval); //2nd CAL command + } + + createByteStream(bytestream3,0x1d,5,16+m_calL1ADelay-5); /* 11101 (5bits) = L1A */ + createByteStream(bytestream4,0x1d,5,16+m_interval+9+m_calL1ADelay-5); //2nd L1A command + + + //The overall bytestream is the logical OR of each of the individual bytestreams + for(int ibyte=0; ibyte<numChars; ibyte++){ + + char finalByte = bytestream1[ibyte]; + finalByte = finalByte | bytestream2[ibyte]; + finalByte = finalByte | bytestream3[ibyte]; + finalByte = finalByte | bytestream4[ibyte]; + + bytestream.push_back(finalByte); + } + + while(bytestream.size()%4!=0)bytestream.push_back(0); + + + // for (size_t i=0;i<bytestream.size();i++)std::cout<<std::hex<<(unsigned)bytestream[i]<<std::dec<<std::endl; + // std::cout<<"byte stream size is "<<bytestream.size()<<std::endl; + + for(unsigned int i=0;i<bytestream.size()/4;i++){ + unsigned word=0; + for (int j=0;j<4;j++){ + word<<=8; + word|=bytestream[i*4+j]; + } + m_triggerStream.push_back(word); + } + + + //std::cout<<"Length of trigger stream is "<<m_triggerStream.size()<<std::endl; + //for(size_t i=0; i<m_triggerStream.size(); i++){ + // std::cout<<std::hex<<(unsigned)m_triggerStream[i]<<std::dec<<std::endl; + //} + + + //SerialIF::writeRegister(19,0); + //for (size_t i=0;i<m_triggerStream.size();i++)SerialIF::writeRegister(18,m_triggerStream[i]); +#ifdef __rtems__ + for (size_t i=0;i<m_triggerStream.size();i++)payload[i]=m_triggerStream[i]; + m_tds->payloadsize(m_triggerStream.size()*sizeof(unsigned)); + m_tds->flush(true); +#endif + } + + int MultiTrigger::sendTrigger(){ +#ifdef __rtems__ + RCDImaster::instance()->blockWrite(m_tds); + //SerialIF::sendCommand(0xa); +#else + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); +#endif + m_i++; + return 0; + } + + int MultiTrigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int MultiTrigger::resetCounters(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FEI3::FECommands::sendECR(bs); + FEI3::FECommands::sendBCR(bs); + SerialIF::send(bs,SerialIF::WAITFORDATA); + delete bs; + return 0; + } + +void MultiTrigger::createByteStream(std::vector<char>& stream, unsigned int command, unsigned int len, unsigned int offset){ + + // std::cout<<"byte stream "<<command<<" length = "<<len<<" offset = "<<offset<<std::endl; + + assert(len<=9); //if len>9, some parts of function would have to change + + int shift = 16 - len; + command = (command<<shift); + + unsigned int numChars = offset/8; + offset = offset%8; + + //if len>9, then the following command could potentially erase bits, which we don't want + command = (command>>offset); + char byte1 = (command >> 8 ) & 0xff; + char byte2 = command & 0xff; + + stream[numChars] = byte1; + if( (offset+len)>8 ){ + stream[numChars+1] = byte2; + } + + + // for(size_t i=0; i<stream.size(); i++){ + // std::cout<<std::hex<<(unsigned)stream[i]<<std::dec<<std::endl; + // } + // std::cout<<std::endl<<std::endl; + +} diff --git a/rce/rcecalib/config/MultiTrigger.hh b/rce/rcecalib/config/MultiTrigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..cca02d6850bd80908695d256a3e3425d75db17a2 --- /dev/null +++ b/rce/rcecalib/config/MultiTrigger.hh @@ -0,0 +1,36 @@ +#ifndef MULTITRIGGER_HH +#define MULTITRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" +#include "namespace_aliases.hh" + + + + + class MultiTrigger: public AbsTrigger{ + public: + MultiTrigger(); + ~MultiTrigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + private: + void createByteStream(std::vector<char>& stream, unsigned int command, unsigned int len, unsigned int offset); + BitStream m_triggerStream; + int m_calL1ADelay; + int m_repetitions; + int m_interval; + int m_nIntervals; + std::vector<int> m_intervals; + int m_injectForTrigger; + RcePic::Tds* m_tds; + RcePic::Pool *m_pool; + }; + + +#endif diff --git a/rce/rcecalib/config/Trigger.cc b/rce/rcecalib/config/Trigger.cc new file mode 100644 index 0000000000000000000000000000000000000000..cdde49f9b5833610e6d872b6dcac9992b0fd094f --- /dev/null +++ b/rce/rcecalib/config/Trigger.cc @@ -0,0 +1,154 @@ + +#include "rcecalib/config/Trigger.hh" +#include "rcecalib/config/FEI3/FECommands.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/HW/SerialIF.hh" +#include "rcecalib/profiler/Profiler.hh" +#ifdef __rtems__ +#include "rcecalib/HW/Headers.hh" +#include "rcecalib/HW/RCDImaster.hh" +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, pic, Tds.hh) +#include DAT_PUBLIC( oldPpi, pic, Pool.hh) +#include DAT_PUBLIC( oldPpi, pgp, Driver.hh) +#include DAT_PUBLIC( oldPpi, pgp, DriverList.hh) +#else +#include "rce/pic/Pool.hh" +#include "rce/pgp/Driver.hh" +#include "rce/pgp/DriverList.hh" +#include "rce/pic/Tds.hh" +#endif +#include "namespace_aliases.hh" +using namespace PgpTrans; +#endif + +namespace FEI3{ + + Trigger::Trigger():AbsTrigger(),m_calL1ADelay(-1){ + m_parameters.push_back("TRIGGER_DELAY"); +#ifdef __rtems__ + const RcePic::Params Tx = { + RcePic::NonContiguous, + 16, // Header + 64*132, // Payload + 1 // Number of buffers + }; + + m_pool = new RcePic::Pool::Pool(Tx); + m_tds=m_pool->allocate(); + assert (m_tds!=0); + char* header=(char*)m_tds->header(); + int headersize=m_tds->headersize(); + for (int i=0;i<headersize;i++)header[i]=0; + new(m_tds->header())BlockWriteTxHeader(0); +#endif + } + Trigger::~Trigger(){ +#ifdef __rtems__ + m_pool->deallocate(m_tds); + delete m_pool; +#endif + } + int Trigger::configureScan(boost::property_tree::ptree* scanOptions){ + int retval=0; + m_i=0; //reset the number of triggers + try{ + int calL1ADelay = scanOptions->get<int>("trigOpt.CalL1ADelay"); + if(calL1ADelay==-1 || calL1ADelay!=m_calL1ADelay){ // have to redo trigger stream + m_calL1ADelay=calL1ADelay; + setupTriggerStream(); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; + } + int Trigger::setupParameter(const char* name, int val){ + if(std::string(name)=="TRIGGER_DELAY"){ + if(val!=m_calL1ADelay){ // have to redo trigger stream + // std::cout<<"Setting up trigger stream. Delay is "<<val<<std::endl; + m_calL1ADelay=val; + setupTriggerStream(); + } + } + return 0; + } + + void Trigger::setupTriggerStream(){ +#ifdef __rtems__ + unsigned* payload=(unsigned*)m_tds->payload(); +#endif + m_triggerStream.clear(); + //prepend 4 zeroes a la NewDsp + BitStreamUtils::prependZeros(&m_triggerStream); + std::vector<char> bytestream; + /* calculate the size required for this stream */ + /*trigger delay is between end of CAL and L1A command */ + /* CAL is a slow command with 9 bits 101100100, L1A is 5 bits 11101*/ + /* form the trigger stream */ + bytestream.push_back(0x01); + bytestream.push_back(0x64); /* 101100100 (9bits) = CAL */ + /* at this point, still have to provide (delay - 5) zero bits */ + if(m_calL1ADelay!=0xffff){ + int nBits = m_calL1ADelay - 5; + int nBytes = nBits >> 3; + for(int k=0;k<nBytes;++k) bytestream.push_back(0); + unsigned short t = (0xE800 >> (nBits & 0x7)); + bytestream.push_back((t >> 8) & 0xff); + bytestream.push_back(t & 0xff); + }else{ + std::cout<<"CAL strobe only."<<std::endl; + } + while(bytestream.size()%4!=0)bytestream.push_back(0); + //for (size_t i=0;i<bytestream.size();i++)std::cout<<std::hex<<(unsigned)bytestream[i]<<std::dec<<std::endl; + //std::cout<<"Size is "<<bytestream.size()<<std::endl; + for(unsigned int i=0;i<bytestream.size()/4;i++){ + unsigned word=0; + for (int j=0;j<4;j++){ + word<<=8; + word|=bytestream[i*4+j]; + } + m_triggerStream.push_back(word); + } + m_triggerStream.push_back(0); + std::cout<<"Size of trigger stream is "<<m_triggerStream.size()*4<<" bytes"<<std::endl; + SerialIF::writeRegister(19,0); + //for (size_t i=0;i<m_triggerStream.size();i++)SerialIF::writeRegister(18,m_triggerStream[i]); +#ifdef __rtems__ + for (size_t i=0;i<m_triggerStream.size();i++)payload[i]=m_triggerStream[i]; + m_tds->payloadsize(m_triggerStream.size()*sizeof(unsigned)); + m_tds->flush(true); +#endif + } + + int Trigger::sendTrigger(){ + //std::cout<<"Trigger "<<m_i<<std::endl; +#ifdef __rtems__ + RCDImaster::instance()->blockWrite(m_tds); + //SerialIF::sendCommand(0xa); +#else + SerialIF::send(&m_triggerStream,SerialIF::DONT_CLEAR|SerialIF::WAITFORDATA); +#endif + m_i++; + return 0; + } + + int Trigger::enableTrigger(bool on){ + return SerialIF::enableTrigger(on); + return 0; + } + int Trigger::resetCounters(){ + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FECommands::sendECR(bs); + FECommands::sendBCR(bs); + SerialIF::send(bs,SerialIF::WAITFORDATA); + delete bs; + return 0; + } +}; diff --git a/rce/rcecalib/config/Trigger.hh b/rce/rcecalib/config/Trigger.hh new file mode 100644 index 0000000000000000000000000000000000000000..68135ea89a24ca19dc068490f39c2be26bd1587e --- /dev/null +++ b/rce/rcecalib/config/Trigger.hh @@ -0,0 +1,31 @@ +#ifndef FEI3__TRIGGER_HH +#define FEI3__TRIGGER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/AbsTrigger.hh" +#include "rcecalib/HW/BitStream.hh" +#include "namespace_aliases.hh" + + +namespace FEI3{ + + class Trigger: public AbsTrigger{ + public: + Trigger(); + ~Trigger(); + int configureScan(boost::property_tree::ptree* scanOptions); + int setupParameter(const char* name, int val); + int sendTrigger(); + int enableTrigger(bool on); + int resetCounters(); + void setupTriggerStream(); + private: + BitStream m_triggerStream; + int m_calL1ADelay; + RcePic::Tds* m_tds; + RcePic::Pool *m_pool; + }; + +}; + +#endif diff --git a/rce/rcecalib/config/TriggerReceiverIF.cc b/rce/rcecalib/config/TriggerReceiverIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..68db9d0ca8cbcd0fd308ffc0e729cc667f1f1bdd --- /dev/null +++ b/rce/rcecalib/config/TriggerReceiverIF.cc @@ -0,0 +1,15 @@ +#include "rcecalib/config/TriggerReceiverIF.hh" +#include <assert.h> + +TriggerReceiverIF::TriggerReceiverIF(){ + s_rec=this; +} +TriggerReceiverIF::~TriggerReceiverIF(){ + s_rec=0; +} +void TriggerReceiverIF::receive(unsigned *data, int size){ + assert(s_rec); + s_rec->Receive(data, size); +} + +TriggerReceiverIF* TriggerReceiverIF::s_rec=0; diff --git a/rce/rcecalib/config/TriggerReceiverIF.hh b/rce/rcecalib/config/TriggerReceiverIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..2ef1c66c939636d8b5b1377f7b54e991df21bf61 --- /dev/null +++ b/rce/rcecalib/config/TriggerReceiverIF.hh @@ -0,0 +1,13 @@ +#ifndef TRIGGERRECEIVERIF_HH +#define TRIGGERRECEIVERIF_HH + +class TriggerReceiverIF{ +public: + TriggerReceiverIF(); + virtual ~TriggerReceiverIF(); + static void receive(unsigned *data, int size); + virtual void Receive(unsigned* data, int size)=0; +private: + static TriggerReceiverIF* s_rec; +}; +#endif diff --git a/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.cc b/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.cc new file mode 100644 index 0000000000000000000000000000000000000000..593a95e48c6702f9ab9baa912f99e70bcc75f50c --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.cc @@ -0,0 +1,81 @@ +#include "rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/config/afp-hptdc/AFPHPTDCRecord.hh" +#include "rcecalib/config/FEI4/FEI4BRecord.hh" +#include "rcecalib/scanctrl/RceCallback.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include <iostream> +#include <stdio.h> + +AFPHPTDCFormatter::AFPHPTDCFormatter(int id): AbsFormatter(id, "AFPHPTDC"){ +} +AFPHPTDCFormatter::~AFPHPTDCFormatter(){ +} +void AFPHPTDCFormatter::configure(boost::property_tree::ptree* config){ + try{ + for(int i=0;i<2;i++){ + for(int j=0;j<12;j++){ + for(int k=0;k<1024;k++){ + char name[32]; + sprintf(name, "c_%d_%d_%d", i, j, k); + m_calib[i][j][k]=config->get<float>(name); + } + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } +} + +int AFPHPTDCFormatter::decode (const unsigned int *buffer, int buflen, unsigned* parsedData, int &parsedsize, int &nL1A){ + if(buflen==0)return FEI4::FEI4BRecord::Empty; + for(int i=0;i<buflen;i++){ + //std::cout<<"Raw word: "<<std::hex<<buffer[i]<<std::dec<<std::endl; + afphptdc::AFPHPTDCRecord rec(buffer[i]); + if(rec.isHeader()){ + FormattedRecord fr(FormattedRecord::HEADER); + fr.setL1id(rec.getL1id()); + fr.setBxid(rec.getBxid()); + parsedData[parsedsize++]=fr.getWord(); + nL1A++; + //std::cout<<"Header L1id="<<rec.getL1id()<<" bxid="<<rec.getBxid()<<std::endl; + }else if(rec.isData()){ + unsigned dataword=FormattedRecord::DATA; + unsigned tdcid=rec.getTDCid(); + dataword|=tdcid<<24; + unsigned chan=rec.getChannel(); + dataword|=chan<<22; + unsigned edge=rec.getEdge(); + dataword|=edge<<28; + unsigned data=rec.getData(); + if(tdcid>=0xa && tdcid<=0xc){ //TDC id should be 0xa, 0xb, or 0xc + int chanid=(tdcid-0xa)*4+chan; + //applying Inl calibration constants here. + data=(data-(unsigned)m_calib[0][chanid][data&0x3FF])&0x1FFFFF; + }else{ + std::cout<<"Bad TDC id "<<tdcid<<std::endl; + } + dataword|=data; + //std::cout<<"Data TDC id="<<rec.getTDCid()<<" Channel="<<rec.getChannel()<<" Data="<<rec.getData()<<std::endl; + FormattedRecord fr(dataword); + //fr.setDataflag(1); // flags HPTDC data + parsedData[parsedsize++]=fr.getWord(); + }else if(rec.isServiceRecord()){ + //std::cout<<"Received service record with code "<<rec.getErrorCode()<<" and error count "<<rec.getErrorCount()<<std::endl; + }else if(rec.isTdcError()){ + int tdcNum = rec.getTDCid()-0xA; + std::cout<<"Received TDC error for TDC id "<<tdcNum<<" with code 0x"<<std::hex<<rec.getTdcErrorCode()<<std::dec<<std::endl; + }else if(rec.isEmptyRecord()){ + //std::cout<<"Empty record"<<std::endl; + }else{ + std::cout<<"FE "<<getId()<<": Unexpected record type: "<<std::hex<<buffer[i]<<std::dec<<std::endl; + return FEI4::FEI4BRecord::BadRecord; + } + } + return FEI4::FEI4BRecord::OK; +} + diff --git a/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh b/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh new file mode 100644 index 0000000000000000000000000000000000000000..262a9618720af4db2195bb1511d4abfce1079b4f --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh @@ -0,0 +1,16 @@ +#ifndef AFPHPTDCFORMATTER_HH +#define AFPHPTDCFORMATTER_HH + +#include "rcecalib/config/AbsFormatter.hh" + +class AFPHPTDCFormatter:public AbsFormatter{ +public: + AFPHPTDCFormatter(int id); + virtual ~AFPHPTDCFormatter(); + int decode(const unsigned* data, int size, unsigned* parsedData, int &parsedsize, int &nL1A); + void configure(boost::property_tree::ptree* scanOptions); + +private: + float m_calib[2][12][1024]; +}; +#endif diff --git a/rce/rcecalib/config/afp-hptdc/AFPHPTDCRecord.hh b/rce/rcecalib/config/afp-hptdc/AFPHPTDCRecord.hh new file mode 100644 index 0000000000000000000000000000000000000000..0d473b0bc98dcedcaf7a7fa2a250741c6807e48c --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/AFPHPTDCRecord.hh @@ -0,0 +1,30 @@ +#ifndef AFPHPTDC__RECORD_HH +#define AFPHPTDC__RECORD_HH + +namespace afphptdc{ + + class AFPHPTDCRecord{ + public: + AFPHPTDCRecord(unsigned word){(m_record=word);} + virtual ~AFPHPTDCRecord(){}; + bool isData(){return ((m_record>>29)==0x2);} + bool isTdcError(){return ((m_record>>28)==0x6);} + bool isHeader(){return ((m_record>>16)==0xe9);} + bool isServiceRecord(){return ((m_record>>16)==0xef);} + bool isEmptyRecord(){return (m_record==0);} + int getTdcErrorCode(){return m_record&0x7FFF;} + int getL1id(){return (m_record>>8)&0x7f;} + int getBxid(){return m_record&0xff;} + int getEdge(){return (m_record>>28)&0x1;} + int getTDCid(){return (m_record>>24)&0xf;} + int getChannel(){return (m_record>>22)&0x3;} + int getData(){return ((m_record>>19)&0x3) | ((m_record&0x7ffff)<<2);} + int getErrorCode(){return (m_record>>10)&0x3f;} + int getErrorCount(){return m_record&0x3ff;} + private: + unsigned m_record; + +}; + +}; +#endif diff --git a/rce/rcecalib/config/afp-hptdc/IPCModule.cc b/rce/rcecalib/config/afp-hptdc/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..cecc67f2cbb1b8d80bddaebbe7c610a65ddee07f --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/IPCModule.cc @@ -0,0 +1,184 @@ +#ifndef AFPHPTDC__IPCMODULE_CC +#define AFPHPTDC__IPCMODULE_CC +#include "rcecalib/util/RceName.hh" +#include "rcecalib/config/afp-hptdc/IPCModule.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace afphptdc{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::AFPHPTDCModuleConfig &config){ + setFpgaField("test", config.test); + setFpgaField("tdcControl", config.tdcControl); + setFpgaField("run", config.run); + setFpgaField("bypassLut", config.bypassLut); + setFpgaField("localClockEn", config.localClockEn); + setFpgaField("calClockEn", config.calClockEn); + setFpgaField("refEn", config.refEn); + setFpgaField("hitTestEn", config.hitTestEn); + setFpgaField("inputSel", config.inputSel); + setFpgaField("address", config.address); + setFpgaField("fanspeed", config.fanspeed); + setFpgaField("channelEn", config.channelEn); + + for(int i=0;i<3;i++){ + for (int j=31;j>=0;j--){ + char offs[32]; + sprintf(offs, "offset%d", j); + setTdcField(offs, i, config.offset[j][i]); + } + setTdcField("test_select", i, config.test_select[i]); + setTdcField("enable_error_mark", i, config.enable_error_mark[i]); + setTdcField("enable_error_bypass", i, config.enable_error_bypass[i]); + setTdcField("enable_error", i, config.enable_error[i]); + setTdcField("readout_single_cycle_speed", i, config.readout_single_cycle_speed[i]); + setTdcField("serial_delay", i, config.serial_delay[i]); + setTdcField("strobe_select", i, config.strobe_select[i]); + setTdcField("readout_speed_select", i, config.readout_speed_select[i]); + setTdcField("token_delay", i, config.token_delay[i]); + setTdcField("enable_local_trailer", i, config.enable_local_trailer[i]); + setTdcField("enable_local_header", i, config.enable_local_header[i]); + setTdcField("enable_global_trailer", i, config.enable_global_trailer[i]); + setTdcField("enable_global_header", i, config.enable_global_header[i]); + setTdcField("keep_token", i, config.keep_token[i]); + setTdcField("master", i, config.master[i]); + setTdcField("enable_bytewise", i, config.enable_bytewise[i]); + setTdcField("enable_serial", i, config.enable_serial[i]); + setTdcField("enable_jtag_readout", i, config.enable_jtag_readout[i]); + setTdcField("tdc_id", i, config.tdc_id[i]); + setTdcField("select_bypass_inputs", i, config.select_bypass_inputs[i]); + setTdcField("readout_fifo_size", i, config.readout_fifo_size[i]); + setTdcField("reject_count_offset", i, config.reject_count_offset[i]); + setTdcField("search_window", i, config.search_window[i]); + setTdcField("match_window", i, config.match_window[i]); + setTdcField("leading_resolution", i, config.leading_resolution[i]); + setTdcField("fixed_pattern", i, config.fixed_pattern[i]); + setTdcField("enable_fixed_pattern", i, config.enable_fixed_pattern[i]); + setTdcField("max_event_size", i, config.max_event_size[i]); + setTdcField("reject_readout_fifo_full", i, config.reject_readout_fifo_full[i]); + setTdcField("enable_readout_occupancy", i, config.enable_readout_occupancy[i]); + setTdcField("enable_readout_separator", i, config.enable_readout_separator[i]); + setTdcField("enable_overflow_detect", i, config.enable_overflow_detect[i]); + setTdcField("enable_relative", i, config.enable_relative[i]); + setTdcField("enable_automatic_reject", i, config.enable_automatic_reject[i]); + setTdcField("event_count_offset", i, config.event_count_offset[i]); + setTdcField("trigger_count_offset", i, config.trigger_count_offset[i]); + setTdcField("enable_set_counters_on_bunch_reset", i, config.enable_set_counters_on_bunch_reset[i]); + setTdcField("enable_master_reset_code", i, config.enable_master_reset_code[i]); + setTdcField("enable_master_reset_code_on_event_reset", i, config.enable_master_reset_code_on_event_reset[i]); + setTdcField("enable_reset_channel_buffer_when_separator", i, config.enable_reset_channel_buffer_when_separator[i]); + setTdcField("enable_separator_on_event_reset", i, config.enable_separator_on_event_reset[i]); + setTdcField("enable_separator_on_bunch_reset", i, config.enable_separator_on_bunch_reset[i]); + setTdcField("enable_direct_event_reset", i, config.enable_direct_event_reset[i]); + setTdcField("enable_direct_bunch_reset", i, config.enable_direct_bunch_reset[i]); + setTdcField("enable_direct_trigger", i, config.enable_direct_trigger[i]); + setTdcField("coarse_count_offset", i, config.coarse_count_offset[i]); + setTdcField("dll_tap_adjust3_0", i, config.dll_tap_adjust3_0[i]); + setTdcField("dll_tap_adjust7_4", i, config.dll_tap_adjust7_4[i]); + setTdcField("dll_tap_adjust11_8", i, config.dll_tap_adjust11_8[i]); + setTdcField("dll_tap_adjust15_12", i, config.dll_tap_adjust15_12[i]); + setTdcField("dll_tap_adjust19_16", i, config.dll_tap_adjust19_16[i]); + setTdcField("dll_tap_adjust23_20", i, config.dll_tap_adjust23_20[i]); + setTdcField("dll_tap_adjust27_24", i, config.dll_tap_adjust27_24[i]); + setTdcField("dll_tap_adjust31_28", i, config.dll_tap_adjust31_28[i]); + setTdcField("rc_adjust", i, config.rc_adjust[i]); + setTdcField("not_used", i, config.not_used[i]); + setTdcField("low_power_mode", i, config.low_power_mode[i]); + setTdcField("width_select", i, config.width_select[i]); + setTdcField("vernier_offset", i, config.vernier_offset[i]); + setTdcField("dll_control", i, config.dll_control[i]); + setTdcField("dead_time", i, config.dead_time[i]); + setTdcField("test_invert", i, config.test_invert[i]); + setTdcField("test_mode", i, config.test_mode[i]); + setTdcField("enable_trailing", i, config.enable_trailing[i]); + setTdcField("enable_leading", i, config.enable_leading[i]); + setTdcField("mode_rc_compression", i, config.mode_rc_compression[i]); + setTdcField("mode_rc", i, config.mode_rc[i]); + setTdcField("dll_mode", i, config.dll_mode[i]); + setTdcField("pll_control", i, config.pll_control[i]); + setTdcField("serial_clock_delay", i, config.serial_clock_delay[i]); + setTdcField("io_clock_delay", i, config.io_clock_delay[i]); + setTdcField("core_clock_delay", i, config.core_clock_delay[i]); + setTdcField("dll_clock_delay", i, config.dll_clock_delay[i]); + setTdcField("serial_clock_source", i, config.serial_clock_source[i]); + setTdcField("io_clock_source", i, config.io_clock_source[i]); + setTdcField("core_clock_source", i, config.core_clock_source[i]); + setTdcField("dll_clock_source", i, config.dll_clock_source[i]); + setTdcField("roll_over", i, config.roll_over[i]); + setTdcField("enable_matching", i, config.enable_matching[i]); + setTdcField("enable_pair", i, config.enable_pair[i]); + setTdcField("enable_ttl_serial", i, config.enable_ttl_serial[i]); + setTdcField("enable_ttl_control", i, config.enable_ttl_control[i]); + setTdcField("enable_ttl_reset", i, config.enable_ttl_reset[i]); + setTdcField("enable_ttl_clock", i, config.enable_ttl_clock[i]); + setTdcField("enable_ttl_hit", i, config.enable_ttl_hit[i]); + } + AbsFormatter* fmt=getFormatter(); + if(fmt){ + // configure the formatter with the calibration constants + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + for(int i=0;i<2;i++){ + for(int j=0;j<12;j++){ + for(int k=0;k<1024;k++){ + char name[32]; + sprintf(name, "c_%d_%d_%d", i, j, k); + pt->put(name, config.calib[i][j][k]); + } + } + } + std::cout<<"%%%%%%%%% Configuring HPTDC Formatter"<<std::endl; + fmt->configure(pt); + delete pt; + } + return 0; +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/rcecalib/config/afp-hptdc/IPCModule.hh b/rce/rcecalib/config/afp-hptdc/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..2751b29394460a7d2f1fec72dddaea1a8c33c1e1 --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/IPCModule.hh @@ -0,0 +1,26 @@ +#ifndef IPCAFPHPTDCMODULE_HH +#define IPCAFPHPTDCMODULE_HH + +#include "rcecalib/config/afp-hptdc/Module.hh" +#include "ipc/object.h" +#include "AFPHPTDCModuleConfig.hh" +#include "IPCAFPHPTDCAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace afphptdc{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCAFPHPTDCAdapter,TP>, public afphptdc::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::AFPHPTDCModuleConfig &config); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/rcecalib/config/afp-hptdc/Module.cc b/rce/rcecalib/config/afp-hptdc/Module.cc new file mode 100644 index 0000000000000000000000000000000000000000..364f7c9fcccc85ac9c45a339ff833a76f9319f7c --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/Module.cc @@ -0,0 +1,321 @@ +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/afp-hptdc/Module.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> + +namespace afphptdc{ + + Module::Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt) + :AbsModule(name, id,inLink, outLink, fmt){ + //std::cout<<"Module"<<std::endl; + if(!m_initialized)initialize(); + for(int i=0;i<N_FPGA_REGS;i++)m_fpga_registers[i]=0; + for(int j=0;j<3;j++) + for(int i=0;i<N_TDC_REGS;i++) + m_tdc_registers[j][i]=0; + m_commands=new FEI4::FECommands; + } + Module::~Module(){ + delete m_commands; + } + void Module::writeHW(){ + //FPGA registers + for(std::map<int, int>::const_iterator it=m_used_regs.begin(); it!=m_used_regs.end(); it++){ + writeRegisterRawHW(it->first, (unsigned short)m_fpga_registers[it->first]); + } + for(int i=0;i<3;i++){ + writeTdcBitstreamHW(i); + } + } + void Module::writeTdcBitstreamHW(int i){ + // calculate parity; + int parity=0; + for(int j=0;j<=m_regpos;j++){ + for(int k= j==m_regpos? m_bitpos+1 : 0;k<32;k++){ + parity^=(m_tdc_registers[i][j]>>k)&0x1; + } + } + setTdcField("parity", i, parity); + BitStream *bs=new BitStream; + m_commands->feWriteCommand(bs); + (*bs)[bs->size()-1]|=i; //bitstream address + for(int j=0;j<N_TDC_REGS;j++){ + bs->push_back(m_tdc_registers[i][j]); + } + SerialIF::send(bs); //Write bitstream + delete bs; + } + unsigned Module::writeRegisterHW(int i, unsigned short val){ + // i is position in vector, not actual address + /* + m_regw[i]=val; // set register content + int addr=m_registers[i].reg; + int rval=val&((1<<m_registers[i].width)-1); + writeRegisterRawHW(addr, rval); + */ + return 0; + } + void Module::writeRegisterRawHW(int i, unsigned short val){ + BitStream *bs=new BitStream; + m_commands->writeGlobalRegister(bs, i, val); + SerialIF::send(bs); //Write register + delete bs; + } + + void Module::configureHW(){ + std::cout<<"Configuring HPTDC"<<std::endl; + resetFE(); + SerialIF::setDataRate(SerialIF::M160); + writeHW(); + //printRegisters(std::cout); + } + void Module::enableDataTakingHW(){ + std::cout<<"AFPHPTDC Enabled data taking Board "<<getId()<<std::endl; + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + m_commands->switchMode(bs, FEI4::FECommands::RUN); + m_commands->sendECR(bs); + m_commands->sendBCR(bs); + SerialIF::send(bs); + delete bs; + } + void Module::switchToConfigModeHW(){ + std::cout<<"AFPHPTDC Switched to Config Mode Board "<<getId()<<std::endl; + BitStream *bs=new BitStream; + m_commands->switchMode(bs, FEI4::FECommands::CONF); + bs->push_back(0); + SerialIF::send(bs, SerialIF::WAITFORDATA); + delete bs; + } + + void Module::resetFE(){ + BitStream *bs=new BitStream; + m_commands->globalReset(bs); + delete bs; + } + + // set a parameter (global or MCC) in the frontend + int Module::setupParameterHW(const char* name, int val){ + int retval=1; + /* + if(m_parameters.find(name)!=m_parameters.end()){ + retval=0; + writeRegisterHW(m_parameters[name], val); + } + */ + return retval; + } + + int Module::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + // do nothing for now + return retval; + } + void Module::destroy(){ + delete this; + } + ModuleInfo Module::getModuleInfo(){ + return ModuleInfo(m_name, m_id,m_inLink, m_outLink, 1, 12, 1, m_formatter); + } + + void Module::printRegisters(std::ostream &os){ + std::cout<<"FPGA Registers"<<std::endl; + for(std::map<int, int>::const_iterator it=m_used_regs.begin(); it!=m_used_regs.end(); it++){ + os<<"Address = "<<it->first<<" Value = 0x"<<std::hex<<m_fpga_registers[it->first]<<std::dec<<std::endl; + } + for (int i=0;i<3;i++){ + std::cout<<"TDC Registers Bitstream "<<i<<std::endl; + for(int j=0;j<N_TDC_REGS;j++){ + std::cout<<std::hex<<m_tdc_registers[i][j]<<std::dec<<std::endl; + } + } + } + + //static functions + //void Module::addParameter(const char* name, const char* field){ +// int regnum=findRegister(field); +// assert(regnum>-1); +// m_parameters[name]=regnum; + //} + void Module::setFpgaField(const char* name, unsigned val){ + char msg[128]; + sprintf(msg,"parameter %s is invalid",name); + ERS_ASSERT_MSG(m_fpga_fields.find(name)!=m_fpga_fields.end(),msg); + assert(m_fpga_fields.find(name)!=m_fpga_fields.end()); + FieldParams params=m_fpga_fields[name]; + setFieldFun(&m_fpga_registers[params.reg], params.pos, params.width, val); + } + void Module::setTdcField(const char* name, int index, unsigned val){ + char msg[128]; + sprintf(msg,"parameter %s is invalid",name); + //ERS_ASSERT_MSG(m_tdc_fields.find(name)!=m_tdc_fields.end(),msg); + assert(m_tdc_fields.find(name)!=m_tdc_fields.end()); + FieldParams params=m_tdc_fields[name]; + //reverse bit order of fields + unsigned valRev = 0; + for (int i=0;i<params.width;i++){ + valRev <<= 1; + valRev |= val & 1; + val >>= 1; + } + setFieldFun(&m_tdc_registers[index][params.reg], params.pos, params.width, valRev); + } + void Module::setFieldFun(unsigned *reg, int bitpos, int width, unsigned val){ + int pwidth=bitpos+width<=32 ? width : 32 - bitpos; + unsigned mask=(1<<width)-1; + mask=(1<<pwidth)-1; + *reg&=~(mask<<bitpos); + *reg|=(val&mask)<<bitpos; + if(pwidth!=width){ // extends over next register + int rwidth=width-pwidth; + mask=(1<<rwidth)-1; + *(reg-1)&=~mask; + *(reg-1)|=(val>>pwidth); + } + } + + void Module::addFpgaField(const char* name, int reg, int width, int pos){ + FieldParams temp; + temp.reg=reg; + temp.width=width; + temp.pos=pos; + m_fpga_fields[name]=temp; + } + void Module::addTdcField(const char* name, int width){ + m_bitpos-=width; + if(m_bitpos<0){ + m_bitpos+=32; + m_regpos+=1; + } + FieldParams temp; + temp.reg=m_regpos; + temp.width=width; + temp.pos=m_bitpos; + m_tdc_fields[name]=temp; + } + std::map<std::string, FieldParams> Module::m_fpga_fields; + std::map<std::string, FieldParams> Module::m_tdc_fields; + std::map<int, int> Module::m_used_regs; + bool Module::m_initialized = false; + int Module::m_regpos=0; + int Module::m_bitpos=32; + + void Module::initialize(){ + addFpgaField("test", 32, 16, 0); + addFpgaField("tdcControl", 28, 4, 0); + addFpgaField("run", 29, 1, 0); + addFpgaField("bypassLut", 29, 1, 2); + addFpgaField("localClockEn", 29, 1, 3); + addFpgaField("calClockEn", 29, 1, 4); + addFpgaField("refEn", 29, 1, 5); + addFpgaField("hitTestEn", 29, 1, 6); + addFpgaField("inputSel", 29, 3, 8); + addFpgaField("address", 20, 8, 0); + addFpgaField("fanspeed", 27, 8, 0); + addFpgaField("channelEn", 26, 12, 0); + + for(std::map<std::string, FieldParams>::const_iterator it=m_fpga_fields.begin(); it!=m_fpga_fields.end(); it++){ + FieldParams p=it->second; + m_used_regs[p.reg]=1; + } + addTdcField("test_select", 4); + addTdcField("enable_error_mark", 1); + addTdcField("enable_error_bypass", 1); + addTdcField("enable_error", 11); + addTdcField("readout_single_cycle_speed", 3); + addTdcField("serial_delay", 4); + addTdcField("strobe_select", 2); + addTdcField("readout_speed_select", 1); + addTdcField("token_delay", 4); + addTdcField("enable_local_trailer", 1); + addTdcField("enable_local_header", 1); + addTdcField("enable_global_trailer", 1); + addTdcField("enable_global_header", 1); + addTdcField("keep_token", 1); + addTdcField("master", 1); + addTdcField("enable_bytewise", 1); + addTdcField("enable_serial", 1); + addTdcField("enable_jtag_readout", 1); + addTdcField("tdc_id", 4); + addTdcField("select_bypass_inputs", 1); + addTdcField("readout_fifo_size", 3); + addTdcField("reject_count_offset", 12); + addTdcField("search_window", 12); + addTdcField("match_window", 12); + addTdcField("leading_resolution", 3); + addTdcField("fixed_pattern", 28); + addTdcField("enable_fixed_pattern", 1); + addTdcField("max_event_size", 4); + addTdcField("reject_readout_fifo_full", 1); + addTdcField("enable_readout_occupancy", 1); + addTdcField("enable_readout_separator", 1); + addTdcField("enable_overflow_detect", 1); + addTdcField("enable_relative", 1); + addTdcField("enable_automatic_reject", 1); + addTdcField("event_count_offset", 12); + addTdcField("trigger_count_offset", 12); + addTdcField("enable_set_counters_on_bunch_reset", 1); + addTdcField("enable_master_reset_code", 1); + addTdcField("enable_master_reset_code_on_event_reset", 1); + addTdcField("enable_reset_channel_buffer_when_separator", 1); + addTdcField("enable_separator_on_event_reset", 1); + addTdcField("enable_separator_on_bunch_reset", 1); + addTdcField("enable_direct_event_reset", 1); + addTdcField("enable_direct_bunch_reset", 1); + addTdcField("enable_direct_trigger", 1); + for (int j=31;j>=0;j--){ + char offs[32]; + sprintf(offs, "offset%d", j); + addTdcField(offs, 9); + } + addTdcField("coarse_count_offset", 12); + addTdcField("dll_tap_adjust3_0", 12); + addTdcField("dll_tap_adjust7_4", 12); + addTdcField("dll_tap_adjust11_8", 12); + addTdcField("dll_tap_adjust15_12", 12); + addTdcField("dll_tap_adjust19_16", 12); + addTdcField("dll_tap_adjust23_20", 12); + addTdcField("dll_tap_adjust27_24", 12); + addTdcField("dll_tap_adjust31_28", 12); + addTdcField("rc_adjust", 12); + addTdcField("not_used", 3); + addTdcField("low_power_mode", 1); + addTdcField("width_select", 4); + addTdcField("vernier_offset", 5); + addTdcField("dll_control", 4); + addTdcField("dead_time", 2); + addTdcField("test_invert", 1); + addTdcField("test_mode", 1); + addTdcField("enable_trailing", 1); + addTdcField("enable_leading", 1); + addTdcField("mode_rc_compression", 1); + addTdcField("mode_rc", 1); + addTdcField("dll_mode", 2); + addTdcField("pll_control", 8); + addTdcField("serial_clock_delay", 4); + addTdcField("io_clock_delay", 4); + addTdcField("core_clock_delay", 4); + addTdcField("dll_clock_delay", 4); + addTdcField("serial_clock_source", 2); + addTdcField("io_clock_source", 2); + addTdcField("core_clock_source", 2); + addTdcField("dll_clock_source", 3); + addTdcField("roll_over", 12); + addTdcField("enable_matching", 1); + addTdcField("enable_pair", 1); + addTdcField("enable_ttl_serial", 1); + addTdcField("enable_ttl_control", 1); + addTdcField("enable_ttl_reset", 1); + addTdcField("enable_ttl_clock", 1); + addTdcField("enable_ttl_hit", 1); + addTdcField("parity", 1); + m_initialized=true; + std::cout<<"Regpos "<<m_regpos<<std::endl; + std::cout<<"Bitpos "<<m_bitpos<<std::endl; + } +} diff --git a/rce/rcecalib/config/afp-hptdc/Module.hh b/rce/rcecalib/config/afp-hptdc/Module.hh new file mode 100644 index 0000000000000000000000000000000000000000..d2702757a92f188e0025601d527a84bf5fab6dc5 --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/Module.hh @@ -0,0 +1,64 @@ +#ifndef AFPHPTDC__MODULE_HH +#define AFPHPTDC__MODULE_HH + +#include "rcecalib/config/AbsModule.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <map> +#include <string> + +class AbsFormatter; +namespace FEI4{ + class FECommands; +}; + +namespace afphptdc{ + + struct FieldParams{ + int reg; + int width; + int pos; + }; + + class Module: public AbsModule{ + public: + Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + virtual ~Module(); + enum {N_FPGA_REGS=40, N_TDC_REGS=21}; + void configureHW(); + void resetFE(); + void setupMaskStageHW(int stage){}; + void enableDataTakingHW(); + void switchToConfigModeHW(); + int setupParameterHW(const char* name, int val); //HW setup + int configureScan(boost::property_tree::ptree* scanOptions); + ModuleInfo getModuleInfo(); + const float dacToElectrons(int fe, int dac){return 0;} + void printRegisters(std::ostream &os); + unsigned writeRegisterHW(int i, unsigned short val); + void writeRegisterRawHW(int i, unsigned short val); + void writeHW(); + void writeTdcBitstreamHW(int i); + void setFieldFun(unsigned *reg, int bitpos, int width, unsigned val); + void setFpgaField(const char* name, unsigned val); + void setTdcField(const char* name, int index, unsigned val); + virtual void destroy(); + private: + FEI4::FECommands* m_commands; + static void addFpgaField(const char* name, int reg, int width, int pos); + static void addTdcField(const char* name, int width); + //static void addParameter(const char* name, const char* field); + static void initialize(); + unsigned m_fpga_registers[N_FPGA_REGS]; + unsigned m_tdc_registers[3][N_TDC_REGS]; + static std::map<std::string, FieldParams> m_fpga_fields; + static std::map<int, int> m_used_regs; + static std::map<std::string, FieldParams> m_tdc_fields; + //static std::map<std::string, int> m_parameters; + static bool m_initialized; + static int m_regpos; + static int m_bitpos; + +}; + +}; +#endif diff --git a/rce/rcecalib/config/afp-hptdc/ModuleGroup.cc b/rce/rcecalib/config/afp-hptdc/ModuleGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..ab57464a89a047f1898afd40aaabad98225a60cd --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/ModuleGroup.cc @@ -0,0 +1,86 @@ + +#include <boost/property_tree/ptree.hpp> +#include <stdio.h> +#include "rcecalib/config/afp-hptdc/Module.hh" +#include "rcecalib/config/afp-hptdc/ModuleGroup.hh" +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include "rcecalib/HW/SerialIF.hh" + +namespace afphptdc{ + +void ModuleGroup::addModule(Module* module){ + m_modules.push_back(module); + m_channelInMask|=1<<module->getInLink(); + m_channelOutMask=0; +} + +void ModuleGroup::deleteModules(){ + for (unsigned i=0; i<m_modules.size();i++){ + //cannot call delete directly because IPC modules need to call _destroy() instead. + m_modules[i]->destroy(); + } + m_modules.clear(); + m_channelInMask=0; + m_channelOutMask=0; +} + +int ModuleGroup::setupParameterHW(const char* name, int val, bool bcOK){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + retval+=m_modules[i]->setupParameterHW(name,val); + } + disableAllInChannels(); + return retval; +} + +int ModuleGroup::setupMaskStageHW(int stage){ + // no mask staging for the HPTDC chip. + return 0; +} + +void ModuleGroup::configureModulesHW(){ + //std::cout<<"Configure Modules HW"<<std::endl; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + std::cout<<"Setting channel in mask for inlink "<<m_modules[i]->getInLink()<<std::endl; + m_modules[i]->switchToConfigModeHW(); + m_modules[i]->configureHW(); + } + SerialIF::sendCommand(0x10); //phase calibration + disableAllInChannels(); +} + +void ModuleGroup::resetFE(){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->resetFE(); + } + disableAllInChannels(); +} + +void ModuleGroup::enableDataTakingHW(){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->enableDataTakingHW(); + } + disableAllInChannels(); +} + +int ModuleGroup::verifyModuleConfigHW(){ + return 0; // does not exist for HPTDC +} +void ModuleGroup::resetErrorCountersHW(){ + //does not exist for HPTDC +} + +int ModuleGroup::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + retval+=m_modules[i]->configureScan(scanOptions); + } + return retval; +} + +} diff --git a/rce/rcecalib/config/afp-hptdc/ModuleGroup.hh b/rce/rcecalib/config/afp-hptdc/ModuleGroup.hh new file mode 100644 index 0000000000000000000000000000000000000000..b9e0f8ec32ff88e05ccc8ac9c2db31d1d4926c01 --- /dev/null +++ b/rce/rcecalib/config/afp-hptdc/ModuleGroup.hh @@ -0,0 +1,33 @@ +#ifndef MODULEGROUPAFPHPTDC_HH +#define MODULEGROUPAFPHPTDC_HH +#include "rcecalib/config/AbsModuleGroup.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <vector> + +namespace afphptdc{ + + class Module; + +class ModuleGroup: public AbsModuleGroup{ +public: + ModuleGroup():AbsModuleGroup(){}; + virtual ~ModuleGroup(){} + void addModule(Module* module); + void deleteModules(); + int setupParameterHW(const char* name, int val, bool bcok); + int setupMaskStageHW(int stage); + void configureModulesHW(); + int verifyModuleConfigHW(); + void resetErrorCountersHW(); + int configureScan(boost::property_tree::ptree *scanOptions); + void resetFE(); + void enableDataTakingHW(); + unsigned getNmodules(){return m_modules.size();} +private: + void switchToConfigModeHW(); + std::vector<Module*> m_modules; + +}; +} + +#endif diff --git a/rce/rcecalib/config/constituents.mk b/rce/rcecalib/config/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..251fcbdac776bf80a5b3b3b36cf05d495222482a --- /dev/null +++ b/rce/rcecalib/config/constituents.mk @@ -0,0 +1,90 @@ + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := rceconfig +endif +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + modlibnames := rceconfig +endif +ifeq ($(profiler),y) +CPPFLAGS+='-D__PROFILER_ENABLED__' +endif + +libsrcs_rceconfig := AbsTrigger.cc \ + AbsModuleGroup.cc \ + ConfigIF.cc \ + EventFromFileTrigger.cc \ + TriggerReceiverIF.cc \ + MultiShotTrigger.cc \ + HitorTrigger.cc \ + IPCModuleFactory.cc \ + DummyFormatter.cc \ + Trigger.cc \ + MultiTrigger.cc \ + FEI3/MaskStageFactory.cc \ + FEI3/MaskStaging.cc \ + FEI3/RegularMaskStaging.cc \ + FEI3/CrosstalkMaskStaging.cc \ + FEI3/FECommands.cc \ + FEI3/Frontend.cc \ + FEI3/GlobalRegister.cc \ + FEI3/PixelRegister.cc \ + FEI3/Mcc.cc \ + FEI3/ModuleGroup.cc \ + FEI3/Module.cc \ + FEI3/JJFormatter.cc \ + FEI4/FECommands.cc \ + FEI4/PixelRegister.cc \ + FEI4/GlobalRegister.cc \ + FEI4/FEI4AGlobalRegister.cc \ + FEI4/FEI4BGlobalRegister.cc \ + FEI4/FEI4AFormatter.cc \ + FEI4/FEI4BFormatter.cc \ + FEI4/FEI4HitorFormatter.cc \ + FEI4/FEI4OccFormatter.cc \ + FEI4/MaskStageFactory.cc \ + FEI4/MaskStaging.cc \ + FEI4/AnalogMaskStaging.cc \ + FEI4/FastAnalogMaskStaging.cc \ + FEI4/AnalogSingleMaskStaging.cc \ + FEI4/AnalogColprMaskStaging.cc \ + FEI4/AnalogSimpleColprMaskStaging.cc \ + FEI4/AnalogColpr2MaskStagingFei4a.cc \ + FEI4/DigitalMaskStaging.cc \ + FEI4/DigStepMaskStaging.cc \ + FEI4/MaskStaging26880.cc \ + FEI4/AnalogMaskStaging.cc \ + FEI4/CrosstalkMaskStaging.cc \ + FEI4/CrosstalkFastMaskStaging.cc \ + FEI4/DiffusionMaskStaging.cc \ + FEI4/NoiseMaskStaging.cc \ + FEI4/ModuleCrosstalkMaskStaging.cc \ + FEI4/PatternMaskStaging.cc \ + FEI4/FEI4AModule.cc \ + FEI4/FEI4BModule.cc \ + FEI4/ModuleGroup.cc \ + FEI4/Module.cc \ + FEI4/TemperatureTrigger.cc \ + FEI4/MonleakTrigger.cc \ + FEI4/SNTrigger.cc \ + FEI4/Fei4RegisterTestTrigger.cc \ + hitbus/ModuleGroup.cc \ + hitbus/Module.cc \ + afp-hptdc/AFPHPTDCFormatter.cc \ + afp-hptdc/ModuleGroup.cc \ + afp-hptdc/Module.cc + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + libsrcs_rceconfig += MeasurementTrigger.cc +endif + + +libincs_rceconfig := rcecalib \ + $(ers_include_path) \ + $(owl_include_path) \ + $(ipc_include_path) \ + $(is_include_path) \ + $(oh_include_path) \ + $(boost_include_path) \ + $(omniorb_include_path) + + diff --git a/rce/rcecalib/config/hitbus/IPCModule.cc b/rce/rcecalib/config/hitbus/IPCModule.cc new file mode 100644 index 0000000000000000000000000000000000000000..73ee2562a1be84c5fe3bf8f426f9366e3e81017c --- /dev/null +++ b/rce/rcecalib/config/hitbus/IPCModule.cc @@ -0,0 +1,74 @@ +#ifndef HITBUS__IPCMODULE_CC +#define HITBUS__IPCMODULE_CC +#include "rcecalib/util/RceName.hh" +#include "rcecalib/config/hitbus/IPCModule.hh" +#include "ipc/partition.h" +#include "ers/ers.h" +#include <boost/lexical_cast.hpp> + +namespace Hitbus{ + +template <class TP> +IPCModule<TP>::IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt): + IPCNamedObject<POA_ipc::IPCHitbusAdapter, TP>( p, std::string(boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(RceName::getRceNumber())).c_str()) , + Module(name, id, inlink, outlink, fmt){ + // std::cout<<"IPCModule"<<std::endl; + try { + IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCModule<TP>::~IPCModule(){ + try { + IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCModule<TP>::IPCdownloadConfig(const ipc::HitbusModuleConfig &config){ + setRegister("bpm", config.bpm); + setRegister("delay_tam1", config.delay_tam1); + setRegister("delay_tam2", config.delay_tam2); + setRegister("delay_tam3", config.delay_tam3); + setRegister("delay_tbm1", config.delay_tbm1); + setRegister("delay_tbm2", config.delay_tbm2); + setRegister("delay_tbm3", config.delay_tbm3); + setRegister("bypass_delay", config.bypass_delay); + setRegister("clock", config.clock); + setRegister("function_A", config.function_A); + setRegister("function_B", config.function_B); + std::cout<<"Configure done"<<std::endl; + return 0; +} + +template <class TP> +void IPCModule<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +template <class TP> +void IPCModule<TP>::destroy(){ + this->_destroy(); +} + + + +}; + +#endif diff --git a/rce/rcecalib/config/hitbus/IPCModule.hh b/rce/rcecalib/config/hitbus/IPCModule.hh new file mode 100644 index 0000000000000000000000000000000000000000..f5819096910ddd5f146e92d618f4d9fff34ef9e8 --- /dev/null +++ b/rce/rcecalib/config/hitbus/IPCModule.hh @@ -0,0 +1,26 @@ +#ifndef IPCHITBUSMODULE_HH +#define IPCHITBUSMODULE_HH + +#include "rcecalib/config/hitbus/Module.hh" +#include "ipc/object.h" +#include "HitbusModuleConfig.hh" +#include "IPCHitbusAdapter.hh" + +class IPCPartition; +class AbsFormatter; + +namespace Hitbus{ +template <class TP = ipc::single_thread> +class IPCModule: public IPCNamedObject<POA_ipc::IPCHitbusAdapter,TP>, public Hitbus::Module { +public: + IPCModule(IPCPartition & p, const char * name, unsigned id, unsigned inlink, unsigned outlink, AbsFormatter* fmt); + ~IPCModule(); + CORBA::Long IPCdownloadConfig(const ipc::HitbusModuleConfig &config); + void shutdown(); + void destroy(); + +}; +}; + + +#endif diff --git a/rce/rcecalib/config/hitbus/Module.cc b/rce/rcecalib/config/hitbus/Module.cc new file mode 100644 index 0000000000000000000000000000000000000000..0f3f4d929d79d62cd2d3b3a1998c2217893b7e35 --- /dev/null +++ b/rce/rcecalib/config/hitbus/Module.cc @@ -0,0 +1,129 @@ +#include "rcecalib/HW/BitStream.hh" +#include "rcecalib/config/hitbus/Module.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/HW/SerialIF.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/util/exceptions.hh" +#include <iostream> +#include "ers/ers.h" +#include <stdio.h> + +namespace Hitbus{ + + Module::Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt) + :AbsModule(name, id,inLink, outLink, fmt){ + // std::cout<<"Module"<<std::endl; + if(!m_initialized)initialize(); + m_regw=new unsigned short[m_registers.size()]; + for(size_t i=0;i<m_registers.size();i++)m_regw[i]=0; + m_commands=new FEI4::FECommands; + } + Module::~Module(){ + delete [] m_regw; + delete m_commands; + } + void Module::writeHW(){ + for(size_t i=0;i<m_registers.size();i++){ + assert(writeRegisterHW(i, m_regw[i])==0); + } + } + unsigned Module::writeRegisterHW(int i, unsigned short val){ + // i is position in vector, not actual address + m_regw[i]=val; // set register content + int addr=m_registers[i].reg; + int rval=val&((1<<m_registers[i].width)-1); + writeRegisterRawHW(addr, rval); + return 0; + } + void Module::writeRegisterRawHW(int i, unsigned short val){ + BitStream *bs=new BitStream; + m_commands->writeGlobalRegister(bs, 47, (i<<8) | val); + SerialIF::send(bs, SerialIF::WAITFORDATA); //Write register + delete bs; + } + + void Module::configureHW(){ + std::cout<<"Configuring hitbus"<<std::endl; + printRegisters(std::cout); + resetFE(); + writeHW(); + } + + void Module::resetFE(){ + writeRegisterRawHW(0x94, 0xcd); //pulse clear + writeRegisterRawHW(1, 1); // core reset on + writeRegisterRawHW(1, 0); // core reset off + } + + // set a parameter (global or MCC) in the frontend + int Module::setupParameterHW(const char* name, int val){ + int retval=1; + if(m_parameters.find(name)!=m_parameters.end()){ + retval=0; + writeRegisterHW(m_parameters[name], val); + } + return retval; + } + + int Module::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + // do nothing for now + return retval; + } + void Module::destroy(){ + delete this; + } + ModuleInfo Module::getModuleInfo(){ + return ModuleInfo(m_name, m_id,m_inLink, m_outLink, N_FRONTENDS, N_ROWS, N_COLS, m_formatter); + } + + void Module::printRegisters(std::ostream &os){ + for(size_t i=0;i<m_registers.size();i++){ + os<<m_registers[i].name<<": Address="<<m_registers[i].reg<<" Value="<<m_regw[i]<<std::endl; + } + } + void Module::setRegister(const char* name, unsigned short val){ + int reg=findRegister(name); + if(reg!=-1)m_regw[reg]=val; + } + + //static functions + void Module::addParameter(const char* name, const char* field){ + int regnum=findRegister(field); + assert(regnum>-1); + m_parameters[name]=regnum; + } + int Module::findRegister(const char* name){ + for(size_t i=0;i<m_registers.size();i++){ + if(m_registers[i].name==name)return i; + } + return -1; + } + void Module::addRegister(const char* name, int reg, unsigned width){ + RegParams temp; + temp.reg=reg; + temp.width=width; + temp.name=name; + m_registers.push_back(temp); + } + std::vector<RegParams> Module::m_registers; + std::map<std::string, int> Module::m_parameters; + bool Module::m_initialized = false; + + void Module::initialize(){ + addRegister("bpm", 2, 1); + addRegister("delay_tam1", 5, 7); + addRegister("delay_tam2", 6, 7); + addRegister("delay_tam3", 7, 7); + addRegister("delay_tbm1", 8, 7); + addRegister("delay_tbm2", 9, 7); + addRegister("delay_tbm3", 10, 7); + addRegister("bypass_delay", 17, 1); + addRegister("clock", 21, 8); + addRegister("function_A", 18, 8); + addRegister("function_B", 19, 8); + + m_initialized=true; + } +}; + diff --git a/rce/rcecalib/config/hitbus/Module.hh b/rce/rcecalib/config/hitbus/Module.hh new file mode 100644 index 0000000000000000000000000000000000000000..f11e5e27ef5c1cdef629654515c1bfc21b045cc5 --- /dev/null +++ b/rce/rcecalib/config/hitbus/Module.hh @@ -0,0 +1,55 @@ +#ifndef HITBUS__MODULE_HH +#define HITBUS__MODULE_HH + +#include "rcecalib/config/AbsModule.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <map> +#include <string> + +class AbsFormatter; +namespace FEI4{ + class FECommands; +}; + +namespace Hitbus{ + + struct RegParams{ + int reg; + int width; + std::string name; + }; + + class Module: public AbsModule{ + public: + Module(const char* name, unsigned id, unsigned inLink, unsigned outLink, AbsFormatter* fmt); + virtual ~Module(); + enum {N_FRONTENDS=0, N_ROWS=0, N_COLS=0}; + void configureHW(); + void resetFE(); + void setupMaskStageHW(int stage){}; + void enableDataTakingHW(){}; + void setRegister(const char* name, unsigned short val); + int setupParameterHW(const char* name, int val); //HW setup + int configureScan(boost::property_tree::ptree* scanOptions); + ModuleInfo getModuleInfo(); + const float dacToElectrons(int fe, int dac){return 0;} + void printRegisters(std::ostream &os); + unsigned writeRegisterHW(int i, unsigned short val); + void writeRegisterRawHW(int i, unsigned short val); + void writeHW(); + virtual void destroy(); + private: + FEI4::FECommands* m_commands; + unsigned short *m_regw;// write registers + static void addRegister(const char* name, int reg, unsigned width); + static void addParameter(const char* name, const char* field); + static int findRegister(const char* name); + static void initialize(); + static std::vector<RegParams> m_registers; + static std::map<std::string, int> m_parameters; + static bool m_initialized; + +}; + +}; +#endif diff --git a/rce/rcecalib/config/hitbus/ModuleGroup.cc b/rce/rcecalib/config/hitbus/ModuleGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..3e888cb4eaf857ec7508ee45713518846658d35e --- /dev/null +++ b/rce/rcecalib/config/hitbus/ModuleGroup.cc @@ -0,0 +1,81 @@ + +#include <boost/property_tree/ptree.hpp> +#include <stdio.h> +#include "rcecalib/config/hitbus/Module.hh" +#include "rcecalib/config/hitbus/ModuleGroup.hh" +#include "rcecalib/util/exceptions.hh" +#include "ers/ers.h" +#include "rcecalib/HW/SerialIF.hh" + +namespace Hitbus{ + +void ModuleGroup::addModule(Module* module){ + m_modules.push_back(module); + m_channelInMask|=1<<module->getInLink(); + m_channelOutMask=0; +} + +void ModuleGroup::deleteModules(){ + for (unsigned i=0; i<m_modules.size();i++){ + //cannot call delete directly because IPC modules need to call _destroy() instead. + m_modules[i]->destroy(); + } + m_modules.clear(); + m_channelInMask=0; + m_channelOutMask=0; +} + +int ModuleGroup::setupParameterHW(const char* name, int val, bool bcOK){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + retval+=m_modules[i]->setupParameterHW(name,val); + } + disableAllInChannels(); + return retval; +} + +int ModuleGroup::setupMaskStageHW(int stage){ + // no mask staging for the hitbus chip. + return 0; +} + +void ModuleGroup::configureModulesHW(){ + //std::cout<<"Configure Modules HW"<<std::endl; + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + std::cout<<"Setting channel in mask for inlink "<<m_modules[i]->getInLink()<<std::endl; + m_modules[i]->configureHW(); + } + SerialIF::sendCommand(0x10); //phase calibration + disableAllInChannels(); +} + +void ModuleGroup::resetFE(){ + for (unsigned int i=0;i<m_modules.size();i++){ + SerialIF::setChannelInMask(1<<m_modules[i]->getInLink()); + m_modules[i]->resetFE(); + } + disableAllInChannels(); +} + +void ModuleGroup::enableDataTakingHW(){ + // do nothing +} + +int ModuleGroup::verifyModuleConfigHW(){ + return 0; // does not exist for Hitbus +} +void ModuleGroup::resetErrorCountersHW(){ + //does not exist for Hitbus +} + +int ModuleGroup::configureScan(boost::property_tree::ptree *scanOptions){ + int retval=0; + for (unsigned int i=0;i<m_modules.size();i++){ + retval+=m_modules[i]->configureScan(scanOptions); + } + return retval; +} + +} diff --git a/rce/rcecalib/config/hitbus/ModuleGroup.hh b/rce/rcecalib/config/hitbus/ModuleGroup.hh new file mode 100644 index 0000000000000000000000000000000000000000..2fc5158c7cd81a150ada34261de7bc75168d4e18 --- /dev/null +++ b/rce/rcecalib/config/hitbus/ModuleGroup.hh @@ -0,0 +1,33 @@ +#ifndef MODULEGROUPHITBUS_HH +#define MODULEGROUPHITBUS_HH +#include "rcecalib/config/AbsModuleGroup.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include <vector> + +namespace Hitbus{ + + class Module; + +class ModuleGroup: public AbsModuleGroup{ +public: + ModuleGroup():AbsModuleGroup(){}; + virtual ~ModuleGroup(){} + void addModule(Module* module); + void deleteModules(); + int setupParameterHW(const char* name, int val, bool bcok); + int setupMaskStageHW(int stage); + void configureModulesHW(); + int verifyModuleConfigHW(); + void resetErrorCountersHW(); + int configureScan(boost::property_tree::ptree *scanOptions); + void resetFE(); + void enableDataTakingHW(); + unsigned getNmodules(){return m_modules.size();} +private: + void switchToConfigModeHW(); + std::vector<Module*> m_modules; + +}; +} + +#endif diff --git a/rce/rcecalib/dataproc/AbsDataHandler.hh b/rce/rcecalib/dataproc/AbsDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..17a91ac46ba44ccb89f4f786c0cecc3fc5ac8348 --- /dev/null +++ b/rce/rcecalib/dataproc/AbsDataHandler.hh @@ -0,0 +1,23 @@ +#ifndef ABSDATAHANDLER_HH +#define ABSDATAHANDLER_HH + +#include <vector> +#include <assert.h> +#include "rcecalib/util/DataCond.hh" + +class AbsDataProc; +class ConfigIF; + +class AbsDataHandler{ +public: + AbsDataHandler(AbsDataProc* dataproc, DataCond& datacond, ConfigIF* cif) + :m_dataProc(dataproc), m_dataCond(datacond), m_configIF(cif){} + virtual ~AbsDataHandler(){}; + virtual void handle(unsigned link, unsigned* data, int size)=0; + virtual void timeoutOccurred(){} +protected: + AbsDataProc* m_dataProc; + DataCond& m_dataCond; + ConfigIF* m_configIF; +}; +#endif diff --git a/rce/rcecalib/dataproc/AbsDataProc.cc b/rce/rcecalib/dataproc/AbsDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..4240295d39ee05fde483475e577993e80e88f116 --- /dev/null +++ b/rce/rcecalib/dataproc/AbsDataProc.cc @@ -0,0 +1,47 @@ +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <stdio.h> +#include "ers/ers.h" + +AbsDataProc::AbsDataProc(ConfigIF* cif):m_configIF(cif){ + m_currentMaskStage=0; + m_currentBin=0; + m_info.clear(); + int maxlink=0; + m_nEvents=0; + for (unsigned int i=0;i<m_configIF->getNmodules();i++){ + m_info.push_back(m_configIF->getModuleInfo(i)); + if(m_info[i].getOutLink()>maxlink)maxlink=m_info[i].getOutLink(); + } + maxlink++; + m_linkToIndex=new int[maxlink]; + for (unsigned int i=0;i<m_configIF->getNmodules();i++){ + m_linkToIndex[m_info[i].getOutLink()]=i; + } + +} + +AbsDataProc::~AbsDataProc(){ + delete [] m_linkToIndex; +} +int AbsDataProc::changeBin(int i){ + m_currentBin=i; + ERS_DEBUG(2,"Change bin"); + return 0; +} + +int AbsDataProc::fit(std::string fitfunc){ + ERS_DEBUG(2,"fit"); + return 0; +} +int AbsDataProc::setMaskStage(int stage){ + m_currentMaskStage=stage; + ERS_DEBUG(2,"setMaskStage"); + return 0; +} + +int AbsDataProc::processData(unsigned link, unsigned* data, int size){ + ERS_DEBUG (2,"processing data"); + return 0; +} + diff --git a/rce/rcecalib/dataproc/AbsDataProc.hh b/rce/rcecalib/dataproc/AbsDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..4e3a77b801f33020f8901d030b52c1b196e47dc5 --- /dev/null +++ b/rce/rcecalib/dataproc/AbsDataProc.hh @@ -0,0 +1,30 @@ +#ifndef ABSDATAPROC_HH +#define ABSDATAPROC_HH + +#include <string> +#include <vector> +#include <map> +#include "rcecalib/config/ModuleInfo.hh" + +class ConfigIF; +class Scan; + +class AbsDataProc{ +public: + AbsDataProc(ConfigIF* cif); + virtual ~AbsDataProc(); + virtual int changeBin(int i); + virtual int setMaskStage(int stage); + virtual int processData(unsigned link, unsigned *data, int size); + virtual int fit(std::string fitfun); + virtual unsigned nEvents(){return m_nEvents;} +protected: + ConfigIF* m_configIF; + std::vector<ModuleInfo> m_info; + int *m_linkToIndex; + int m_currentMaskStage; + int m_currentBin; + unsigned m_nEvents; +}; + +#endif diff --git a/rce/rcecalib/dataproc/AbsReceiver.hh b/rce/rcecalib/dataproc/AbsReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..c5376712d82e2289c1c06fadd9e1bdb6e2ae29a1 --- /dev/null +++ b/rce/rcecalib/dataproc/AbsReceiver.hh @@ -0,0 +1,15 @@ +#ifndef ABSRECEIVER_HH +#define ABSRECEIVER_HH + +#include "rcecalib/dataproc/AbsDataHandler.hh" + +class AbsReceiver{ +public: + AbsReceiver(AbsDataHandler* handler):m_handler(handler){} + virtual ~AbsReceiver(){} + virtual void resynch(){} +protected: + AbsDataHandler* m_handler; + +}; +#endif diff --git a/rce/rcecalib/dataproc/BcidDataProc.cc b/rce/rcecalib/dataproc/BcidDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..405005f5883bc716b18527e6017eb8feed4b8c78 --- /dev/null +++ b/rce/rcecalib/dataproc/BcidDataProc.cc @@ -0,0 +1,155 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/BcidDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/fit/FitFactory.cc" +#include "rcecalib/dataproc/fit/CalculateMeanSigma.cc" + + +int BcidDataProc::fit(std::string fitfun) { + std::cout << "Running: " << fitfun << std::endl; + if(fitfun=="CALCULATE_MEAN_SIGMA" && m_nPoints!=0) { + calculateMeanSigma(m_histo_occ, m_histo_bcid, m_histo_bcid2, m_histo_bcid_mean, m_histo_bcid_sigma); + } + return 0; +} + +int BcidDataProc::processData(unsigned link, unsigned *data, int size){ + // std::cout<<"Process data"<<std::endl; + for (int i=0;i<size;i++){ + int module=m_linkToIndex[link]; // will be different when parser is fully there + FormattedRecord current(data[i]); + if (current.isHeader()){ + l1id = current.getL1id(); + bcid = current.getBxid(); + //printf("bcid : %x \n", bcid); + //printf("l1id : %x \n", l1id); + if (l1id != l1id_last) + { + l1id_last = l1id; + bcid_ref = bcid; + } + bcid = bcid-bcid_ref; + // printf("bcidafter : %x \n", bcid); + } + if (current.isData()){ + unsigned int chip=current.getFE(); + //unsigned int tot=current.getToT(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + //printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + m_histo_occ[module][m_currentBin]->increment(chip*m_info[module].getNColumns()+col,row); + m_histo_bcid[module][m_currentBin]->fill(chip*m_info[module].getNColumns()+col,row,(unsigned int)bcid); + m_histo_bcid2[module][m_currentBin]->fill(chip*m_info[module].getNColumns()+col,row,(unsigned int)bcid*bcid); + //printf("bcidafter : %x \n", bcid); + } + } + return 0; +} + +BcidDataProc::BcidDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + bcid_ref = 0; + l1id_last = 0; + bcid = 0; + l1id = 0; + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<short, short>* > vh; + std::vector<RceHisto2d<char, char>* > vhc; + m_histo_occ.push_back(vhc); + m_histo_bcid.push_back(vh); + m_histo_bcid2.push_back(vh); + m_histo_bcid_sigma.push_back(vh); + m_histo_bcid_mean.push_back(vh); + char name[128]; + char title[128]; + RceHisto2d<short, short> *histo; + RceHisto2d<char, char> *histoc; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Occupancy_Point_%03d", moduleId,point); + histoc=new RceHisto2d<char, char>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histoc->setAxisTitle(0,"Column"); + else histoc->setAxisTitle(0,"FE*N_COL+Column"); + histoc->setAxisTitle(1, "Row"); + m_histo_occ[module].push_back(histoc); + sprintf(title,"BCID Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_BCID_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_bcid[module].push_back(histo); + + sprintf(title,"BCID2 Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_BCID2_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_bcid2[module].push_back(histo); + + sprintf(title,"BCID_MEAN Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_BCIDmean_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_bcid_mean[module].push_back(histo); + + sprintf(title,"BCID_SIGMA Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_BCIDsigma_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_bcid_sigma[module].push_back(histo); + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +BcidDataProc::~BcidDataProc(){ + for (size_t module=0;module<m_histo_bcid.size();module++) + for(size_t i=0;i<m_histo_bcid[module].size();i++)delete m_histo_bcid[module][i]; + for (size_t module=0;module<m_histo_bcid2.size();module++) + for(size_t i=0;i<m_histo_bcid2[module].size();i++)delete m_histo_bcid2[module][i]; + for (size_t module=0;module<m_histo_bcid_sigma.size();module++) + for(size_t i=0;i<m_histo_bcid_sigma[module].size();i++)delete m_histo_bcid_sigma[module][i]; + for (size_t module=0;module<m_histo_bcid_mean.size();module++) + for(size_t i=0;i<m_histo_bcid_mean[module].size();i++)delete m_histo_bcid_mean[module][i]; + for (size_t module=0;module<m_histo_occ.size();module++) + for(size_t i=0;i<m_histo_occ[module].size();i++)delete m_histo_occ[module][i]; + +} + + diff --git a/rce/rcecalib/dataproc/BcidDataProc.hh b/rce/rcecalib/dataproc/BcidDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..d0ab3c7b3244b7a02fb2aead6ba4a42ca3b1bab0 --- /dev/null +++ b/rce/rcecalib/dataproc/BcidDataProc.hh @@ -0,0 +1,33 @@ +#ifndef BCIDDATAPROC_HH +#define BCIDDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" + +class BcidDataProc: public AbsDataProc{ +public: + BcidDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~BcidDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_bcid; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_bcid2; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_bcid_sigma; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_bcid_mean; + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ; + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + unsigned int bcid_ref; + unsigned int l1id_last; + unsigned int bcid; + unsigned int l1id; +}; + +#endif diff --git a/rce/rcecalib/dataproc/Channeldefs.hh b/rce/rcecalib/dataproc/Channeldefs.hh new file mode 100644 index 0000000000000000000000000000000000000000..bf2fad0c1bf6cc33b2ef8f58e31a5df679b3b726 --- /dev/null +++ b/rce/rcecalib/dataproc/Channeldefs.hh @@ -0,0 +1,7 @@ +#ifndef CHANNELDEFS_HH +#define CHANNELDEFS_HH + +enum channeldefs {ADCREADOUT=29, TDCREADOUT=30, PGPACK=31}; +enum shiftdefs {MARKERPOS=7, RCEPOS=8, LINKMASK=0x7f, RCEMASK=0xff}; + +#endif diff --git a/rce/rcecalib/dataproc/ClusterProc.cc b/rce/rcecalib/dataproc/ClusterProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..16a9d7cf5773464c1c959e3b469a28a13ea8e3ee --- /dev/null +++ b/rce/rcecalib/dataproc/ClusterProc.cc @@ -0,0 +1,154 @@ +#include "rcecalib/dataproc/ClusterProc.hh" +#include <stdio.h> + +ClusterProc::ClusterProc() { + cluster_id = 0; + // Safety cuts + max_hits_in_cluster = 20; + max_hits = 3000; + // Cluster cuts + bcidCut = 3; + colCut = 1; + rowCut = 1; +} + +ClusterProc::ClusterProc(RceHisto1d<int, int> *histo_hits, RceHisto1d<int, int> *histo_tot, RceHisto2d<int, int> *histo_tot_size) { + cluster_id = 0; + // Safety cuts + max_hits_in_cluster = 20; + max_hits = 3000; + // Cluster cuts + bcidCut = 3; + colCut = 1; + rowCut = 1; + m_histo_hits = histo_hits; + m_histo_tot = histo_tot; + m_histo_tot_size = histo_tot_size; +} + +ClusterProc::~ClusterProc() { + colVec.clear(); + rowVec.clear(); + totVec.clear(); + bcidVec.clear(); + + tot_in_cluster.clear(); + hits_in_cluster.clear(); + cluster_with_overflow.clear(); +} + +void ClusterProc::assignHitHisto(RceHisto1d<int, int> *histo_hits) { + m_histo_hits = histo_hits; +} + +void ClusterProc::assignToTHisto(RceHisto1d<int, int> *histo_tot) { + m_histo_tot = histo_tot; +} + +void ClusterProc::assignToTClusterSizeHisto(RceHisto2d<int, int> *histo_tot_size) { + m_histo_tot_size = histo_tot_size; +} + +void ClusterProc::addHit(unsigned int col, unsigned int row, unsigned int tot, unsigned int bcid) { + colVec.push_back(col); + rowVec.push_back(row); + totVec.push_back(tot); + bcidVec.push_back(bcid); +} + +void ClusterProc::iterativeSeek(unsigned int this_cluster) { + // not yet implemented +} + +void ClusterProc::recursiveSeek(unsigned int this_cluster, unsigned int col, unsigned int row, unsigned int bcid) { + for(unsigned int i=0; i<colVec.size(); i++) { + // Safety if for too big clusters + if (hits_in_cluster[this_cluster] > max_hits_in_cluster) return; + + // Check if hit is in the cluster range and in time + if ((abs((int)(colVec[i]-col)) <= colCut) && + (abs((int)(rowVec[i]-row)) <= rowCut) && + (abs((int)(bcidVec[i]-bcid)) <= bcidCut)) { + // Add it + unsigned int new_col = colVec[i]; + unsigned int new_row = rowVec[i]; + unsigned int new_bcid = bcidVec[i]; + hits_in_cluster[this_cluster]++; + tot_in_cluster[this_cluster] += totVec[i]; + if (totVec[i]>13) cluster_with_overflow[this_cluster] = true; + + // Erase hit + colVec.erase(colVec.begin()+i); + rowVec.erase(rowVec.begin()+i); + totVec.erase(totVec.begin()+i); + bcidVec.erase(bcidVec.begin()+i); + + // Search from here (questionable which bcid to pick) + this->recursiveSeek(this_cluster, new_col, new_row, new_bcid); + } + } +} + +void ClusterProc::clusterize() { + unsigned int safety_cnt = 0; + while((!colVec.empty()) && (safety_cnt < max_hits)) { + // New cluster + unsigned int this_cluster = cluster_id; + hits_in_cluster.push_back(0); + tot_in_cluster.push_back(0); + cluster_with_overflow.push_back(false); + + // Insert first hit + unsigned int col = colVec[0]; + unsigned int row = rowVec[0]; + unsigned int bcid = bcidVec[0]; + hits_in_cluster[this_cluster]++; + tot_in_cluster[this_cluster] += totVec[0]; + + // Dismiss clusters with overflow ToT + if(totVec[0] > 13) cluster_with_overflow[this_cluster] = true; + + // Erase hit + colVec.erase(colVec.begin()); + rowVec.erase(rowVec.begin()); + totVec.erase(totVec.begin()); + bcidVec.erase(bcidVec.begin()); + + // Search for more hits + this->recursiveSeek(this_cluster, col, row, bcid); + //printf("New cluster with #%d hits and %d total ToT\n", hits_in_cluster[this_cluster], tot_in_cluster[this_cluster]); + // Next cluster + cluster_id++; + safety_cnt++; + } + // Fill the histograms + this->fillHistos(); + + // Reset all vectors for the next event + this->reset(); +} + +void ClusterProc::fillHistos() { + if (m_histo_hits != NULL && m_histo_tot != NULL) { + for (unsigned int i=0; i<hits_in_cluster.size(); i++) { + if (!cluster_with_overflow[i]) { + if (m_histo_hits) m_histo_hits->increment(hits_in_cluster[i]); + if (m_histo_tot) m_histo_tot->increment(tot_in_cluster[i]); + if (m_histo_tot_size) m_histo_tot_size->increment(tot_in_cluster[i], hits_in_cluster[i]); + } + } + } +} + +void ClusterProc::reset() { + cluster_id = 0; + + colVec.clear(); + rowVec.clear(); + totVec.clear(); + + tot_in_cluster.clear(); + hits_in_cluster.clear(); + cluster_with_overflow.clear(); +} + diff --git a/rce/rcecalib/dataproc/ClusterProc.hh b/rce/rcecalib/dataproc/ClusterProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..d5e91e55904c8f8544e24a4b4013054a1ea1f33f --- /dev/null +++ b/rce/rcecalib/dataproc/ClusterProc.hh @@ -0,0 +1,61 @@ +#ifndef CLUSTERPROC_HH +#define CLUSTERPROC_HH + +#include <stdio.h> +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceMath.hh" + +class ClusterProc { +public: + ClusterProc(); + ClusterProc(RceHisto1d<int, int> *histo_hits, RceHisto1d<int, int> *histo_tot, RceHisto2d<int, int> *histo_tot_size); + ~ClusterProc(); + + void assignHitHisto(RceHisto1d<int, int> *histo_hits); + void assignToTHisto(RceHisto1d<int, int> *histo_tot); + void assignToTClusterSizeHisto(RceHisto2d<int, int> *histo_tot_size); + + void addHit(unsigned int col, unsigned int row, unsigned int tot, unsigned int bcid); + + void clusterize(); + void recursiveSeek(unsigned int this_cluster, unsigned int col, unsigned int row, unsigned int bcid); + void iterativeSeek(unsigned int this_cluster); + + void reset(); + void fillHistos(); +private: + // Histograms + RceHisto1d<int, int> *m_histo_hits; + RceHisto1d<int, int> *m_histo_tot; + RceHisto2d<int, int> *m_histo_tot_size; + RceHisto1d<int, int> *m_histo_col_rms; + RceHisto1d<int, int> *m_histo_row_rms; + RceHisto2d<int, int> *m_histo_col_row_rms; + + // Cluster counter + unsigned int cluster_id; + + // To prevent calling the function too often + unsigned int max_hits_in_cluster; + unsigned int max_hits; + + // Cluster cuts + int bcidCut; + int colCut; + int rowCut; + + // Raw data + std::vector<unsigned int> colVec; + std::vector<unsigned int> rowVec; + std::vector<unsigned int> totVec; + std::vector<unsigned int> bcidVec; + + // Clustered data + std::vector<unsigned int> tot_in_cluster; + std::vector<unsigned int> hits_in_cluster; + std::vector<bool> cluster_with_overflow; +}; + +#endif diff --git a/rce/rcecalib/dataproc/CosmicDataHandler.cc b/rce/rcecalib/dataproc/CosmicDataHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..6fd7af5873bee1a248b68381701ec195e20cd400 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicDataHandler.cc @@ -0,0 +1,59 @@ +#include "rcecalib/dataproc/CosmicDataHandler.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/config/DummyFormatter.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/util/DataCond.hh" +#include <boost/property_tree/ptree.hpp> +#include <iostream> + +CosmicDataHandler::CosmicDataHandler(AbsDataProc* dataproc, + DataCond& datacond, + ConfigIF* cif, + boost::property_tree::ptree* scanOptions) + :AbsDataHandler(dataproc, datacond, cif){ + std::cout<<"Cosmic data handler"<<std::endl; + m_nModules=m_configIF->getNmodules(); + for (int i=0;i<m_nModules;i++){ + m_formatter.push_back(m_configIF->getModuleInfo(i).getFormatter()); + } + m_dummy=new DummyFormatter(0); + m_formatter.push_back(m_dummy); + m_linkToIndex=new int[MAXMODULES]; + for(int i=0;i<MAXMODULES;i++)m_linkToIndex[i]=m_nModules; //point to dummy formatter + //now configure existing module formatters + for (int i=0;i<m_nModules;i++){ + m_linkToIndex[m_configIF->getModuleInfo(i).getOutLink()]=i; + } + m_parsedData=new unsigned[16384]; +} + +CosmicDataHandler::~CosmicDataHandler(){ + delete [] m_parsedData; + delete [] m_linkToIndex; + delete m_dummy; +} + +void CosmicDataHandler::handle(unsigned desc, unsigned *data, int size){ + // nL1A contains the number of L1A in the data chunk + unsigned link=desc&0xf; + int parsedsize=0; + //std::cout<<"Data for link "<<link<<std::endl; + unsigned *thedata; + if((link)==10){ + thedata=data; + parsedsize=size; + } else { + thedata=m_parsedData; + int nL1A=0; + int retval=m_formatter[m_linkToIndex[link]]->decode(data,size,m_parsedData, parsedsize, nL1A); + //std::cout<<"parser"<<retval<<" "<<size<<std::endl; + if(retval!=0){ + std::cout<<"Parser error for link "<<link<<": Data size "<<size<<" number of triggers "<<nL1A<<std::endl; + for (int i=0;i<(size<100?size:100);i++)std::cout<<std::hex<<data[i]<<std::endl; + } + } + if(parsedsize>0){ + m_dataProc->processData(desc, thedata, parsedsize); + } +} diff --git a/rce/rcecalib/dataproc/CosmicDataHandler.hh b/rce/rcecalib/dataproc/CosmicDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..aa3a62f43b7b99a0a376d654dd240811af1a2bdd --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicDataHandler.hh @@ -0,0 +1,27 @@ +#ifndef COSMICDATAHANDLER_HH +#define COSMICDATAHANDLER_HH + +#include <vector> +#include <map> +#include <assert.h> + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include <boost/property_tree/ptree_fwd.hpp> + +class AbsFormatter; +class DataCond; + +class CosmicDataHandler: public AbsDataHandler{ +public: + CosmicDataHandler(AbsDataProc* dataproc, DataCond &datacond, ConfigIF* cif, boost::property_tree::ptree* scanOptions); + virtual ~CosmicDataHandler(); + void handle(unsigned desc, unsigned* data, int size); + enum MD{MAXMODULES=16}; +protected: + int m_nModules; + int *m_linkToIndex; + unsigned *m_parsedData; + std::vector<AbsFormatter*> m_formatter; + AbsFormatter * m_dummy; +}; +#endif diff --git a/rce/rcecalib/dataproc/CosmicDataProc.cc b/rce/rcecalib/dataproc/CosmicDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..9eb784853a61c5cfb716602b1ff1360f5380339a --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicDataProc.cc @@ -0,0 +1,264 @@ +#include <boost/property_tree/ptree.hpp> +#include <boost/regex.hpp> +#include <boost/algorithm/string.hpp> +#include "rcecalib/dataproc/CosmicDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/DataProcFactory.hh" +#include "rcecalib/dataproc/CosmicEvent.hh" +#include "rcecalib/dataproc/CosmicEventIterator.hh" +#include "eudaq/Event.hh" +#include "eudaq/DataSender.hh" +#include "eudaq/DataSenderIF.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/counted_ptr.hh" +#include <iomanip> +#include <iostream> +#include <stdlib.h> + + +int CosmicDataProc::fit(std::string command){ + if(command=="CloseFile"){ + std::cout<<"Number of fragments processed: "<<m_nfrag<<std::endl; + if(m_file!=0){ + sleep(1); // wait for any left over data to trickle in + eudaq::DetectorEvent dev(m_runNo,m_nEvents,0); + dev.SetFlags(eudaq::Event::FLAG_EORE); + eudaq::RawDataEvent *revc=new eudaq::RawDataEvent(eudaq::RawDataEvent::EORE("CTEL",m_runNo,m_nEvents)); + counted_ptr<eudaq::Event> cpc(revc); + dev.AddEvent(cpc); + eudaq::RawDataEvent *revd=new eudaq::RawDataEvent(eudaq::RawDataEvent::EORE("APIX-CT",m_runNo,m_nEvents)); + counted_ptr<eudaq::Event> cpd(revd); + dev.AddEvent(cpd); + dev.Serialize(*m_file); + delete m_file; + m_file=0; + } + // m_file.close(); + std::cout<<"close file called"<<std::endl; + } + return 0; +} + +int CosmicDataProc::processData(unsigned rlink, unsigned *data, int size){ + m_nfrag++; + if((m_nfrag&0xffff)==0)usleep(1); //give external commands a chance to execute from time to time + int link=rlink&0xf; + bool marker=((rlink&0x10)==0x10); + m_hits=0; + // std::cout<<"DataProc Link "<<link<<" size "<<size<<std::endl; + // if synching throw away fragments until we find the marker + if(m_linksynch[link]==true) { + if (marker==false){ + if(m_print>0){ + if(link==10)std::cout<<"Ignoring Link 10 L1A: "<<(data[1]>>24)<<std::endl; + else { + FormattedRecord fr(data[0]); + std::cout<<"Ignoring Link "<<link<<" L1A: "<<fr.getL1id()<<" bxid: "<<fr.getBxid()<<std::endl; + } + m_print--; + } + m_tossed[link]++; + return 0; + } + m_linksynch[link]=false; + //if(marker)std::cout<<"Markerevent"<<std::endl; + std::cout<<"Tossed "<<m_tossed[link]<<" fragments for link "<<link<<std::endl; + } + if (link==10){ + // unsigned trgtime1=data[3]; + // unsigned trgtime2=data[4]; + // unsigned long long trgtime=trgtime1; + // trgtime=(trgtime<<32) | trgtime2; + + // std::cout<<"Trigger time: "<<std::hex<<trgtime<<std::dec<<std::endl; + // std::cout<<"Link 10 L1id "<<((data[0]>>24)&0xf)<<std::endl; + //This doesn't work with multiple RCE's yet--BL + bool success=m_iterator->setTdcData(data,0); + if(success==false){ + resynch(); + return 0; + } + }else{ + int module=m_linkToIndex[link]; //map link onto module index + unsigned int l1id=99; + int ntrg=0; + int bxfirst=-666; + int bxlast=-555; + int start=0; + do{ //possibly we must split the data because it belongs to 2 triggers. + //if(start!=0)std::cout<<"Newstart "<<start<<std::endl; + int newstart=processModuleData(&data[start],size-start,link, l1id,bxfirst,bxlast,ntrg); + //if(m_hits>0) std::cout<<"Link "<<link<<" had "<<m_hits<<" hits."<<std::endl; + // std::cout<<"Data from module "<<module<<" link="<<link<<" with l1id="<<l1id<<" ntrg="<<ntrg<<std::endl; + bool isdut=((link<9) || (m_file==0)); //all data is DUT when running as a producer (m_file==0) + + //This doesn't work with multiple RCE's yet--BL + bool success=m_iterator->addPixelData(module,l1id, bxfirst, bxlast, ntrg, 0, isdut,&data[start],newstart); + if(success==false){ + resynch(); + return 0; + } + start+=newstart; + }while(start<size); + } + return 0; +} + +int CosmicDataProc::processModuleData(unsigned* udata,int size, int link, unsigned& l1id, int& bxfirst, int &bxlast, int &ntrg){ + FormattedRecord* data=(FormattedRecord*)udata; + if(!data[0].isHeader()){ + std::cout<<"Module data not starting with 0x2xxxxxxx"<<std::endl; + return -1; + } + //int bx; + ntrg=1; + data[0].setLink(link); + bxfirst=data[0].getBxid()&0xff; + bxlast=bxfirst; + l1id=data[0].getL1id()&0xf; + //std::cout<<"Link "<<link<<" l1a "<<l1id<<" bx "<<bx<<std::endl; + unsigned l1a; + for (int i=1;i<size;i++){ + if (data[i].isHeader()){ + data[i].setLink(link); + l1a=data[i].getL1id()&0xf; + bxlast=data[i].getBxid(); + //std::cout<<"Link "<<link<<" l1a "<<l1a<<" bx "<<bx<<std::endl; + if(l1id!=l1a)return i; + ntrg++; + } + //}else if(data[i]&0x80000000){ + // //m_hits++; + // int chip=(data[i]>>24)&0xf; + // int tot=(data[i]>>16)&0xff; + // int col=(data[i]>>8)&0x1f; + // int row=data[i]&0xff; + // int tr=bx-bxfirst; + // if (tr<0)tr+=256; + //if(row<156 && tot > 6) + // std::cout<<"Link "<<link<<" Trigger "<<tr<<" Chip "<<chip<<" row "<<row<<" col "<<col<<" tot "<<tot<<std::endl; + // } + } + return size; +} + + +void CosmicDataProc::resynch(){ + std::cout<<"Resynchronizing"<<std::endl; + int serstat; + serstat=m_configIF->sendHWcommand(4);//pause run + assert(serstat==0); + // set synch flags for everybody + for (int i=0;i<16;i++)m_linksynch[i]=true; + for (int i=0;i<16;i++)m_tossed[i]=0; + m_print=0; + m_configIF->resetCountersHW();//send ECR and BCR + m_iterator->resynch(); + serstat=m_configIF->sendHWcommand(7);//resume run and post marker + assert(serstat==0); +} + +CosmicDataProc::CosmicDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + std::cout<<"Start CosmicDataProc Constructor"<<std::endl; + try{ //catch bad scan option parameters + m_nModules=m_configIF->getNmodules(); + + for (int i=0;i<16;i++)m_linksynch[i]=false; + m_nfrag=0; + m_print=0; + m_nL1AperEv=scanOptions->get<int>("trigOpt.nL1AperEvent"); + std::string name=scanOptions->get<std::string>("Name"); + std::cout<<"CosmicDataProc name "<<name<<std::endl; + m_runNo=0; + + std::string prefix("CosmicGui"); + if (name.compare(0, prefix.size(), prefix) == 0) + { + // CosmicGui asks to send back over TCP + // parse string of form: CosmicGui|01168|tcp://127.56.2.6:4500 + std::vector<std::string> strs; + boost::split(strs, name, boost::is_any_of("|")); + m_runNo=atoi(strs[1].c_str()); + name = strs[2]; + + std::cout<<"TCP to " << name << " instead of file"<<std::endl; + m_file = 0; + eudaq::DataSender * ds = new eudaq::DataSender(std::string("DataSender"), std::string("CosmicGuiDataSender")); + DataSenderIF::setDataSender(ds); + try + { + ds->Connect(name); + } + catch (const std::exception & ex) + { + // Need to do sensible things here, maybe catch different types of exceptions. + std::cout << "DataSender could not connect. Exception says: \n " << ex.what() << std::endl; + } + + } + else + { + boost::cmatch matches; + boost::regex re("(\\d+)"); + if(boost::regex_search(name.c_str(), matches, re)){ + if(matches.size()>1){ + std::string match(matches[1].first, matches[1].second); + m_runNo=strtoul(match.c_str(),0,10); + } + } + + boost::regex r1("TCP"); + if(boost::regex_search(name,r1)==0) + { + // Write file to NFS + std::string path="/nfs/cosmicData/"; + std::string fullpath=path+name+".raw"; + // m_file.open(fullpath.c_str()); + m_file=new eudaq::FileSerializer(fullpath.c_str()); + eudaq::DetectorEvent dev(m_runNo,0,0); + dev.SetFlags(eudaq::Event::FLAG_BORE); + dev.SetTag("CONFIG", "Name = Test"); + eudaq::RawDataEvent *revc=new eudaq::RawDataEvent(eudaq::RawDataEvent::BORE("CTEL",m_runNo)); + counted_ptr<eudaq::Event> cpc(revc); + dev.AddEvent(cpc); + eudaq::RawDataEvent *revd=new eudaq::RawDataEvent(eudaq::RawDataEvent::BORE("APIX-CT",m_runNo)); + counted_ptr<eudaq::Event> cpd(revd); + dev.AddEvent(cpd); + dev.Serialize(*m_file); + } + else + { + // Don't write to file. Send events to Eudaq instead. + m_file=0; + } + + + } + std::cout<<"Run number "<<m_runNo<<std::endl; + + // create the event iterator class which does all the work + //This doesn't work with multiple RCE's yet--BL + std::vector<int> rces; + rces.push_back(0); + m_iterator=new CosmicEventIterator(false, m_file, 0, m_runNo,m_nModules,rces); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +CosmicDataProc::~CosmicDataProc(){ + + delete m_file; + delete m_iterator; +} + +unsigned CosmicDataProc::nEvents(){ + return m_iterator->nEvents(); +} diff --git a/rce/rcecalib/dataproc/CosmicDataProc.hh b/rce/rcecalib/dataproc/CosmicDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..c08841846543df28a5bf3a652eb94055c82aa6a6 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicDataProc.hh @@ -0,0 +1,39 @@ +#ifndef COSMICDATAPROC_HH +#define COSMICDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/eudaq/FileSerializer.hh" +#include <list> +#include <fstream> +#include <fstream> + +class CosmicEvent; +class CosmicEventIterator; + +class CosmicDataProc: public AbsDataProc{ +public: + CosmicDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~CosmicDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string); + unsigned nEvents(); +protected: + void resynch(); + inline int processModuleData(unsigned* data,int size, int link, unsigned& l1id, int& bxfirst, int& bxlast, int &ntrg); + + int m_nL1AperEv; + int m_nModules; + bool m_linksynch[16]; + int m_tossed[16]; + unsigned m_runNo; + eudaq::FileSerializer *m_file; + //std::ofstream m_file; + int m_nfrag; + CosmicEventIterator* m_iterator; + int m_print; + int m_hits; + +}; + +#endif diff --git a/rce/rcecalib/dataproc/CosmicEvent.cc b/rce/rcecalib/dataproc/CosmicEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..58b3c1fe5dc9ac1990e974324a25cb85065e551d --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicEvent.cc @@ -0,0 +1,302 @@ +#include "rcecalib/dataproc/CosmicEvent.hh" +#include "rcecalib/eudaq/FileSerializer.hh" +#include "rcecalib/eudaq/Event.hh" +#include "rcecalib/eudaq/RawDataEvent.hh" +#include "rcecalib/eudaq/DetectorEvent.hh" +#include "rcecalib/eudaq/ProducerIF.hh" +#include "rcecalib/eudaq/DataSenderIF.hh" +#include "rcecalib/dataproc/CosmicEventReceiver.hh" + +bool CosmicEvent::m_synch=false; +int CosmicEvent::m_lastTLU=0; + +CosmicEvent::CosmicEvent(unsigned runno, unsigned l1a, unsigned nMod, std::vector<int>& rces): + m_tdctrig(false), m_l1a(l1a), m_nMod(nMod), + m_runno(runno), m_rces(rces){ + + for (unsigned int i=0;i<nMod;i++){ + m_ntrig.push_back(0); + m_bx.push_back(999); + m_bxlast.push_back(999); + m_modRceIndex.push_back(9999); + } + + m_nRce = m_rces.size(); + for(unsigned int i=0; i<m_nRce; i++){ + m_timestamp.push_back(0); + m_tdcbx.push_back(999); + } + + m_ctel=new eudaq::RawDataEvent("CTEL",m_runno,0); + m_ctel->AddBlock(0); + m_dut=new eudaq::RawDataEvent("APIX-CT",m_runno,0); + m_dut->AddBlock(0); + + for(unsigned int iRce=0; iRce<m_nRce; iRce++){ + m_dut->AddBlock(iRce+1); + unsigned rceNum = m_rces[iRce]; + rceNum |= 0x40000000; //HeaderTwo format + m_dut->AppendBlock(iRce+1,(char*)&rceNum,sizeof(unsigned)); + } + +} + +CosmicEvent::~CosmicEvent(){ + delete m_dut; + delete m_ctel; +} +void CosmicEvent::setTdcData(unsigned firstword, unsigned* data, unsigned rceIndex){ + m_tdctrig=true; + + unsigned rceNum = m_rces[rceIndex]; + + //std::cout<<"Appending TDC data: "<<std::endl; + //std::cout<<std::hex<<rceNum<<std::dec<<std::endl; + //std::cout<<std::hex<<firstword<<std::dec<<std::endl; + //for(unsigned int i=0; i<8; i++){ + // std::cout<<std::hex<<data[i]<<std::dec<<" "<<std::endl; + //} + + m_dut->AppendBlock(0,(char*)&rceNum,sizeof(unsigned)); + m_dut->AppendBlock(0,(char*)&firstword,sizeof(unsigned)); + m_dut->AppendBlock(0,(char*)data,8*sizeof(unsigned)); + + //timestamp is a 32 bit number giving the time of arrival of the trigger, in + //units of clock ticks (25 ns) + m_timestamp[rceIndex]=data[3]; + m_timestamp[rceIndex]<<=32; + m_timestamp[rceIndex] |= data[4]; + m_tdcbx[rceIndex] = data[4]&0xff; +} + +void CosmicEvent::appendCtelData(unsigned* data, unsigned size){ + m_ctel->AppendBlock(0,(char*)data,size*sizeof(unsigned)); +} + +void CosmicEvent::appendDutData(unsigned* data, unsigned size, unsigned rceIndex){ + + //unsigned rceNum = m_rces[rceIndex]; + //std::cout<<"Appending dut data for rce "<<rceNum<<" :"<<std::endl; + //for(unsigned int i=0; i<size; i++){ + // std::cout<<std::hex<<data[i]<<std::dec<<" "<<std::endl; + //} + + m_dut->AppendBlock(rceIndex+1,(char*)data,size*sizeof(unsigned)); +} + +void CosmicEvent::incrementTrigger(unsigned mod, int ntrgin, unsigned bxfirst, unsigned bxlast, unsigned rceIndex){ + if(m_modRceIndex[mod]>m_nRce){ + m_modRceIndex[mod]=rceIndex; + } + if(m_ntrig[mod]==0)m_bx[mod]=bxfirst; + m_bxlast[mod]=bxlast; + m_ntrig[mod]+=ntrgin; +} + +bool CosmicEvent::consistent(CosmicEvent* ref){ + for (unsigned i=0;i<m_nMod;i++){ + // Check that all modules have the correct number of triggers + if(m_ntrig[i]!=ref->m_ntrig[i]){ + std::cout<<"Module "<<i<<" has "<<m_ntrig[i]<<" triggers instead of "<<ref->m_ntrig[i]<<std::endl; + return false; + } + //Check that first and last bxid are consistent with the number of triggers. + int diffbx=(m_bxlast[i]+1-m_bx[i])%256; + if(diffbx!=m_ntrig[i]){ + std::cout<<"Bad Module "<<i<<" firstbx "<<m_bx[i]<<" lastbx "<<m_bxlast[i]<< " ntrig "<<m_ntrig[i]<<std::endl; + return false; + } + } + if(this==ref){ //Reference event only + //Make sure that every module from the same RCE has the same first bx number + //It's OK if the bx numbers for different RCE's are different + std::cout<<"Now checking reference event"<<std::endl; + for(unsigned int j_rce=0; j_rce<m_nRce; j_rce++){ + std::cout<<"Module "<<j_rce<<" has "<<m_ntrig[j_rce]<<" triggers."<<std::endl; + int modIndex = getFirstModWithRceIndex(j_rce); + for (unsigned int i_mod=modIndex+1; i_mod<m_nMod; i_mod++){ + if(m_modRceIndex[i_mod]==j_rce && m_bx[i_mod]!=m_bx[modIndex]){ + std::cout<<"Module "<<i_mod<<" on RCE "<<j_rce<<" has BXID "<<m_bx[i_mod]<<" while module " + <<modIndex<<" has BXID "<<m_bx[modIndex]<<std::endl; + return false; + } + } + } + } + //Make sure that the BXID dfference between this event and the reference event agrees for all RCEs and all modules. + int bxiddiff=0; + for(unsigned int j_rce=0; j_rce<m_nRce; j_rce++){ + int difftdc=(m_tdcbx[j_rce] - ref->m_tdcbx[j_rce])%256; + if(j_rce==0){ //use RCE 0 as the reference for the difference + bxiddiff=difftdc; + }else{ //check the other RCEs + if(difftdc!=bxiddiff){ + std::cout<<"Events between different RCEs are inconsistent."<<std::endl; + return false; + } + } + } + //Check module BXID differences against RCEs + for(unsigned int i=0;i<m_nMod;i++){ + int diffmod=(m_bx[i]-ref->m_bx[i])%256; + if(diffmod!=bxiddiff){ + std::cout<<"Module "<<i<<" has a BXID difference of "<<diffmod<<", the TDC difference is "<<bxiddiff<<std::endl; + return false; + } + } + return true; +} + +void CosmicEvent::writeEvent(bool monitor, eudaq::FileSerializer* efile, std::ofstream* pfile, unsigned &evtno){ + + if(monitor==true){ + unsigned long long firstTimeStamp = m_timestamp[0]; + for(unsigned i_rce=1; i_rce<m_nRce; i_rce++){ + if(m_timestamp[i_rce]<firstTimeStamp){ + firstTimeStamp = m_timestamp[i_rce]; + } + } + + eudaq::DetectorEvent *dev=new eudaq::DetectorEvent(m_runno,evtno,firstTimeStamp); + counted_ptr<eudaq::Event> ev(dev); + m_ctel->SetEventNumber(evtno); + counted_ptr<eudaq::Event> cpc(m_ctel); + dev->AddEvent(cpc); + m_dut->SetEventNumber(evtno); + counted_ptr<eudaq::Event> cpd(m_dut); + dev->AddEvent(cpd); + if(efile!=0)dev->Serialize(*efile); + if(pfile!=0){ + const unsigned char* block0=&m_dut->GetBlock(0)[0]; + size_t lenTdc=m_dut->GetBlock(0).size(); + + unsigned totalsize=8+lenTdc; + + for(unsigned iRce=0; iRce<m_nRce; iRce++){ + size_t lenPix=m_dut->GetBlock(iRce+1).size(); + totalsize += lenPix; + } + + pfile->write((char*)&totalsize, 4); + pfile->write((char*)&evtno, 4); + pfile->write((const char*)block0, lenTdc); + + for(unsigned iRce=0; iRce<m_nRce; iRce++){ + size_t lenPix=m_dut->GetBlock(iRce+1).size(); + const unsigned char* blockRce=&m_dut->GetBlock(iRce+1)[0]; + pfile->write((const char*)blockRce, lenPix); + } + + } + CosmicEventReceiver::receiveEvent(ev); //this function adds event to monitoring GUI + m_ctel=0; + m_dut=0; + evtno++; + }else if (DataSenderIF::hasInstance()) { + // sending event to CosmicGui + // K. Barry + + // Code for when CosmicGui is receiving events via TCP. + // This code assumes that the DUT and CTEL data have + // been kept separate. It amalgamates them into one + // DetectorEvent and sends that. This is to be + // consistent with the way the data is written to file + // in file-ouput mode of running. + + m_ctel->SetEventNumber(evtno); + counted_ptr<eudaq::Event> cpc(m_ctel); + m_dut->SetEventNumber(evtno); + counted_ptr<eudaq::Event> cpd(m_dut); + + // Need to modify this to include the whole event -- DONE already? + // DataSenderIF::SendEvent(m_dut); + + unsigned long long firstTimeStamp = m_timestamp[0]; + for(unsigned i_rce=1; i_rce<m_nRce; i_rce++){ + if(m_timestamp[i_rce]<firstTimeStamp){ + firstTimeStamp = m_timestamp[i_rce]; + } + } + + eudaq::DetectorEvent dev(m_runno, evtno, firstTimeStamp); + dev.AddEvent(cpc); + dev.AddEvent(cpd); + DataSenderIF::SendEvent(&dev); + + m_ctel = 0; + m_dut = 0; + evtno++; + } else { + // send event to eudaq + //std::cout<<"Sending Eudet event."<<std::endl; + int tlu=(m_dut->GetBlock(0)[37]<<8)|m_dut->GetBlock(0)[36]; + //if(!m_synch&&tlu-1!=m_lastTLU)std::cout<<"Bad tlu "<<tlu<<" last "<<m_lastTLU<<std::endl; + if(m_synch&&(tlu-1!=m_lastTLU && (tlu!=0 || m_lastTLU!=32767))){ + if(tlu<m_lastTLU)tlu+=32768; + std::cout<<"Inserting "<<tlu-m_lastTLU<<" events. TLU id="<<tlu<<" old tlu="<<m_lastTLU<<std::endl; + for(int i=m_lastTLU+1;i<tlu;i++){ + CosmicEvent *ev=makeDummyEvent(m_runno, i, evtno++); + ProducerIF::sendEvent(ev->m_dut); + delete ev; + } + m_synch=false; + std::cout<<"Done inserting events."<<std::endl; + } + m_lastTLU=tlu; + m_dut->SetEventNumber(evtno++); + ProducerIF::sendEvent(m_dut); + } + + +} + +CosmicEvent* CosmicEvent::makeDummyEvent(int runno, int tlu, int evtno){ + std::vector<int> bla; + bla.push_back(0); + CosmicEvent* ev=new CosmicEvent(runno,0,0,bla); + unsigned block[8]={0,0,0,0,0,0,0,0}; + unsigned char* bc=(unsigned char*)block; + bc[29]=(tlu&0x7f00)>>8; + bc[28]=tlu&0xff; + ev->setTdcData(0,block, 0); + ev->m_dut->SetEventNumber(evtno); + return ev; +} + + +void CosmicEvent::print(){ + std::cout<<"Event printout"<<std::endl; + std::cout<<"=============="<<std::endl; + std::cout<<"L1A: "<<m_l1a<<std::endl; + std::cout<<"Event with "<<m_nRce<<" RCEs."<<std::endl; + std::cout<<"RCE's: "; + for (unsigned int i=0;i<m_nRce;i++){ + std::cout<<"RCE "<<m_rces[i]<<": Timestamp: "<<std::hex<<m_timestamp[i] + <<std::dec<<" , TDC BX: "<<m_tdcbx[i]<<std::endl; + } + + if(m_nMod>(16*m_nRce))std::cout<<"ERROR: Number of modules is "<<m_nMod<<std::endl; + else{ + for (unsigned int i=0;i<m_nMod;i++){ + std::cout<<"Module "<<i<<" BX: "<<m_bx[i]<<std::endl; + } + std::cout<<std::endl; + } +} + +unsigned CosmicEvent::getFirstModWithRceIndex(unsigned rceIndex){ + + for(unsigned i=0; i<m_nMod; i++){ + + if(m_modRceIndex[i] == rceIndex){ + return i; + } + + } + + //No module found with the given rce index. Return invalid index. + return m_nMod+1; + +} + +CosmicEventReceiver* CosmicEventReceiver::s_receiver=0; diff --git a/rce/rcecalib/dataproc/CosmicEvent.hh b/rce/rcecalib/dataproc/CosmicEvent.hh new file mode 100644 index 0000000000000000000000000000000000000000..ca7ba9b9f339383199bb104e339367ea3dfa5030 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicEvent.hh @@ -0,0 +1,58 @@ +#ifndef COSMICEVENT_HH +#define COSMICEVENT_HH + +#include <vector> +#include <stdlib.h> +#include <iostream> +#include <fstream> + +namespace eudaq{ + class DetectorEvent; + class RawDataEvent; + class FileSerializer; +} + +class CosmicEvent{ +public: + CosmicEvent(unsigned runno, unsigned l1a, unsigned nMod, std::vector<int>& rces); + ~CosmicEvent(); + void appendCtelData(unsigned *data, unsigned size); + void appendDutData(unsigned *data, unsigned size, unsigned rceIndex); + void setTdcData(unsigned firstword, unsigned *data, unsigned rceIndex); + void incrementTrigger(unsigned mod, int ntrg, unsigned bxfirst, unsigned bxlast, unsigned rceIndex); + + bool consistent(CosmicEvent* ev); + + unsigned getL1A(){return m_l1a;} + int getNmod(){ return m_nMod;} + unsigned getRunNo(){ return m_runno;} + unsigned getFirstModWithRceIndex(unsigned rceIndex); + + + CosmicEvent* makeDummyEvent(int runno, int tlu, int evtno); + void writeEvent(bool monitor, eudaq::FileSerializer *efile, std::ofstream* pfile, unsigned& evtno); + void print(); + static void synch(bool on){m_synch=on;}; + +private: + + bool m_tdctrig; + std::vector<int> m_ntrig; + std::vector<unsigned> m_bx; + std::vector<unsigned> m_bxlast; + std::vector<unsigned> m_modRceIndex; + eudaq::RawDataEvent* m_ctel; + eudaq::RawDataEvent* m_dut; + unsigned m_l1a; + unsigned m_nMod; + std::vector<unsigned long long> m_timestamp; + std::vector<unsigned> m_tdcbx; + unsigned m_runno; + std::vector<int> m_rces; + unsigned m_nRce; + static int m_lastTLU; + static bool m_synch; + +}; + +#endif diff --git a/rce/rcecalib/dataproc/CosmicEventIterator.cc b/rce/rcecalib/dataproc/CosmicEventIterator.cc new file mode 100644 index 0000000000000000000000000000000000000000..46a5d97e881e40129427ba49533e63b70d38ec05 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicEventIterator.cc @@ -0,0 +1,177 @@ + +#include "rcecalib/dataproc/CosmicEventIterator.hh" +#include "rcecalib/dataproc/CosmicEvent.hh" +#include <iostream> + +namespace{ + int badEventThreshold = 3; +} + +CosmicEventIterator::CosmicEventIterator(bool monitor, eudaq::FileSerializer* fs, std::ofstream *pfile, unsigned runno, int nMod, std::vector<int> rces) + : m_runNo(runno), m_nMod(nMod), m_rces(rces), m_monitor(monitor), m_file(fs), m_pfile(pfile), + m_99(true), m_101(false), m_badEvents(0), m_nEvents(1){ + for(int i=0;i<m_nMod;i++) { + m_modit.push_back(std::list<CosmicEvent*>::iterator()); + } + + m_nRce = m_rces.size(); + for(int i=0;i<m_nRce;i++) { + m_tdcit.push_back(std::list<CosmicEvent*>::iterator()); + } + + m_refevent=new CosmicEvent(m_runNo,1,m_nMod,m_rces); // 1 is the first L1id + m_events.push_back(m_refevent); + set(m_events.begin()); + CosmicEvent::synch(false); +} + +CosmicEventIterator::~CosmicEventIterator(){ + if((*(m_events.begin()))!=m_refevent)delete m_refevent; + std::list<CosmicEvent*>::iterator it; + for(it=m_events.begin();it!=m_events.end();it++){ + delete (*it); + } +} + +void CosmicEventIterator::resynch(){ + std::cout<<"CosmicEventIterator::resynch()"<<std::endl; + CosmicEvent::synch(true); + if((*(m_events.begin()))!=m_refevent){ + delete m_refevent; + std::cout<<"First event is not refevent"<<std::endl; + } + std::list<CosmicEvent*>::iterator it; + int i=0; + for(it=m_events.begin();it!=m_events.end();it++){ + std::cout<<"Tossing event with L1A id="<<(*it)->getL1A()<<std::endl; + //(*it)->print(); + delete (*it); + i++; + } + std::cout<<"CosmicEventIterator: Tossed "<<i<<" events."<<std::endl; + m_events.clear(); + m_refevent=new CosmicEvent(m_runNo,1,m_nMod,m_rces); // 1 is the first L1id + m_events.push_back(m_refevent); + set(m_events.begin()); +} +inline void CosmicEventIterator::set(std::list<CosmicEvent*>::iterator it){ + for(int i=0;i<m_nRce;i++)m_tdcit[i]=it; + for(int i=0;i<m_nMod;i++)m_modit[i]=it; +} + +bool CosmicEventIterator::setTdcData(unsigned *data, int rceIndex){ + //return false: indicates that resynching is necessary + + unsigned current=data[0]>>16; // l1id + //unsigned bxid=current&0xff; + unsigned l1id=(current>>8)&0xf; + current|=0x200a0000; //link 10 and header word marker + unsigned l1a=(*m_tdcit[rceIndex])->getL1A(); + if(l1a!=l1id){ + std::cout<<"TDC Event missing. Got L1id "<<l1id<<", was expecting "<<l1a<<std::endl; + return false; + } + + (*m_tdcit[rceIndex])->setTdcData(current, &data[0], rceIndex); + bool success=checkForNewEvent(l1id,m_tdcit[rceIndex]); + if(success==false)return false; + m_tdcit[rceIndex]++; + return checkForWrite(); +} + +bool CosmicEventIterator::addPixelData(int mod, unsigned l1id, int bxfirst, int bxlast, int ntrg, int rceIndex, + bool isdut, unsigned* data, unsigned size){ + CosmicEvent *ev=*m_modit[mod]; + unsigned l1a=ev->getL1A(); + if(l1a!=l1id){ + if((l1id==0&&l1a==15) || (l1id==l1a+1)){ + bool success=checkForNewEvent(l1a,m_modit[mod]); + if(success==false){ + std::cout<<"bad check"<<std::endl; + return false; + } + m_modit[mod]++; + ev=*m_modit[mod]; + if(checkForWrite()==false)return false; + }else{ + std::cout<<"Module "<<mod<<" Event missing. Got L1id "<<l1id<<", was expecting "<<l1a<<std::endl; + return false; + } + } + if(ntrg>0)ev->incrementTrigger(mod, ntrg, bxfirst, bxlast, rceIndex); + if(isdut==true)ev->appendDutData(data,size,rceIndex); + else ev->appendCtelData(data,size); + return true; +} +void CosmicEventIterator::flushEvents(){ + int eventswritten=0; + int badevents=0; + while(!m_events.empty()){ + CosmicEvent* ev=m_events.front(); + m_events.pop_front(); + if(ev->consistent(m_refevent)){ + std::cout<<"Flushing event with L1id="<<ev->getL1A()<<std::endl; + ev->writeEvent(m_monitor, m_file, m_pfile, m_nEvents); + eventswritten++; + }else{ + badevents++; + } + if(ev!=m_refevent)delete ev; + } + std::cout<<"Wrote "<<eventswritten<<" events and discarded "<<badevents<<std::endl; +} + +inline bool CosmicEventIterator::checkForWrite(){ + bool retval=true; + while(!m_events.empty() && inUse(m_events.begin())==false){ + CosmicEvent* ev=m_events.front(); + m_events.pop_front(); + if(ev->consistent(m_refevent)){ + //ev->print(); + ev->writeEvent(m_monitor, m_file, m_pfile, m_nEvents); + m_badEvents=0; + }else{ //inconsistent event. + m_badEvents++; + if(m_badEvents>badEventThreshold){ + m_badEvents=0; + retval=false; + ev->print(); + std::cout<<"Bad consistency for more than "<<badEventThreshold<<" events in a row. Resynchronizing"<<std::endl; + } else{ + ev->print(); + std::cout<<"Bad consistency for "<<m_badEvents<<" events in a row. Tossing event."<<std::endl; + } + } + if(ev!=m_refevent)delete ev; + } + return retval; +} + +inline bool CosmicEventIterator::inUse(std::list<CosmicEvent*>::iterator it){ + + for (int i=0;i<m_nRce;i++){ + if(m_tdcit[i]==it){ + return true; + } + } + for (int i=0;i<m_nMod;i++){ + if(m_modit[i]==it){ + return true; + } + } + return false; +} + +inline bool CosmicEventIterator::checkForNewEvent(unsigned l1a, std::list<CosmicEvent*>::iterator it){ + //return false only if we need to create new event AND we don't have room to store it + it++; + if(it==m_events.end()){ // need new event + unsigned nextl1a= l1a==15 ? 0 : l1a+1; + m_events.push_back(new CosmicEvent(m_runNo, nextl1a, m_nMod, m_rces)); + if(m_events.size()==1001){ + std::cout<<"Now exceeding 1000 events in list. Resynching."<<std::endl; + return false; + } + } + return true; +} diff --git a/rce/rcecalib/dataproc/CosmicEventIterator.hh b/rce/rcecalib/dataproc/CosmicEventIterator.hh new file mode 100644 index 0000000000000000000000000000000000000000..15b6887da62d812607a024e5833a9bd27e425dc4 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicEventIterator.hh @@ -0,0 +1,44 @@ +#ifndef COSMICEVENTITERATOR_HH +#define COSMICEVENTITERATOR_HH + +#include <vector> +#include <list> +#include <fstream> + +class CosmicEvent; +namespace eudaq{ + class FileSerializer; +} + +class CosmicEventIterator{ +public: + CosmicEventIterator(bool monitor, eudaq::FileSerializer *fs, std::ofstream *pf, unsigned runno, + int nMod, std::vector<int> rces); + ~CosmicEventIterator(); + void resynch(); + bool setTdcData(unsigned* data, int rceIndex); + bool checkForWrite(); + bool inUse(std::list<CosmicEvent*>::iterator it); + void flushEvents(); + int nEvents(){return m_nEvents;} + inline bool checkForNewEvent(unsigned l1a, std::list<CosmicEvent*>::iterator it); + bool addPixelData(int mod, unsigned l1id, int bxfirst, int bxlast, int ntrg, int rceIndex, + bool isdut, unsigned* data, unsigned size); + CosmicEvent* m_refevent; +private: + void set(std::list<CosmicEvent*>::iterator it); + unsigned m_runNo; + int m_nMod; + std::vector<int> m_rces; + int m_nRce; + std::list<CosmicEvent*> m_events; + std::vector<std::list<CosmicEvent*>::iterator> m_modit; + std::vector<std::list<CosmicEvent*>::iterator> m_tdcit; + bool m_monitor; + eudaq::FileSerializer *m_file; + std::ofstream *m_pfile; + bool m_99, m_101; + int m_badEvents; + unsigned int m_nEvents; +}; +#endif diff --git a/rce/rcecalib/dataproc/CosmicEventReceiver.hh b/rce/rcecalib/dataproc/CosmicEventReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..0020db6bb694249b4e81bb1c4ad736307ccfcf73 --- /dev/null +++ b/rce/rcecalib/dataproc/CosmicEventReceiver.hh @@ -0,0 +1,17 @@ +#ifndef COSMICEVENTRECEIVER_HH +#define COSMICEVENTRECEIVER_HH + +#include "rcecalib/eudaq/Event.hh" + +class CosmicEventReceiver{ +public: + CosmicEventReceiver(){s_receiver=this;} + virtual ~CosmicEventReceiver(){} + virtual void OnReceive(counted_ptr<eudaq::Event> ev)=0; + static void receiveEvent(counted_ptr<eudaq::Event> ev){ + if(s_receiver!=0)s_receiver->OnReceive(ev); + } + static CosmicEventReceiver* s_receiver; +}; + +#endif diff --git a/rce/rcecalib/dataproc/DataProcFactory.cc b/rce/rcecalib/dataproc/DataProcFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..1ac99e7a12e8b185e5c39329f49e6a962aa96382 --- /dev/null +++ b/rce/rcecalib/dataproc/DataProcFactory.cc @@ -0,0 +1,114 @@ +#include "util/DataCond.hh" +#include "dataproc/DataProcFactory.hh" +#include "dataproc/OccupancyDataProc.hh" +#include "dataproc/RawFei4OccupancyDataProc.hh" +#include "dataproc/NoiseOccupancyDataProc.hh" +#include "dataproc/TotDataProc.hh" +#include "dataproc/TotCalibDataProc.hh" +#include "dataproc/BcidDataProc.hh" +#include "dataproc/SelftriggerDataProc.hh" +#include "dataproc/MultiTrigOccupancyDataProc.hh" +#include "dataproc/MultiTrigNoiseDataProc.hh" +#include "dataproc/MeasurementDataProc.hh" +#include "dataproc/HitorDataProc.hh" +#include "dataproc/CosmicDataProc.hh" +#include "dataproc/DelayScanDataProc.hh" +#include "dataproc/DelayScanDataHandler.hh" +#include "dataproc/CosmicDataHandler.hh" +#include "dataproc/SimpleDataHandler.hh" +#include "dataproc/RegularScanDataHandler.hh" +#include "dataproc/RegularScanRawDataHandler.hh" +#include "dataproc/ModuleCrosstalkRawDataHandler.hh" +#include "dataproc/SimpleReceiver.hh" +#include "dataproc/MeasurementReceiver.hh" +#include "dataproc/PgpReceiver.hh" +#include "dataproc/PgpCosmicReceiver.hh" +#include "dataproc/PgpCosmicNwReceiver.hh" +#include "dataproc/TemperatureDataProc.hh" +#include "dataproc/MonleakDataProc.hh" +#include "dataproc/SNDataProc.hh" +#include "dataproc/Fei4RegisterTestDataProc.hh" + +#ifdef __rtems__ +#include <boost/property_tree/ptree.hpp> +#endif +#include <iostream> + + +AbsDataProc* DataProcFactory::createDataProcessor(const char* type, ConfigIF* cif, + boost::property_tree::ptree* scanOptions){ + if(std::string(type)=="OCCUPANCY") + return new OccupancyDataProc(cif, scanOptions); + if(std::string(type)=="RawFei4Occupancy") + return new RawFei4OccupancyDataProc(cif, scanOptions); + if(std::string(type)=="Noisescan") + return new NoiseOccupancyDataProc(cif, scanOptions); + if(std::string(type)=="TOT") + return new TotDataProc(cif, scanOptions); + if(std::string(type)=="TOTCALIB") + return new TotCalibDataProc(cif, scanOptions); + if(std::string(type)=="BCID") + return new BcidDataProc(cif, scanOptions); + if(std::string(type)=="Delay") + return new DelayScanDataProc(cif, scanOptions); + if(std::string(type)=="CosmicData") + return new CosmicDataProc(cif, scanOptions); + if(std::string(type)=="Measurement") + return new MeasurementDataProc(cif, scanOptions); + if(std::string(type)=="Selftrigger") + return new SelftriggerDataProc(cif, scanOptions); + if(std::string(type)=="MultiTrigOccupancy") + return new MultiTrigOccupancyDataProc(cif, scanOptions); + if(std::string(type)=="MultiTrigNoise") + return new MultiTrigNoiseDataProc(cif, scanOptions); + if(std::string(type)=="Hitor") + return new HitorDataProc(cif, scanOptions); + if(std::string(type)=="Temperature") + return new TemperatureDataProc(cif, scanOptions); + if(std::string(type)=="Monleak") + return new MonleakDataProc(cif, scanOptions); + if(std::string(type)=="SerialNumber") + return new SNDataProc(cif, scanOptions); + if(std::string(type)=="Fei4RegisterTest") + return new Fei4RegisterTestDataProc(cif, scanOptions); + else + return 0; +} + + +AbsDataHandler* DataProcFactory::createDataHandler(const char* type, AbsDataProc *dataproc, DataCond& datacond, + ConfigIF* cif, boost::property_tree::ptree* scanOptions){ + if(std::string(type)=="RegularScan") + return new RegularScanDataHandler(dataproc, datacond, cif, scanOptions); + else if(std::string(type)=="RegularScanRaw") + return new RegularScanRawDataHandler(dataproc, datacond, cif, scanOptions); + else if(std::string(type)=="ModuleCrosstalkRaw") + return new ModuleCrosstalkRawDataHandler(dataproc, datacond, cif, scanOptions); + else if(std::string(type)=="Simple") + return new SimpleDataHandler(dataproc, datacond); + else if(std::string(type)=="DelayScan") + return new DelayScanDataHandler(dataproc, datacond); + else if(std::string(type)=="CosmicData") + return new CosmicDataHandler(dataproc, datacond, cif, scanOptions); + else + return 0; +} + +AbsReceiver* DataProcFactory::createReceiver(const char* type, AbsDataHandler* handler, boost::property_tree::ptree* scanOptions) { + std::cout<<"Creating receiver of type "<<type<<std::endl; + if(std::string(type)=="Simple") + return new SimpleReceiver(handler); +#ifdef __rtems__ + else if(std::string(type)=="Pgp") + return new PgpReceiver(handler); + else if(std::string(type)=="PgpCosmic") + return new PgpCosmicReceiver(handler); + else if(std::string(type)=="PgpCosmicNw") + return new PgpCosmicNwReceiver(handler, scanOptions); + else if(std::string(type)=="Measurement") + return new MeasurementReceiver(handler, scanOptions); +#endif + else + return 0; +} + diff --git a/rce/rcecalib/dataproc/DataProcFactory.hh b/rce/rcecalib/dataproc/DataProcFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..c98f7e965ad6892ff3d775dedffd00d9e45ba6cc --- /dev/null +++ b/rce/rcecalib/dataproc/DataProcFactory.hh @@ -0,0 +1,24 @@ +#ifndef DATAPROCFACTORY_HH +#define DATAPROCFACTORY_HH + +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/AbsReceiver.hh" +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <boost/property_tree/ptree_fwd.hpp> + +class DataCond; + +class DataProcFactory{ +public: + DataProcFactory(){}; + AbsDataProc* createDataProcessor(const char* type, ConfigIF* cif, boost::property_tree::ptree* scanOptions); + AbsDataHandler* createDataHandler(const char* type, AbsDataProc *dataproc, DataCond& datacond, + ConfigIF* cif, boost::property_tree::ptree* scanOptions); + AbsReceiver *createReceiver(const char* type, AbsDataHandler* handler, boost::property_tree::ptree* scanOptions); + + +}; + + +#endif diff --git a/rce/rcecalib/dataproc/DelayScanDataHandler.cc b/rce/rcecalib/dataproc/DelayScanDataHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..037938f59094536ded2b660ba47340d11ac87440 --- /dev/null +++ b/rce/rcecalib/dataproc/DelayScanDataHandler.cc @@ -0,0 +1,15 @@ +#include "rcecalib/dataproc/DelayScanDataHandler.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/util/DataCond.hh" +#include <boost/property_tree/ptree.hpp> +#include <iostream> + +DelayScanDataHandler::DelayScanDataHandler(AbsDataProc* dataproc, DataCond& datacond) + :AbsDataHandler(dataproc, datacond, 0 ){} + + +void DelayScanDataHandler::handle(unsigned link, unsigned *data, int size){ + assert(link==10); + m_dataProc->processData(link, data, size); +} diff --git a/rce/rcecalib/dataproc/DelayScanDataHandler.hh b/rce/rcecalib/dataproc/DelayScanDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..3e679086d8d2ff5ee500cb185410201252958272 --- /dev/null +++ b/rce/rcecalib/dataproc/DelayScanDataHandler.hh @@ -0,0 +1,19 @@ +#ifndef DELAYSCANDATAHANDLER_HH +#define DELAYSCANDATAHANDLER_HH + +#include <vector> +#include <map> +#include <assert.h> + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include <boost/property_tree/ptree_fwd.hpp> +class DataCond; + + +class DelayScanDataHandler: public AbsDataHandler{ +public: + DelayScanDataHandler(AbsDataProc* dataproc, DataCond& datacond); + virtual ~DelayScanDataHandler(){} + void handle(unsigned link, unsigned* data, int size); +}; +#endif diff --git a/rce/rcecalib/dataproc/DelayScanDataProc.cc b/rce/rcecalib/dataproc/DelayScanDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..d0fe654eb54fd75f5dc9e42e539f1f4766411a69 --- /dev/null +++ b/rce/rcecalib/dataproc/DelayScanDataProc.cc @@ -0,0 +1,43 @@ +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/DelayScanDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/DataProcFactory.hh" +#include <assert.h> +#include <stdio.h> + + +int DelayScanDataProc::processData(unsigned link, unsigned *data, int size){ + printf("Coincidence\n"); + m_histo[0][0]->increment(m_currentBin); + return 0; +} + +DelayScanDataProc::DelayScanDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + try{ //catch bad scan option parameters + int nLoops = scanOptions->get<int>("nLoops"); + assert (nLoops>0); + int nPoints=1; + nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + assert(nPoints>1); + int p0=scanOptions->get<int>("scanLoop_0.dataPoints.P_0"); + char pointname[10]; + sprintf(pointname,"P_%d",nPoints-1); + int pn=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + std::vector<RceHisto1d<short, short>*> vh; + std::cout<<"DelayScanDataProc"<<std::endl; + m_histo.push_back(vh); + int overlap = (pn-p0)/(nPoints-1)/2; + m_histo[0].push_back(new RceHisto1d<short, short>("delhisto","DISC 1 - DISC 0",nPoints, p0-overlap, pn+overlap)); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +DelayScanDataProc::~DelayScanDataProc(){ + delete m_histo[0][0]; +} diff --git a/rce/rcecalib/dataproc/DelayScanDataProc.hh b/rce/rcecalib/dataproc/DelayScanDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..14819f31626728040b2ece71a1afb013419bf46e --- /dev/null +++ b/rce/rcecalib/dataproc/DelayScanDataProc.hh @@ -0,0 +1,19 @@ +#ifndef DELAYSCANDATAPROC_HH +#define DELAYSCANDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" + +class DelayScanDataProc: public AbsDataProc{ +public: + DelayScanDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~DelayScanDataProc(); + int processData(unsigned link, unsigned *data, int size); +private: + std::vector<std::vector<RceHisto1d<short, short>*> > m_histo; + +}; + +#endif diff --git a/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.cc b/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..bbfe5f8985594ff2f7681aef8b5e083cd7d49c81 --- /dev/null +++ b/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.cc @@ -0,0 +1,145 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/Fei4RegisterTestDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" + +int Fei4RegisterTestDataProc::fit(std::string fitfun) { + return 0; +} + +int Fei4RegisterTestDataProc::processData(unsigned link, unsigned *buffer, int buflen){ + //m_timer.Start(); + if(buflen==0)return 0; + int nL1A=0; + int module=m_linkToIndex[link]; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4ARecord rec; + int address=-1; + int row=0, col=0; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isEmptyRecord()){ //includes empty record type + // do nothing + }else if(rec.isData()){ //includes empty record type + std::cout<<"Data"<<std::endl; + } else if(rec.isDataHeader()){ + //nL1A++; + std::cout<<"Data Header"<<std::endl; + }else if(rec.isServiceRecord()){ + //unsigned int moduleId=m_info[module].getId(); + //if(rec.getErrorCode()!=10 && (rec.getErrorCode()!=16 || (rec.getErrorCount()&0x200)) ) + // printf("Service record FE %d . Error code: %d. Count: %d \n", moduleId, rec.getErrorCode(), rec.getErrorCount()); + //if( rec.getErrorCode()<32)m_errhist[module]->fill(rec.getErrorCode(), rec.getErrorCount()); + //header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + nL1A++; + //printf("Value record: %04x.\n",rec.getValue()); + if(address==-1)std::cout<<"Address record missing"<<std::endl; + if(m_currentMaskStage<2){ //Pixel register + if(address==15)m_counter[module]++; //new bit or dcol + int dcol=m_counter[module]/13; + int bit=m_counter[module]%13; + for (int i=0;i<16;i++){ + if(address>335){ + row=address-i-336; + col=dcol*2; + }else{ + row=335-address+i; + col=dcol*2+1; + } + int oldval=(*m_pix[module])(row, col); + oldval&=0x1fff; // clear initial setting to show that the value was read + int val=rec.getValue()&(1<<i); + bool bad=false; + if(m_currentMaskStage==(row%2)){ + if(!val)bad=true; + }else{ + if(val)bad=true; + } + if(bad){ + oldval|=1<<bit; + } + m_pix[module]->set(row,col, oldval); + } + }else{ //global register + if(address>=0&&address<=35){ + m_glob[module]->set(address, rec.getValue()); + } + } + }else if(rec.isAddressRecord()){ // address record + //std::cout<<"FE "<<m_info[module].getId()<<": Address record for "; + //if(rec.isGlobal())std::cout<<" global register "; + //else std::cout<<" shift register "; + //std::cout<<rec.getAddress()<<std::endl; + address=rec.getAddress(); + }else{ + std::cout<<"FE "<<m_info[module].getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + //return FEI4::FEI4ARecord::BadRecord; + return 0; + } + bytepointer+=3; + } + //m_timer.Stop(); + return nL1A; +} + +Fei4RegisterTestDataProc::Fei4RegisterTestDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + std::cout<<"Register Test Data Proc"<<std::endl; + m_counter.clear(); + try{ //catch bad scan option parameters + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + char name[128]; + char title[128]; + RceHisto2d<int, int> *histo; + RceHisto1d<int, int> *histo1d; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + sprintf(title,"Pixel Register Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Pixel_Reg", moduleId); + histo=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true); + histo->setAxisTitle(1,"Column"); + histo->setAxisTitle(0, "Row"); + //initialize to non-zero value + for(unsigned int i=0;i<rows;i++){ + for(unsigned int j=0;j<cols;j++){ + histo->set(i, j, 1<<13); + } + } + m_pix.push_back(histo); + m_counter.push_back(-1); + sprintf(title,"Global Register Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Global_Reg", moduleId); + histo1d=new RceHisto1d<int, int>(name,title,36, -0.5, 35.5); + histo1d->setAxisTitle(0, "Register"); + m_glob.push_back(histo1d); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } + //m_timer.Reset(); +} + +Fei4RegisterTestDataProc::~Fei4RegisterTestDataProc(){ + for (size_t module=0;module<m_pix.size();module++){ + delete m_pix[module]; + delete m_glob[module]; + } +} + +int Fei4RegisterTestDataProc::setMaskStage(int stage){ + m_currentMaskStage=stage; + for(unsigned i=0;i<m_counter.size();i++)m_counter[i]=-1; + return 0; +} + diff --git a/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.hh b/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..e3e1f8c98c51bea80c01b0aa171e9b4f6e28a02b --- /dev/null +++ b/rce/rcecalib/dataproc/Fei4RegisterTestDataProc.hh @@ -0,0 +1,26 @@ +#ifndef FEI4REGISTERTESTDATAPROC_HH +#define FEI4REGISTERTESTDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceHisto1d.cc" +#include "rcecalib/profiler/Profiler.hh" + +class Fei4RegisterTestDataProc: public AbsDataProc{ +public: + Fei4RegisterTestDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~Fei4RegisterTestDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + int setMaskStage(int stage); + +protected: + enum FEI4{N_ROW=336, N_COL=80}; + std::vector<RceHisto2d<int, int>*> m_pix; + std::vector<RceHisto1d<int, int>*>m_glob; + std::vector<int> m_counter; +}; + +#endif diff --git a/rce/rcecalib/dataproc/HitorDataProc.cc b/rce/rcecalib/dataproc/HitorDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..019768456ab1fa9939a73321d6d908765c9262f9 --- /dev/null +++ b/rce/rcecalib/dataproc/HitorDataProc.cc @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/HitorDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" + + +int HitorDataProc::processData(unsigned link, unsigned *data, int size){ + // std::cout<<"Process data"<<std::endl; + int module=m_linkToIndex[link]; + int col=m_currentMaskStage/m_info[module].getNRows(); + int row=m_currentMaskStage%m_info[module].getNRows(); + m_histo_occ[module][0]->increment(col,row); + return 0; +} + +HitorDataProc::HitorDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif){ + std::cout<<"Hitor Data Proc"<<std::endl; + try{ //catch bad scan option parameters + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<short, short>* > vh; + m_histo_occ.push_back(vh); + char name[128]; + char title[128]; + RceHisto2d<short, short> *histo; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + std::cout<<"Creating Hitor histograms."<<std::endl; + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Hitor", moduleId); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_occ[module].push_back(histo); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +HitorDataProc::~HitorDataProc(){ + for (size_t module=0;module<m_histo_occ.size();module++) + for(size_t i=0;i<m_histo_occ[module].size();i++)delete m_histo_occ[module][i]; + +} + + diff --git a/rce/rcecalib/dataproc/HitorDataProc.hh b/rce/rcecalib/dataproc/HitorDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..6e261f54b30764930df844475156a858f080bfba --- /dev/null +++ b/rce/rcecalib/dataproc/HitorDataProc.hh @@ -0,0 +1,21 @@ +#ifndef HITORDATAPROC_HH +#define HITORDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" + +class HitorDataProc: public AbsDataProc{ +public: + HitorDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~HitorDataProc(); + int processData(unsigned link, unsigned *data, int size); + +protected: + + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_occ; +}; + +#endif diff --git a/rce/rcecalib/dataproc/Makefile b/rce/rcecalib/dataproc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/rcecalib/dataproc/Makefile @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/rcecalib/dataproc/MeasurementDataProc.cc b/rce/rcecalib/dataproc/MeasurementDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..beda83dde3faea24d29db1d8130f09f8ced3fb4e --- /dev/null +++ b/rce/rcecalib/dataproc/MeasurementDataProc.cc @@ -0,0 +1,74 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/MeasurementDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/util/exceptions.hh" +#include "math.h" + +int MeasurementDataProc::fit(std::string fitfun) { + std::cout << "Running: " << fitfun << std::endl; + if(fitfun=="NORMALIZE" && m_nTrigger>0) { + float n=(float)m_nTrigger; + for(int j=0;j<m_nPoints;j++){ + float mean=(*m_histo)(j)/n; + m_histo->set(j, mean); + float err=(m_err[j]/n-mean*mean)/n; + if(err<0)err=0; //prevent rounding errors + m_histo->setBinError(j, err); + // std::cout<<"Bin content is "<<(*m_histo[module][i])(j)<<std::endl; + //std::cout<<"Bin error is "<<m_histo[module][i]->getBinError(j)<<std::endl; + } + } + return 0; +} + +int MeasurementDataProc::processData(unsigned link, unsigned *data, int size){ + // std::cout<<"Process data"<<std::endl; + float val=*((float*)data); + //std::cout<<"Measured value "<<val<<std::endl; + m_histo->fill(m_currentBin, val); + m_err[m_currentBin]+= val*val; + return 0; +} + +MeasurementDataProc::MeasurementDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif){ + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + double width=1; + if(m_nPoints>1)width=double(m_vcal[m_nPoints-1]-m_vcal[0])/(double)(m_nPoints-1)*0.5; + m_histo=new RceHisto1d<float, float>("Measurement","Measurement",m_nPoints,m_vcal[0]-width,m_vcal[m_nPoints-1]+width); + m_histo->setAxisTitle(0,"DAC"); + + //error array + m_err=new float[m_nPoints]; + for(int i=0;i<m_nPoints;i++)m_err[i]=0; + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +MeasurementDataProc::~MeasurementDataProc(){ + delete m_histo; + delete [] m_err; +} + + diff --git a/rce/rcecalib/dataproc/MeasurementDataProc.hh b/rce/rcecalib/dataproc/MeasurementDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..4047468760c620744eba2875016079eb2ba19417 --- /dev/null +++ b/rce/rcecalib/dataproc/MeasurementDataProc.hh @@ -0,0 +1,28 @@ +#ifndef MEASUREMENTDATAPROC_HH +#define MEASUREMENTDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" + +class MeasurementDataProc: public AbsDataProc{ +public: + MeasurementDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~MeasurementDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + RceHisto1d<float, float>* m_histo; + std::vector<int> m_vcal; + float *m_err; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + int m_nMaskStages; +}; + +#endif diff --git a/rce/rcecalib/dataproc/MeasurementReceiver.cc b/rce/rcecalib/dataproc/MeasurementReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..8669a5528509d61b2addda81872f47396fac9571 --- /dev/null +++ b/rce/rcecalib/dataproc/MeasurementReceiver.cc @@ -0,0 +1,101 @@ +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, net, Error.hh) +#include DAT_PUBLIC( oldPpi, net, SocketTcp.hh) +#ifndef __rtems__ +#include DAT_PUBLIC( oldPpi, net, GetAddr.hh) +#endif +#else +#include "rce/net/Error.hh" +#include "rce/net/Getaddr.hh" +#include "rce/net/SocketTcp.hh" +#endif +#include "namespace_aliases.hh" +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <string.h> +#include "rcecalib/HW/RCDImaster.hh" +#include <boost/regex.hpp> +#include <boost/property_tree/ptree.hpp> + +#include <arpa/inet.h> // for htonl + +#include "rcecalib/dataproc/MeasurementReceiver.hh" + + +MeasurementReceiver::MeasurementReceiver(AbsDataHandler* handler, boost::property_tree::ptree* scanOptions): + PgpReceiver(handler), TriggerReceiverIF(){ + PgpTrans::RCDImaster::instance()->setReceiver(this); + + //the name is "ipAddr:port" + std::string name=scanOptions->get<std::string>("Name"); + boost::cmatch matches; + boost::regex re("(^.*):(\\d+)"); + std::string ipaddr, port; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>2); + ipaddr=std::string(matches[1].first, matches[1].second); + port=std::string(matches[2].first, matches[2].second); + }else{ + std::cout<<"No ip addr:port given"<<std::endl; + assert(0); + } +#ifdef __rtems__ + // construct address from string with dots + boost::regex re2("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"); + unsigned address; + if(boost::regex_search(ipaddr.c_str(), matches, re2)){ + assert(matches.size()>4); + address=atoi(std::string(matches[1].first, matches[1].second).c_str())<<24; + address|=atoi(std::string(matches[2].first, matches[2].second).c_str())<<16; + address|=atoi(std::string(matches[3].first, matches[3].second).c_str())<<8; + address|=atoi(std::string(matches[4].first, matches[4].second).c_str()); + }else{ + std::cout<<"bad ip address given"<<std::endl; + assert(0); + } +#else + unsigned address = RceNet::getaddr(ipaddr.c_str()); +#endif + std::cout<<"Ip address is "<<std::hex<<address<<std::dec<<std::endl; + int porti=atoi(port.c_str()); + m_addr=RceNet::IpAddress(address, porti); + m_ipname=ipaddr; + + std::cout<<"Created Measurement receiver"<<std::endl; + +} + + +void MeasurementReceiver::Receive(unsigned *data, int size){ + std::string vals=sendCommand("measure", m_addr, m_ipname.c_str()); + float val; + char* end; + val=strtof(vals.c_str(), &end); + if(end-vals.c_str()!=(int)vals.size()){ + std::cout<<"Bad value "<<vals<<std::endl; + assert(0); + } + m_handler->handle(0, (unsigned*)&val, 1); + return; +} +const char* MeasurementReceiver::sendCommand(std::string inpline, RceNet::IpAddress dst, const char* rce){ + RceNet::SocketTcp socket; + socket.connect(dst); + socket.send(inpline.c_str(), inpline.size()); + int timeout= 10000; + static char line[128]; + try{ + socket.setrcvtmo(timeout); + int bytes=socket.recv(line,128); + line[bytes]=0; + } + catch (...){ + std::cout<<"Network error. Exiting."<<std::endl; + assert(0); + } + socket.close(); + return line; +} + diff --git a/rce/rcecalib/dataproc/MeasurementReceiver.hh b/rce/rcecalib/dataproc/MeasurementReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..d393304300df71c3385aa3d04fc1755eaf84c488 --- /dev/null +++ b/rce/rcecalib/dataproc/MeasurementReceiver.hh @@ -0,0 +1,24 @@ +#ifndef MEASUREMENTRECEIVER_HH +#define MEASUREMENTRECEIVER_HH + +#include "rcecalib/dataproc/PgpReceiver.hh" +#include "rcecalib/config/TriggerReceiverIF.hh" +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, net, IpAddress.hh) +#else +#include "rce/net/IpAddress.hh" +#endif +#include <boost/property_tree/ptree_fwd.hpp> +#include "namespace_aliases.hh" +class MeasurementReceiver: public PgpReceiver, public TriggerReceiverIF{ +public: + MeasurementReceiver(AbsDataHandler* handler, boost::property_tree::ptree* scanOptions); + void Receive(unsigned *data, int size); + void receive(PgpTrans::PgpData* pgpdata){}; //pgp dummy + const char* sendCommand(std::string inpline, RceNet::IpAddress address, const char* rce); +private: + RceNet::IpAddress m_addr; + std::string m_ipname; +}; +#endif diff --git a/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.cc b/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..e720d4a3073d7c22b679c7489af40e6176f52558 --- /dev/null +++ b/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.cc @@ -0,0 +1,85 @@ +#include "rcecalib/dataproc/ModuleCrosstalkRawDataHandler.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <boost/property_tree/ptree.hpp> +#include <iostream> +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/util/DataCond.hh" + +ModuleCrosstalkRawDataHandler::ModuleCrosstalkRawDataHandler(AbsDataProc* dataproc, + DataCond& datacond, + ConfigIF* cif, + boost::property_tree::ptree* scanOptions) + :AbsDataHandler(dataproc, datacond, cif){ + std::cout<<"Regular raw data handler"<<std::endl; + m_nL1AperEv=scanOptions->get<int>("trigOpt.nL1AperEvent"); + int ntrigpergroup=scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + if(ntrigpergroup!=0)m_nL1AperEv*=ntrigpergroup; + std::cout<<"Number of expected triggers is "<<m_nL1AperEv<<std::endl; + int maxlink=0; + m_nModules=m_configIF->getNmodules(); + m_L1Acounters=new int[m_nModules]; + m_outlinkMask=new int[m_nModules]; + m_moduleTrgMask=scanOptions->get<int>("trigOpt.moduleTrgMask"); + resetL1counters(); + for (int i=0;i<m_nModules;i++){ + m_outlinkMask[i]=1<<m_configIF->getModuleInfo(i).getOutLink(); + if(m_configIF->getModuleInfo(i).getOutLink()>maxlink)maxlink=m_configIF->getModuleInfo(i).getOutLink(); + } + maxlink++; + m_linkToIndex=new int[maxlink]; + for (unsigned int i=0;i<m_configIF->getNmodules();i++){ + m_linkToIndex[m_configIF->getModuleInfo(i).getOutLink()]=i; + } + //m_timer.Reset(); + m_counter=0; +} + +ModuleCrosstalkRawDataHandler::~ModuleCrosstalkRawDataHandler(){ + delete [] m_L1Acounters; + delete [] m_outlinkMask; + delete [] m_linkToIndex; + // m_timer.Print("ModuleCrosstalkRawDataHandler"); +} + +void ModuleCrosstalkRawDataHandler::timeoutOccurred(){ + resetL1counters(); +} + +void ModuleCrosstalkRawDataHandler::resetL1counters(){ + for (int i=0;i<m_nModules;i++){ + m_L1Acounters[i]=0; + } +} + +void ModuleCrosstalkRawDataHandler::handle(unsigned link, unsigned *data, int size){ + // nL1A contains the number of L1A in the data chunk + //std::cout<<"Data from Link "<<link<<std::endl; + //m_timer.Start(); + int nL1A= m_dataProc->processData(link, data, size); + //m_timer.Stop(); + //std::cout<<nL1A<<" events."<<std::endl; + // std::cout<<"Expecting "<<m_nL1AperEv<<std::endl; + //for (int i=size-4;i<size;i++)std::cout<<std::hex<<data[i]<<std::endl; + m_L1Acounters[m_linkToIndex[link]]+=nL1A; + // std::cout<<m_L1Acounters[m_linkToIndex[link]]<<" events so far."<<std::endl; + bool done=true; + //check if the event is complete. + for (int i=0;i<m_nModules;i++){ + //if(m_L1Acounters[i]>m_nL1AperEv)std::cout<<m_L1Acounters[i]<<" L1Atriggers"<<std::endl; + if(m_outlinkMask[i]&m_moduleTrgMask)continue; + if (m_L1Acounters[i]<m_nL1AperEv){ + done=false; + break; + } + } + if(done){ + //std::cout<<"Restarting scan "<<std::endl; + resetL1counters(); + // Next trigger + omni_mutex_lock pl( m_dataCond.mutex ); + if(m_dataCond.waitingForData==true)m_dataCond.cond.signal(); + else std::cout<<"Scan was not waiting for data!"<<std::endl; + } +} diff --git a/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.hh b/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..83a22cc9fa37f9effb15f1ef1340a48a68d094f5 --- /dev/null +++ b/rce/rcecalib/dataproc/ModuleCrosstalkRawDataHandler.hh @@ -0,0 +1,31 @@ +#ifndef MODULECROSSTALKRAWDATAHANDLER_HH +#define MODULECROSSTALKRAWDATAHANDLER_HH + +#include <omnithread.h> +#include <assert.h> + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/profiler/Profiler.hh" + +class AbsFormatter; +class DataCond; + +class ModuleCrosstalkRawDataHandler: public AbsDataHandler{ +public: + ModuleCrosstalkRawDataHandler(AbsDataProc* dataproc, DataCond& datacond, ConfigIF* cif, boost::property_tree::ptree* scanOptions); + virtual ~ModuleCrosstalkRawDataHandler(); + inline void handle(unsigned link, unsigned* data, int size); + void timeoutOccurred(); + inline void resetL1counters(); +protected: + int m_nL1AperEv; + int* m_L1Acounters; + int m_nModules; + int *m_linkToIndex; + int m_moduleTrgMask; + int* m_outlinkMask; + Profiler::Timer m_timer; + int m_counter; +}; +#endif diff --git a/rce/rcecalib/dataproc/MonleakDataProc.cc b/rce/rcecalib/dataproc/MonleakDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..9ea94a0ce4aaac80b4237821f86b6c461f418166 --- /dev/null +++ b/rce/rcecalib/dataproc/MonleakDataProc.cc @@ -0,0 +1,192 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/MonleakDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/config/FEI4/FEI4BRecord.hh" +#include "rcecalib/config/FEI4/PixelRegister.hh" +using namespace FEI4; + +int MonleakDataProc::fit(std::string fitfun) { + std::cout << "Running: " << fitfun << std::endl; + if(fitfun=="NORMALIZE") { + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + for(int j=0;j<m_nPoints;j++){ + // float n=(float)(*m_histo_occ[module])(j); + std::cout<<"Fit function currently not working, will need to change eventually to work with 2d histos"<<std::endl; + // float n=1; + // float mean=0; + + /* + if(n>0)mean=(float)(*m_histo_adc[module])(j)/n; + m_histo_norm[module]->set(j, mean); + float err=0; + if(n>0)err=((*m_histo_adc2[module])(j)/n-mean*mean)/n; //error^2 on mean + if(err<0)err=0; //prevent rounding errors + m_histo_norm[module]->setBinError(j, err); + // std::cout<<"Bin content is "<<(*m_histo[module][i])(j)<<std::endl; + //std::cout<<"Bin error is "<<m_histo[module][i]->getBinError(j)<<std::endl; + */ + + } + } + } + return 0; +} + +int MonleakDataProc::processData(unsigned link, unsigned *buffer, int buflen){ + //m_timer.Start(); + if(buflen==0)return 0; + int nL1A=0; + int module=m_linkToIndex[link]; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4BRecord rec; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isData()){ //includes empty record type + //should not happen + } else if(rec.isDataHeader()){ + //should not happen, either + }else if(rec.isServiceRecord()){ + //no service records + }else if(rec.isValueRecord()){ //val rec without addr rec + int value=rec.getValue()>>4; + + //std::cout<<"Link "<<link<<" value record! Value="<<std::hex<<rec.getValue()<<std::dec<<std::endl; + + fillHistogram(m_histo_occ[module], m_currentMaskStage, 1); + fillHistogram(m_histo_adc[module], m_currentMaskStage, value); + fillHistogram(m_histo_adc2[module], m_currentMaskStage, value*value); + + nL1A++; + }else if(rec.isAddressRecord()){ // address record + // Ignore address records + //std::cout<<"FE "<<m_info[module].getId()<<": Address record for "; + //if(rec.isGlobal())std::cout<<" global register "; + //else std::cout<<" shift register "; + //std::cout<<rec.getAddress()<<std::endl; + //std::cout<<"This should not happen."<<std::endl; + }else{ + std::cout<<"FE "<<m_info[module].getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + //return FEI4::FEI4ARecord::BadRecord; + return 0; + } + bytepointer+=3; + } + //m_timer.Stop(); + return nL1A; +} + +MonleakDataProc::MonleakDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit(0) { + std::cout<<"Monleak Data Proc"<<std::endl; + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + m_maskstageType=scanOptions->get<std::string>("maskStages"); //this is m_maskStageTotalSteps from PixScanBase_presetRCE.h + + std::cout<<"Initializing MonleakDataProc with maskstagetype = "<<m_maskstageType<<std::endl; + + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + char name[128]; + char title[128]; + + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + + RceHisto2d<int, int> *histoOcc; + RceHisto2d<int, int> *histoAdc; + RceHisto2d<int, int> *histoAdc2; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + + /* retrieve scan points - Vcal steps in this case */ + sprintf(name, "Mod_%d_nEvents", moduleId); + sprintf(title, "Module %d at %s Number of events", moduleId, moduleName.c_str()); + histoOcc=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true); + + sprintf(name, "Mod_%d_ADC", moduleId); + sprintf(title, "Module %d at %s ADC", moduleId, moduleName.c_str()); + histoAdc=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true); + + sprintf(name, "Mod_%d_ADC2", moduleId); + sprintf(title, "Module %d at %s ADC^2", moduleId, moduleName.c_str()); + histoAdc2=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true); + + if(m_info[module].getNFrontends()==1){ + histoOcc->setAxisTitle(1,"Column"); + histoAdc->setAxisTitle(1,"Column"); + histoAdc2->setAxisTitle(1,"Column"); + } + else{ + histoOcc->setAxisTitle(1,"FE*N_COL+Column"); + histoAdc->setAxisTitle(1,"FE*N_COL+Column"); + histoAdc2->setAxisTitle(1,"FE*N_COL+Column"); + } + histoOcc->setAxisTitle(0, "Row"); + histoAdc->setAxisTitle(0, "Row"); + histoAdc2->setAxisTitle(0, "Row"); + m_histo_occ.push_back(histoOcc); + m_histo_adc.push_back(histoAdc); + m_histo_adc2.push_back(histoAdc2); + + sprintf(name, "Mod_%d_Voltage", moduleId); + sprintf(title, "Module %d at %s Voltage", moduleId, moduleName.c_str()); + m_histo_norm.push_back(new RceHisto1d<float, float>(name, title, m_nPoints, 0, m_nPoints, true)); + m_histo_norm.back()->setAxisTitle(0, "Set point"); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +MonleakDataProc::~MonleakDataProc(){ + for (size_t module=0;module<m_histo_occ.size();module++){ + delete m_histo_occ[module]; + delete m_histo_adc[module]; + delete m_histo_adc2[module]; + delete m_histo_norm[module]; + } + +} + + +int MonleakDataProc::fillHistogram(RceHisto2d<int, int>* hist, int maskStage, int value){ + + if(m_maskstageType=="FEI4_26880"){ + int row = maskStage%PixelRegister::N_ROWS; + int col = maskStage/PixelRegister::N_ROWS; + + //now I need to write code to translate maskStage into row and col + //std::cout<<"I'm filling histogram row,col = "<<row<<" , "<<col<<" with val = "<<value<<std::endl; + hist->fill(row,col,value); + + } + else{ + return 0; + } + + return 1; + +} + diff --git a/rce/rcecalib/dataproc/MonleakDataProc.hh b/rce/rcecalib/dataproc/MonleakDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..a4c584cc6a1d931f06ff1c90aff87d5a5f5301fa --- /dev/null +++ b/rce/rcecalib/dataproc/MonleakDataProc.hh @@ -0,0 +1,32 @@ +#ifndef MONLEAKDATAPROC_HH +#define MONLEAKDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" +#include "rcecalib/util/RceHisto2d.cc" + +class MonleakDataProc: public AbsDataProc{ +public: + MonleakDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~MonleakDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + int fillHistogram(RceHisto2d<int, int>* hist, int maskStage, int value); + std::vector<RceHisto2d<int, int>*> m_histo_occ; + std::vector<RceHisto2d<int, int>*> m_histo_adc; + std::vector<RceHisto2d<int, int>*> m_histo_adc2; + std::vector<RceHisto1d<float, float>*> m_histo_norm; + AbsFit *m_fit; + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + std::string m_maskstageType; +}; + +#endif diff --git a/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.cc b/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..662cf6072070f11de80c3587facc14c074f17967 --- /dev/null +++ b/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.cc @@ -0,0 +1,219 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/MultiTrigNoiseDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/RceName.hh" +#include "rcecalib/dataproc/fit/FitFactory.cc" +#include "rcecalib/profiler/Profiler.hh" + + +int MultiTrigNoiseDataProc::fit(std::string fitfun) { + FitFactory<int, int> dfac; //template parameters are the type of the histogram and error + std::cout << "Running: " << fitfun << std::endl; + if(fitfun.size()>=6 && fitfun.substr(0,6)=="SCURVE") { + // m_fit=dfac.createFit("ScurveLikelihoodFloat",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + m_fit0=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ0,m_vcal,m_nTrigger, "Trig0"); + int opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + m_fit0->doFit(opt); + + m_fit1=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ1,m_vcal,m_nTrigger, "Trig1"); + opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + m_fit1->doFit(opt); + } + return 0; +} + +int MultiTrigNoiseDataProc::processData(unsigned link, unsigned *data, int size){ + m_timer.Start(); + // std::cout<<"Process data with size = "<<size<<std::endl; + int module=m_linkToIndex[link]; + + int l1id = 0; + int bcid = 0; + + for (int i=0;i<size;i++){ + FormattedRecord current(data[i]); + + + if (current.isHeader()){ + l1id = current.getL1id(); + bcid = current.getBxid(); + + + //old code for deciding which trigger data belongs to. Unfortunately, we've seen cases + //where the l1id order gets messed up, in which case this doesn't work. + /* + if (l1id != m_l1id_prev) { + // std::cout<<"new l1id = "<<l1id<<std::endl; + + if (m_nbcid!=m_nbcid_total){ + std::cout<<"VERY BAD last l1id had m_nbcid = "<<m_nbcid<<std::endl; + } + + m_l1id_which++; + if(m_l1id_which>=2){ + m_l1id_which=0; + } + + // m_l1id_prev = l1id; + // m_bcid_prev = bcid; + m_nbcid=0; + } + else{ + int exp_bcid = m_bcid_prev+1; + exp_bcid = exp_bcid%256; + if ( (bcid%256) != exp_bcid) { + std::cout<<"SCREAM! bcid changed from "<<m_bcid_prev<<" to "<<bcid<<std::endl; + } + } + */ + + //assume l1id starts counting from 1. Empirically, this seems to work. + if((l1id%2)==0){ + m_l1id_which=1; + } + else{ + m_l1id_which=0; + } + + + //printf("bcid : %d , l1id : %d , l1id_which: %d\n", bcid,l1id,m_l1id_which); + + // bcid = bcid-bcid_ref; + m_nbcid++; + //if( (bcid+1) != m_nbcid || m_nbcid > m_nbcid_total || bcid >= m_nbcid_total){ + // std::cout<<"SCREAM bcid = "<<bcid<<" ; m_nbcid = "<<m_nbcid<<std::endl; + // } + m_bcid_prev = bcid; + m_l1id_prev = l1id; + + } //if(isHeader) + + if (current.isData()){ + unsigned int chip=current.getFE(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + // unsigned int tot=current.getToT(); + // if(col==10 && row==10){ + // printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + // } + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns())) { + + RceHisto2d<int, int>* histo(0); + + if(m_l1id_which==0){ + histo = m_histo_occ0[module][m_currentBin]; + } + else if(m_l1id_which==1){ + histo = m_histo_occ1[module][m_currentBin]; + } + else{ + std::cout<<"This can't happen!"<<std::endl; + } + + if (chip==0) histo->incrementFast(row,col); + else if (chip<(unsigned)m_info[module].getNFrontends()) histo->incrementFast(row, chip*m_info[module].getNColumns()+col); + } + + } //if(isData) + + } //end for(int i=0; i<size; i++) + + m_timer.Stop(); + return 0; +} + +MultiTrigNoiseDataProc::MultiTrigNoiseDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit0(0),m_fit1(0),m_l1id_prev(-1),m_bcid_prev(0),m_nbcid(0),m_nbcid_total(0),m_l1id_which(-1) { + std::cout<<"MultiTrigNoise Data Proc"<<std::endl; + std::cout<<"Rce Number is "<<RceName::getRceNumber()<<std::endl; + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + m_nbcid_total = scanOptions->get<int>("trigOpt.nL1AperEvent"); + m_nbcid = m_nbcid_total; + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<int, int>* > vh; + m_histo_occ0.push_back(vh); + m_histo_occ1.push_back(vh); + + char name[128]; + char title[128]; + RceHisto2d<int, int> *histo0; + RceHisto2d<int, int> *histo1; + + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + std::cout<<"Creating Occupancy histograms."<<std::endl; + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + + sprintf(name,"Mod_%d_Trig0_Occupancy_Point_%03d", moduleId,point); + histo0=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true, false); + + sprintf(name,"Mod_%d_Trig1_Occupancy_Point_%03d", moduleId,point); + histo1=new RceHisto2d<int, int>(name,title,rows,0,rows,cols,0,cols, true, false); + + if(m_info[module].getNFrontends()==1){ + histo0->setAxisTitle(0,"Column"); + histo1->setAxisTitle(0,"Column"); + } + else{ + histo0->setAxisTitle(0,"FE*N_COL+Column"); + histo1->setAxisTitle(0,"FE*N_COL+Column"); + } + histo0->setAxisTitle(1, "Row"); + histo1->setAxisTitle(1, "Row"); + + m_histo_occ0[module].push_back(histo0); + m_histo_occ1[module].push_back(histo1); + + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } + m_timer.Reset(); +} + +MultiTrigNoiseDataProc::~MultiTrigNoiseDataProc(){ + if(m_fit0) delete m_fit0; + if(m_fit1) delete m_fit1; + + for (size_t module=0;module<m_histo_occ0.size();module++){ + for(size_t i=0;i<m_histo_occ0[module].size();i++){ + delete m_histo_occ0[module][i]; + delete m_histo_occ1[module][i]; + } + } + + m_timer.Print("MultiTrigNoiseDataProc"); +} + + diff --git a/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.hh b/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..b5ffb89410dee5a1bd0d910ebc9d8d667ccaefb7 --- /dev/null +++ b/rce/rcecalib/dataproc/MultiTrigNoiseDataProc.hh @@ -0,0 +1,40 @@ +#ifndef MULTITRIGNOISEDATAPROC_HH +#define MULTITRIGNOISEDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/profiler/Profiler.hh" + +class MultiTrigNoiseDataProc: public AbsDataProc{ +public: + MultiTrigNoiseDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~MultiTrigNoiseDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + std::vector<std::vector<RceHisto2d<int, int>*> > m_histo_occ0; + std::vector<std::vector<RceHisto2d<int, int>*> > m_histo_occ1; + + AbsFit *m_fit0; + AbsFit *m_fit1; + + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + + int m_l1id_prev; + int m_bcid_prev; + int m_nbcid; + int m_nbcid_total; + int m_l1id_which; + + Profiler::Timer m_timer; +}; + +#endif diff --git a/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.cc b/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..0002abbf1cd59f6c43a8e54294200c42b92927e2 --- /dev/null +++ b/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.cc @@ -0,0 +1,219 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/MultiTrigOccupancyDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/RceName.hh" +#include "rcecalib/dataproc/fit/FitFactory.cc" +#include "rcecalib/profiler/Profiler.hh" + + +int MultiTrigOccupancyDataProc::fit(std::string fitfun) { + FitFactory<char, char> dfac; //template parameters are the type of the histogram and error + std::cout << "Running: " << fitfun << std::endl; + if(fitfun.size()>=6 && fitfun.substr(0,6)=="SCURVE") { + // m_fit=dfac.createFit("ScurveLikelihoodFloat",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + m_fit0=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ0,m_vcal,m_nTrigger, "Trig0"); + int opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + m_fit0->doFit(opt); + + m_fit1=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ1,m_vcal,m_nTrigger, "Trig1"); + opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + m_fit1->doFit(opt); + } + return 0; +} + +int MultiTrigOccupancyDataProc::processData(unsigned link, unsigned *data, int size){ + m_timer.Start(); + // std::cout<<"Process data with size = "<<size<<std::endl; + int module=m_linkToIndex[link]; + + int l1id = 0; + int bcid = 0; + + for (int i=0;i<size;i++){ + FormattedRecord current(data[i]); + + + if (current.isHeader()){ + l1id = current.getL1id(); + bcid = current.getBxid(); + + + //old code for deciding which trigger data belongs to. Unfortunately, we've seen cases + //where the l1id order gets messed up, in which case this doesn't work. + /* + if (l1id != m_l1id_prev) { + // std::cout<<"new l1id = "<<l1id<<std::endl; + + if (m_nbcid!=m_nbcid_total){ + std::cout<<"VERY BAD last l1id had m_nbcid = "<<m_nbcid<<std::endl; + } + + m_l1id_which++; + if(m_l1id_which>=2){ + m_l1id_which=0; + } + + // m_l1id_prev = l1id; + // m_bcid_prev = bcid; + m_nbcid=0; + } + else{ + int exp_bcid = m_bcid_prev+1; + exp_bcid = exp_bcid%256; + if ( (bcid%256) != exp_bcid) { + std::cout<<"SCREAM! bcid changed from "<<m_bcid_prev<<" to "<<bcid<<std::endl; + } + } + */ + + //assume l1id starts counting from 1. Empirically, this seems to work. + if((l1id%2)==0){ + m_l1id_which=1; + } + else{ + m_l1id_which=0; + } + + + //printf("bcid : %d , l1id : %d , l1id_which: %d\n", bcid,l1id,m_l1id_which); + + // bcid = bcid-bcid_ref; + m_nbcid++; + //if( (bcid+1) != m_nbcid || m_nbcid > m_nbcid_total || bcid >= m_nbcid_total){ + // std::cout<<"SCREAM bcid = "<<bcid<<" ; m_nbcid = "<<m_nbcid<<std::endl; + // } + m_bcid_prev = bcid; + m_l1id_prev = l1id; + + } //if(isHeader) + + if (current.isData()){ + unsigned int chip=current.getFE(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + // unsigned int tot=current.getToT(); + // if(col==10 && row==10){ + // printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + // } + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns())) { + + RceHisto2d<char, char>* histo(0); + + if(m_l1id_which==0){ + histo = m_histo_occ0[module][m_currentBin]; + } + else if(m_l1id_which==1){ + histo = m_histo_occ1[module][m_currentBin]; + } + else{ + std::cout<<"This can't happen!"<<std::endl; + } + + if (chip==0) histo->incrementFast(row,col); + else if (chip<(unsigned)m_info[module].getNFrontends()) histo->incrementFast(row, chip*m_info[module].getNColumns()+col); + } + + } //if(isData) + + } //end for(int i=0; i<size; i++) + + m_timer.Stop(); + return 0; +} + +MultiTrigOccupancyDataProc::MultiTrigOccupancyDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit0(0),m_fit1(0),m_l1id_prev(-1),m_bcid_prev(0),m_nbcid(0),m_nbcid_total(0),m_l1id_which(-1) { + std::cout<<"MultiTrigOccupancy Data Proc"<<std::endl; + std::cout<<"Rce Number is "<<RceName::getRceNumber()<<std::endl; + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + m_nbcid_total = scanOptions->get<int>("trigOpt.nL1AperEvent"); + m_nbcid = m_nbcid_total; + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<char, char>* > vh; + m_histo_occ0.push_back(vh); + m_histo_occ1.push_back(vh); + + char name[128]; + char title[128]; + RceHisto2d<char, char> *histo0; + RceHisto2d<char, char> *histo1; + + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + std::cout<<"Creating Occupancy histograms."<<std::endl; + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + + sprintf(name,"Mod_%d_Trig0_Occupancy_Point_%03d", moduleId,point); + histo0=new RceHisto2d<char, char>(name,title,rows,0,rows,cols,0,cols, true, false); + + sprintf(name,"Mod_%d_Trig1_Occupancy_Point_%03d", moduleId,point); + histo1=new RceHisto2d<char, char>(name,title,rows,0,rows,cols,0,cols, true, false); + + if(m_info[module].getNFrontends()==1){ + histo0->setAxisTitle(0,"Column"); + histo1->setAxisTitle(0,"Column"); + } + else{ + histo0->setAxisTitle(0,"FE*N_COL+Column"); + histo1->setAxisTitle(0,"FE*N_COL+Column"); + } + histo0->setAxisTitle(1, "Row"); + histo1->setAxisTitle(1, "Row"); + + m_histo_occ0[module].push_back(histo0); + m_histo_occ1[module].push_back(histo1); + + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } + m_timer.Reset(); +} + +MultiTrigOccupancyDataProc::~MultiTrigOccupancyDataProc(){ + if(m_fit0) delete m_fit0; + if(m_fit1) delete m_fit1; + + for (size_t module=0;module<m_histo_occ0.size();module++){ + for(size_t i=0;i<m_histo_occ0[module].size();i++){ + delete m_histo_occ0[module][i]; + delete m_histo_occ1[module][i]; + } + } + + m_timer.Print("MultiTrigOccupancyDataProc"); +} + + diff --git a/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.hh b/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..28bf21361e16be76129f866d00f10da78823cc6e --- /dev/null +++ b/rce/rcecalib/dataproc/MultiTrigOccupancyDataProc.hh @@ -0,0 +1,40 @@ +#ifndef MULTITRIGOCCUPANCYDATAPROC_HH +#define MULTITRIGOCCUPANCYDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/profiler/Profiler.hh" + +class MultiTrigOccupancyDataProc: public AbsDataProc{ +public: + MultiTrigOccupancyDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~MultiTrigOccupancyDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ0; + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ1; + + AbsFit *m_fit0; + AbsFit *m_fit1; + + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + + int m_l1id_prev; + int m_bcid_prev; + int m_nbcid; + int m_nbcid_total; + int m_l1id_which; + + Profiler::Timer m_timer; +}; + +#endif diff --git a/rce/rcecalib/dataproc/NoiseOccupancyDataProc.cc b/rce/rcecalib/dataproc/NoiseOccupancyDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..99a1076c5636a7121abaaf75a741b8b3658f5c65 --- /dev/null +++ b/rce/rcecalib/dataproc/NoiseOccupancyDataProc.cc @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/NoiseOccupancyDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" + + +int NoiseOccupancyDataProc::processData(unsigned link, unsigned *data, int size){ + //std::cout<<"Process data of size "<<size<<std::endl; + if(m_counter++==0)usleep(1); + int module=m_linkToIndex[link]; + for (int i=0;i<size;i++){ + FormattedRecord current(data[i]); + if (current.isHeader()){ + unsigned l1id = current.getL1id(); + //printf("bcid : %x \n", bcid); + //printf("l1id : %x \n", l1id); + if (l1id != m_l1id_last[module]) + { + m_l1id_last[module] = l1id; + m_histo_eventCount[module]->incrementFast(0); + } + //printf("bcidafter : %x \n", bcid); + } + if (current.isData()){ + unsigned int chip=current.getFE(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + //unsigned int tot=current.getToT(); + //printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + if(chip==0){ + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns())) { + m_histo_occ[module]->incrementFast(col,row); + } + }else{ + if(chip<(unsigned)m_info[module].getNFrontends() && + (row<(unsigned)m_info[module].getNRows()) && + (col<(unsigned)m_info[module].getNColumns())) { + m_histo_occ[module]->incrementFast(chip*m_info[module].getNColumns()+col,row); + } + } + } + } + return 0; +} + +NoiseOccupancyDataProc::NoiseOccupancyDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif), m_counter(0) { + std::cout<<"Occupancy Data Proc"<<std::endl; + try{ //catch bad scan option parameters + m_l1id_last = new unsigned[m_configIF->getNmodules()]; + for(unsigned i=0;i<m_configIF->getNmodules();i++)m_l1id_last[i]=0xffff; + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + char name[128]; + char title[128]; + RceHisto2d<int, int> *histo; + RceHisto1d<int, int> *histo_ec; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + std::cout<<"Creating Occupancy histograms."<<std::endl; + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_NoiseOccupancy", moduleId); + histo=new RceHisto2d<int, int>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_occ.push_back(histo); + + sprintf(title,"Number of Events Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_nEvents", moduleId); + histo_ec=new RceHisto1d<int,int>(name, title, 1,0,1); + histo_ec->setAxisTitle(0, "n Event Bin"); + m_histo_eventCount.push_back(histo_ec); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +NoiseOccupancyDataProc::~NoiseOccupancyDataProc(){ + delete [] m_l1id_last; + for (size_t module=0;module<m_histo_occ.size();module++)delete m_histo_occ[module]; + for (size_t module=0;module<m_histo_occ.size();module++)delete m_histo_eventCount[module]; + +} + + diff --git a/rce/rcecalib/dataproc/NoiseOccupancyDataProc.hh b/rce/rcecalib/dataproc/NoiseOccupancyDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..4bac9302c8437ace103bb9ca1a2edb5ec2556a1c --- /dev/null +++ b/rce/rcecalib/dataproc/NoiseOccupancyDataProc.hh @@ -0,0 +1,25 @@ +#ifndef NOISEOCCUPANCYDATAPROC_HH +#define NOISEOCCUPANCYDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceHisto1d.cc" + +class NoiseOccupancyDataProc: public AbsDataProc{ +public: + NoiseOccupancyDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~NoiseOccupancyDataProc(); + int processData(unsigned link, unsigned *data, int size); + +protected: + + std::vector<RceHisto2d<int, int>*> m_histo_occ; + std::vector<RceHisto1d<int, int>*> m_histo_eventCount; + unsigned int *m_l1id_last; + unsigned short m_counter; +}; + +#endif diff --git a/rce/rcecalib/dataproc/OccupancyDataProc.cc b/rce/rcecalib/dataproc/OccupancyDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..7a9226b6dec04781690d6f7612eee0c3e6303180 --- /dev/null +++ b/rce/rcecalib/dataproc/OccupancyDataProc.cc @@ -0,0 +1,121 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/OccupancyDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/fit/FitFactory.cc" +#include "rcecalib/profiler/Profiler.hh" + + +int OccupancyDataProc::fit(std::string fitfun) { + FitFactory<char, char> dfac; //template parameters are the type of the histogram and error + std::cout << "Running: " << fitfun << std::endl; + if(fitfun.size()>=6 && fitfun.substr(0,6)=="SCURVE") { + // m_fit=dfac.createFit("ScurveLikelihoodFloat",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + m_fit=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + int opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + m_fit->doFit(opt); + } + return 0; +} + +int OccupancyDataProc::processData(unsigned link, unsigned *data, int size){ + m_timer.Start(); + // std::cout<<"Process data"<<std::endl; + int module=m_linkToIndex[link]; + RceHisto2d<char, char>* histo=m_histo_occ[module][m_currentBin]; + for (int i=0;i<size;i++){ + FormattedRecord current(data[i]); + /* + if (current.isHeader()){ + l1id = current.getL1id(); + bcid = current.getBxid(); + //printf("bcid : %x \n", bcid); + //printf("l1id : %x \n", l1id); + if (l1id != l1id_last) + { + l1id_last = l1id; + bcid_ref = bcid; + } + bcid = bcid-bcid_ref; + //printf("bcidafter : %x \n", bcid); + } + */ + if (current.isData()){ + unsigned int chip=current.getFE(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + //unsigned int tot=current.getToT(); + //printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns())) { + if(chip==0)histo->incrementFast(row,col); + else if(chip<(unsigned)m_info[module].getNFrontends())histo->incrementFast(row, chip*m_info[module].getNColumns()+col); + } + } + } + m_timer.Stop(); + return 0; +} + +OccupancyDataProc::OccupancyDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit(0) { + std::cout<<"Occupancy Data Proc"<<std::endl; + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<char, char>* > vh; + m_histo_occ.push_back(vh); + char name[128]; + char title[128]; + RceHisto2d<char, char> *histo; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + /* retrieve scan points - Vcal steps in this case */ + std::cout<<"Creating Occupancy histograms."<<std::endl; + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY"); + sprintf(name,"Mod_%d_Occupancy_Point_%03d", moduleId,point); + histo=new RceHisto2d<char, char>(name,title,rows,0,rows,cols,0,cols, true, false); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(1,"Column"); + else histo->setAxisTitle(1,"FE*N_COL+Column"); + histo->setAxisTitle(0, "Row"); + m_histo_occ[module].push_back(histo); + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } + m_timer.Reset(); +} + +OccupancyDataProc::~OccupancyDataProc(){ + if(m_fit) delete m_fit; + for (size_t module=0;module<m_histo_occ.size();module++) + for(size_t i=0;i<m_histo_occ[module].size();i++)delete m_histo_occ[module][i]; + + m_timer.Print("OccupancyDataProc"); +} + + diff --git a/rce/rcecalib/dataproc/OccupancyDataProc.hh b/rce/rcecalib/dataproc/OccupancyDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..5398a0a5372d3bfa79ea72cab6447ecaf0bb5e19 --- /dev/null +++ b/rce/rcecalib/dataproc/OccupancyDataProc.hh @@ -0,0 +1,29 @@ +#ifndef OCCUPANCYDATAPROC_HH +#define OCCUPANCYDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/profiler/Profiler.hh" + +class OccupancyDataProc: public AbsDataProc{ +public: + OccupancyDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~OccupancyDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ; + AbsFit *m_fit; + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + Profiler::Timer m_timer; +}; + +#endif diff --git a/rce/rcecalib/dataproc/PgpCosmicNwReceiver.cc b/rce/rcecalib/dataproc/PgpCosmicNwReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..a07b9e071f3cdaa62f1a4a908fc684eb06cea8ed --- /dev/null +++ b/rce/rcecalib/dataproc/PgpCosmicNwReceiver.cc @@ -0,0 +1,145 @@ +#include "dataproc/PgpCosmicNwReceiver.hh" +#include "dataproc/Channeldefs.hh" +#include "HW/RCDImaster.hh" +#include "eudaq/DataSender.hh" +#include "eudaq/DataSenderIF.hh" +//#include "rce/service/Cache.hh" +using namespace PgpTrans; + +#include <iostream> +#include "HW/Headers.hh" +#include <stdlib.h> +#include <boost/property_tree/ptree.hpp> +#include <boost/algorithm/string.hpp> +#include "HW/SerialIF.hh" +#include "config/FEI3/FECommands.hh" +#include "util/RceName.hh" + +PgpCosmicNwReceiver::PgpCosmicNwReceiver(AbsDataHandler* handler, boost::property_tree::ptree* scanOptions) + :AbsReceiver(handler),Receiver(), m_print(0), m_abs_sec(0), + m_bufferssend(0), m_senddiff(0){ + m_bad=0; + for (int i=0;i<32;i++)m_linksynch[i]=false; + RCDImaster::instance()->setReceiver(this); + std::cout<<"Created pgp cosmic network receiver"<<std::endl; + m_counter=0; + std::string name=scanOptions->get<std::string>("Name"); + std::cout<<"CosmicDataProc name "<<name<<std::endl; + std::string prefix("CosmicGui"); + assert(name.compare(0, prefix.size(), prefix) == 0) ; + // CosmicGui asks to send back over TCP + // parse string of form: CosmicGui|01168|tcp://127.56.2.6:4500 + std::vector<std::string> strs; + boost::split(strs, name, boost::is_any_of("|")); + //m_runNo=atoi(strs[1].c_str()); + name = strs[2]; + std::cout<<"TCP to " << name <<std::endl; + m_ds = new eudaq::DataSender(std::string("DataSender"), std::string("CosmicGuiDataSender")); + DataSenderIF::setDataSender(m_ds); + try + { + m_ds->Connect(name); + } + catch (const std::exception & ex) + { + // Need to do sensible things here, maybe catch different types of exceptions. + std::cout << "DataSender could not connect. Exception says: \n " << ex.what() << std::endl; + } + m_sendbuffer=new unsigned char[1024*1024]; + m_bufferpointer=0; +} +PgpCosmicNwReceiver::~PgpCosmicNwReceiver(){ + std::cout<<"Received "<<std::dec<<m_counter<<" buffers in previous run."<<std::endl; + std::cout<<"Sent "<<std::dec<<m_bufferssend<<" buffers in previous run."<<std::endl; + delete m_ds; + delete [] m_sendbuffer; + } +void PgpCosmicNwReceiver::receive(PgpTrans::PgpData *pgpdata){ + int link=pgpdata->header[2]; + if(link==PGPACK){ + if(m_bufferpointer>0){ //sweep + DataSenderIF::SendEvent(m_sendbuffer, m_bufferpointer); + m_abs_sec=(unsigned int)time(0); + m_bufferpointer=0; + } + return; + } + m_counter++; + if((m_counter&0xffff)==0)usleep(1); //give external commands a chance to execute from time to time + unsigned size=pgpdata->payloadSize; + unsigned* data=pgpdata->payload; + //std::cout<<"Link "<<link<<" Size ="<<size<<std::endl; + bool marker=pgpdata->header[6]&0x80; + if(m_linksynch[link]==true) { + if (marker==false){ + if(m_print>0){ + if(link==TDCREADOUT)std::cout<<"Ignoring TDC link L1A: "<<(data[1]>>24)<<std::endl; + else { + std::cout<<"Ignoring Link "<<link<<std::endl; + } + m_print--; + } + m_tossed[link]++; + return ; + } + m_linksynch[link]=false; + //if(marker)std::cout<<"Markerevent"<<std::endl; + std::cout<<"Tossed "<<m_tossed[link]<<" fragments for link "<<link<<std::endl; + } + if(marker){ + link|=1<<MARKERPOS; + } + + int rce = RceName::getRceNumber(); + rce=rce&RCEMASK; + //std::cout<<"link without rce = "<<link<<std::endl; + link |= (rce << RCEPOS); + //std::cout<<"link with rce = "<<link<<std::endl; + + //link is a 16-bit number with the following format: + //xxxxrrrr rrrmllll + //where the x's are currently unused, rrrrrrr is the rce number, + //m is a marker (used for resynching), and llll is the outlink number + + //std::cout<<"Payloadsize "<<payloadSize<<std::endl; + unsigned short* se=(unsigned short*)&m_sendbuffer[m_bufferpointer]; + int bytesize=size*sizeof(unsigned); + se[0]=bytesize; + se[1]=link; +#ifdef __rtems__ //swap + se[0]=se[0]<<8|se[0]>>8; + se[1]=se[1]<<8|se[1]>>8; +#endif + memcpy(&m_sendbuffer[m_bufferpointer+4], data, bytesize); + m_bufferpointer+=bytesize+4; + unsigned abs_sec=(int)time(0); + if(m_bufferpointer>9000 || abs_sec>m_abs_sec){ //send data if buffer full or timeout or link==9(sweep) + DataSenderIF::SendEvent(m_sendbuffer, m_bufferpointer); + m_abs_sec=abs_sec; + m_bufferpointer=0; + } +} +void PgpCosmicNwReceiver::resynch(){ + std::cout<<"Resynchronizing"<<std::endl; + int serstat; + serstat=SerialIF::sendCommand(4);//pause run + assert(serstat==0); + usleep(100000); + // set synch flags for everybody + for (int i=0;i<32;i++)m_linksynch[i]=true; + for (int i=0;i<32;i++)m_tossed[i]=0; + m_print=0; + //ECR/BCR + BitStream *bs=new BitStream; + BitStreamUtils::prependZeros(bs); + FEI3::FECommands::sendECR(bs); + FEI3::FECommands::sendBCR(bs); + SerialIF::send(bs,SerialIF::WAITFORDATA); + delete bs; + //clear send buffer + m_abs_sec=(unsigned int)time(0); + m_bufferpointer=0; + serstat=SerialIF::sendCommand(7);//resume run and post marker + assert(serstat==0); + std::cout<<"Resumed"<<std::endl; +} diff --git a/rce/rcecalib/dataproc/PgpCosmicNwReceiver.hh b/rce/rcecalib/dataproc/PgpCosmicNwReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..b76f877c124b362e7bc9d537dc251f256649d929 --- /dev/null +++ b/rce/rcecalib/dataproc/PgpCosmicNwReceiver.hh @@ -0,0 +1,33 @@ +#ifndef PGPCOSMICNWRECEIVER_HH +#define PGPCOSMICNWRECEIVER_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "dataproc/AbsReceiver.hh" +#include "HW/Receiver.hh" +#include <iostream> + + +namespace eudaq{ + class DataSender; +} + +class PgpCosmicNwReceiver: public AbsReceiver, public PgpTrans::Receiver{ +public: + PgpCosmicNwReceiver(AbsDataHandler* handler, boost::property_tree::ptree* scanOptions); + virtual ~PgpCosmicNwReceiver(); + void receive(PgpTrans::PgpData *pgpdata); + void resynch(); +private: + unsigned* m_buffer; + unsigned m_counter; + bool m_linksynch[32]; + int m_tossed[32]; + int m_print; + eudaq::DataSender *m_ds; + unsigned char *m_sendbuffer; + int m_bufferpointer; + unsigned m_abs_sec; + unsigned m_bufferssend, m_senddiff; + unsigned m_oldl1, m_oldbx, m_firstbx, m_bad; +}; +#endif diff --git a/rce/rcecalib/dataproc/PgpCosmicReceiver.cc b/rce/rcecalib/dataproc/PgpCosmicReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..fdaaef91767b72320d75f591bad3aaa2e131d781 --- /dev/null +++ b/rce/rcecalib/dataproc/PgpCosmicReceiver.cc @@ -0,0 +1,63 @@ +#include "rcecalib/dataproc/PgpCosmicReceiver.hh" +#include "rcecalib/HW/RCDImaster.hh" +#include <iostream> +#include "rcecalib/HW/Headers.hh" +#include "namespace_aliases.hh" + +PgpCosmicReceiver::PgpCosmicReceiver(AbsDataHandler* handler):AbsReceiver(handler),PgpTrans::Receiver(){ + PgpTrans::RCDImaster::instance()->setReceiver(this); + std::cout<<"Created pgp cosmic receiver"<<std::endl; + m_buffer=new unsigned[2048]; + m_counter=0; +} + +void PgpCosmicReceiver::receive(PgpTrans::PgpData *pgpdata){ + int link=pgpdata->header[2]&0xf; + if(link==9)return; + m_counter++; + //std::cout<<"Received data from link "<<link<<std::endl; + //printf("Link %d Payloadsize %d Headersize headerSize %d\n",link, payloadSize,headerSize); + unsigned size=pgpdata->payloadSize; + if (size==0)return; //typically handshake from serialization command + if(size>4096)std::cout<<"Large payload "<<size<<std::endl; + unsigned* data; + // if(link==10&&payloadSize!=0)std::cout<<"Channel 10 payloadsize= "<<payloadSize<<std::endl; + //if(link!=10){ + //data=(unsigned*)tds->header(); + //size=headerSize/sizeof(unsigned); + //for (int i=0;i<size;i++){ + //std::cout<<"Header "<<i<<": "<<std::hex<<data[i]<<std::dec<<", "; + //} + //std::cout<<std::endl; + //data=(unsigned*)tds->payload(); + //size=payloadSize/sizeof(unsigned)+ (payloadSize%4!=0); + //for (int i=0;i<size;i++){ + // std::cout<<"Data "<<i<<": "<<std::hex<<data[i]<<std::dec<<std::endl; + //} + //return; + data=pgpdata->payload; + bool marker=pgpdata->header[6]&0x80; + if(marker){ + link|=1<<4; + } + //std::cout<<"Payloadsize "<<payloadSize<<std::endl; + //unsigned char* payloadc=(unsigned char*)tds->payload(); +#ifdef SWAP_DATA + //byte swap data + unsigned* ptr = data; + unsigned* end = ptr+size; + unsigned *swapped=new(m_buffer) unsigned[size]; + unsigned *sw=swapped; + //for (int i=0;i<8;i++)std::cout<<std::hex<<header[i]<<std::endl; + while (ptr<end) { + unsigned tmp = *ptr; + *sw = (tmp<<16) | (tmp >>16); + ptr++; + sw++; + } + m_handler->handle(link,swapped,size); + #else + m_handler->handle(link,data,size); + //std::cout<<"Parsing done"<<std::endl; + #endif +} diff --git a/rce/rcecalib/dataproc/PgpCosmicReceiver.hh b/rce/rcecalib/dataproc/PgpCosmicReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..34bef068429b86599cbb2ed87ffd36af03ff2982 --- /dev/null +++ b/rce/rcecalib/dataproc/PgpCosmicReceiver.hh @@ -0,0 +1,21 @@ +#ifndef PGPCOSMICRECEIVER_HH +#define PGPCOSMICRECEIVER_HH + +#include "rcecalib/dataproc/AbsReceiver.hh" +#include "rcecalib/HW/Receiver.hh" +#include <iostream> +#include "namespace_aliases.hh" + +class PgpCosmicReceiver: public AbsReceiver, public PgpTrans::Receiver{ +public: + PgpCosmicReceiver(AbsDataHandler* handler); + virtual ~PgpCosmicReceiver(){ + std::cout<<"Received "<<std::dec<<m_counter<<" buffers in previous run."<<std::endl; + delete [] m_buffer; + } + void receive(PgpTrans::PgpData *pgpdata); +private: + unsigned* m_buffer; + unsigned m_counter; +}; +#endif diff --git a/rce/rcecalib/dataproc/PgpReceiver.cc b/rce/rcecalib/dataproc/PgpReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..153b82dfa54a9793b7204fc9bcc31a78a231448a --- /dev/null +++ b/rce/rcecalib/dataproc/PgpReceiver.cc @@ -0,0 +1,54 @@ +#include "rcecalib/dataproc/PgpReceiver.hh" +#include "rcecalib/HW/RCDImaster.hh" +#include <iostream> +#include "rcecalib/HW/Headers.hh" +#include "namespace_aliases.hh" + +PgpReceiver::PgpReceiver(AbsDataHandler* handler):AbsReceiver(handler),PgpTrans::Receiver(){ + PgpTrans::RCDImaster::instance()->setReceiver(this); + std::cout<<"Created pgp receiver"<<std::endl; + m_buffer=new unsigned[2048]; + m_counter=0; + m_timer.Reset(); +} +PgpReceiver::~PgpReceiver(){ + delete [] m_buffer; + std::cout<<"Received "<<m_counter<<" buffers in previous run"<<std::endl; + // m_timer.Print("PgpReceiver"); +} + +void PgpReceiver::receive(PgpTrans::PgpData *pgpdata){ + //int link=0; + int link=pgpdata->header[2]&0xf; + //std::cout<<"Link is "<<link<<std::endl; + int size=pgpdata->payloadSize; + if (size==0)return; //handshake from serialization command + //printf("Payloadsize %d Headersize %d\n",pgpdata->payloadSize,pgpdata->headerSize); + unsigned* data; + data=pgpdata->payload; + +#ifdef SWAP_DATA + //byte swap data + #warning Data swapping turned on + unsigned* ptr = data; + unsigned* end = ptr+size; + unsigned *swapped=new(m_buffer) unsigned[size]; + unsigned *sw=swapped; + //for (int i=0;i<8;i++)std::cout<<std::hex<<header[i]<<std::endl; + while (ptr<end) { + unsigned tmp = *ptr; + *sw = (tmp<<16) | (tmp >>16); + //*ptr = (tmp<<16) | (tmp >>16); + ptr++; + sw++; + } + m_handler->handle(link,swapped,size); +#else + m_counter++; + //m_timer.Start(); + m_handler->handle(link,data,size); + //m_timer.Stop(); +#endif + + //std::cout<<"Parsing done"<<std::endl; +} diff --git a/rce/rcecalib/dataproc/PgpReceiver.hh b/rce/rcecalib/dataproc/PgpReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..19afbd7b456207bf27f34749a079b9160db0dd3a --- /dev/null +++ b/rce/rcecalib/dataproc/PgpReceiver.hh @@ -0,0 +1,20 @@ +#ifndef PGPRECEIVER_HH +#define PGPRECEIVER_HH + +#include "rcecalib/dataproc/AbsReceiver.hh" +#include "rcecalib/HW/Receiver.hh" +#include "rcecalib/profiler/Profiler.hh" + + + +class PgpReceiver: public AbsReceiver, public PgpTrans::Receiver{ +public: + PgpReceiver(AbsDataHandler* handler); + virtual ~PgpReceiver(); + void receive(PgpTrans::PgpData* pgpdata); +private: + unsigned* m_buffer; + unsigned m_counter; + Profiler::Timer m_timer; +}; +#endif diff --git a/rce/rcecalib/dataproc/ProducerIF.hh b/rce/rcecalib/dataproc/ProducerIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..8696fe804812bff9d98738df83a54980e3177929 --- /dev/null +++ b/rce/rcecalib/dataproc/ProducerIF.hh @@ -0,0 +1,18 @@ +#ifndef PRODUCERIF_HH +#define PRODUCERIF_HH + +namespace eudaq{ + class Event; + class Producer; +} + +class ProducerIF{ +public: + static void SendEvent(eudaq::Event *ev); + static void setProducer(eudaq::Producer* producer); +private: + eudaq::Producer *m_producer; + +}; + +#endif diff --git a/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.cc b/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..b45118048f302f9e0f693afef9eaf17841529458 --- /dev/null +++ b/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.cc @@ -0,0 +1,154 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/RawFei4OccupancyDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/fit/FitFactory.cc" +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" + +int RawFei4OccupancyDataProc::fit(std::string fitfun) { + + FitFactory<char, char> dfac; //template parameters are the type of the histogram and error + std::cout << "Running: " << fitfun << std::endl; + if(fitfun.size()>=6 && fitfun.substr(0,6)=="SCURVE") { + // m_fit=dfac.createFit("ScurveLikelihoodFloat",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + m_fit=dfac.createFit("ScurveLikelihoodFastInt",m_configIF, m_histo_occ,m_vcal,m_nTrigger); + int opt=0; + if(fitfun.size()>=13&&fitfun.substr(7,6)=="NOCONV")opt=AbsFit::NOCONV; + if(fitfun.size()>=12&&fitfun.substr(7,5)=="XTALK")opt=AbsFit::XTALK; + std::cout<<"Scurve option is "<<opt<<std::endl; + m_fit->doFit(opt); + } + return 0; +} + +int RawFei4OccupancyDataProc::processData(unsigned link, unsigned *buffer, int buflen){ + //m_timer.Start(); + if(m_counter++==0)usleep(1); + if(buflen==0)return 0; + int nL1A=0; + int module=m_linkToIndex[link]; + RceHisto2d<char, char>* histo=m_histo_occ[module][m_currentBin]; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4ARecord rec; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isData()){ //includes empty record type + //there are potentially 2 hits in one data record + //fprintf(m_flog, "%x\n", rec.getUnsigned()); + if(((rec.getTotBottom())>>1)!=0x7){ //above threshold + unsigned int row=rec.getRow()-1; + unsigned int col=rec.getColumn()-1; + if(row<N_ROW && col<N_COL) { + histo->incrementFast(row,col); + //std::cout<<"Hit at "<<row<<" "<<col<<std::endl; + } + } + if(((rec.getTotTop())>>1)!=0x7){ //above threshold + unsigned int row=rec.getRow(); + unsigned int col=rec.getColumn()-1; + if(row<N_ROW && col<N_COL) { + histo->incrementFast(row,col); + //std::cout<<"Hit at "<<row<<" "<<col<<std::endl; + } + } + } else if(rec.isDataHeader()){ + //fprintf(m_flog, "%x\n", rec.getUnsigned()); + nL1A++; + }else if(rec.isServiceRecord()){ + unsigned int moduleId=m_info[module].getId(); + //if(rec.getErrorCode()!=10 && (rec.getErrorCode()!=16 || (rec.getErrorCount()&0x200)) ) + printf("Service record FE %d . Error code: %d. Count: %d \n", moduleId, rec.getErrorCode(), rec.getErrorCount()); + if( rec.getErrorCode()<32)m_errhist[module]->fill(rec.getErrorCode(), rec.getErrorCount()); + //header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + // printf("Value record: %04x.\n",rec.getValue()); + }else if(rec.isAddressRecord()){ // address record + std::cout<<"FE "<<m_info[module].getId()<<": Address record for "; + if(rec.isGlobal())std::cout<<" global register "; + else std::cout<<" shift register "; + std::cout<<rec.getAddress()<<std::endl; + std::cout<<"This should not happen."<<std::endl; + }else{ + std::cout<<"FE "<<m_info[module].getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + //return FEI4::FEI4ARecord::BadRecord; + return 0; + } + bytepointer+=3; + } + //m_timer.Stop(); + return nL1A; +} + +RawFei4OccupancyDataProc::RawFei4OccupancyDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit(0), m_counter(0) { + std::cout<<"Raw FEI4 Occupancy Data Proc"<<std::endl; + //m_flog=fopen("/nfs/dbg.txt","w"); + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<char, char>* > vh; + m_histo_occ.push_back(vh); + char name[128]; + char title[128]; + RceHisto2d<char, char> *histo; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + sprintf(name, "Mod_%d_FEI4_Errors_Proc", moduleId); + sprintf(title, "Module %d at %s FEI4 Errors", moduleId, moduleName.c_str()); + m_errhist.push_back(new RceHisto1d<int, int>(name, title, 32, -.5, 31.5)); + std::cout<<"Creating Occupancy histograms."<<std::endl; + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Occupancy_Point_%03d", moduleId,point); + histo=new RceHisto2d<char, char>(name,title,rows,0,rows,cols,0,cols, true); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(1,"Column"); + else histo->setAxisTitle(1,"FE*N_COL+Column"); + histo->setAxisTitle(0, "Row"); + m_histo_occ[module].push_back(histo); + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } + //m_timer.Reset(); +} + +RawFei4OccupancyDataProc::~RawFei4OccupancyDataProc(){ + //fclose(m_flog); + if(m_fit) delete m_fit; + for (size_t module=0;module<m_histo_occ.size();module++){ + delete m_errhist[module]; + for(size_t i=0;i<m_histo_occ[module].size();i++){ + delete m_histo_occ[module][i]; + } + } + + //m_timer.Print("RawFei4OccupancyDataProc"); +} + + diff --git a/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.hh b/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..52989c327a0b008179c182d9ad954fec0e57299a --- /dev/null +++ b/rce/rcecalib/dataproc/RawFei4OccupancyDataProc.hh @@ -0,0 +1,34 @@ +#ifndef RAWFEI4OCCUPANCYDATAPROC_HH +#define RAWFEI4OCCUPANCYDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceHisto1d.cc" +#include "rcecalib/profiler/Profiler.hh" +#include <stdio.h> + +class RawFei4OccupancyDataProc: public AbsDataProc{ +public: + RawFei4OccupancyDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~RawFei4OccupancyDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + enum FEI4{N_ROW=336, N_COL=80}; + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ; + std::vector<RceHisto1d<int, int>*> m_errhist; + AbsFit *m_fit; + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; + Profiler::Timer m_timer; + unsigned short m_counter; + //FILE* m_flog; +}; + +#endif diff --git a/rce/rcecalib/dataproc/RegularScanDataHandler.cc b/rce/rcecalib/dataproc/RegularScanDataHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..f2842498fb58999f3c730c259cbd2f1996637d86 --- /dev/null +++ b/rce/rcecalib/dataproc/RegularScanDataHandler.cc @@ -0,0 +1,108 @@ +#include "rcecalib/dataproc/RegularScanDataHandler.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <boost/property_tree/ptree.hpp> +#include <iostream> +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/util/DataCond.hh" + +RegularScanDataHandler::RegularScanDataHandler(AbsDataProc* dataproc, + DataCond& datacond, + ConfigIF* cif, + boost::property_tree::ptree* scanOptions) + :AbsDataHandler(dataproc, datacond, cif){ + m_nL1AperEv=scanOptions->get<int>("trigOpt.nL1AperEvent"); + int ntrigpergroup=scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + if(ntrigpergroup!=0)m_nL1AperEv*=ntrigpergroup; + std::cout<<"Number of expected triggers is "<<m_nL1AperEv<<std::endl; + m_L1Acounters.clear(); + int maxlink=0; + m_nModules=m_configIF->getNmodules(); + for (int i=0;i<m_nModules;i++){ + m_L1Acounters.push_back(0); + if(m_configIF->getModuleInfo(i).getOutLink()>maxlink)maxlink=m_configIF->getModuleInfo(i).getOutLink(); + m_formatter.push_back(m_configIF->getModuleInfo(i).getFormatter()); + } + maxlink++; + m_linkToIndex=new int[maxlink]; + for (unsigned int i=0;i<m_configIF->getNmodules();i++){ + m_linkToIndex[m_configIF->getModuleInfo(i).getOutLink()]=i; + } + m_parsedData=new unsigned[16384]; + //m_timer.Reset(); +} + +RegularScanDataHandler::~RegularScanDataHandler(){ + delete [] m_parsedData; + delete [] m_linkToIndex; + // m_timer.Print("RegularScanDataHandler"); +} + +void RegularScanDataHandler::timeoutOccurred(){ + //print out which modules timed out + for (int i=0;i<m_nModules;i++){ + if (m_L1Acounters[i]<m_nL1AperEv){ + std::cout<<m_configIF->getModuleInfo(i).getId()<<std::endl; + } + } + resetL1counters(); +} + +void RegularScanDataHandler::resetL1counters(){ + assert(m_nModules==(int)m_L1Acounters.size()); + for (int i=0;i<m_nModules;i++){ + m_L1Acounters[i]=0; + } +} + +void RegularScanDataHandler::handle(unsigned link, unsigned *data, int size){ + // nL1A contains the number of L1A in the data chunk + //std::cout<<"Data from Link "<<link<<std::endl; + int nL1A=0; + int parsedsize=0; + int retval=m_formatter[m_linkToIndex[link]]->decode(data,size,m_parsedData, parsedsize, nL1A); + //std::cout<<"parser"<<retval<<" "<<size<<std::endl; + //if(size==448){ + if(retval!=0){ + std::cout<<"Parser error for link "<<link<<": Data size "<<size<<" number of triggers "<<nL1A<<std::endl; + // if(nL1A==16){ + for (int i=0;i<size;i++)std::cout<<std::hex<<data[i]<<std::endl; + std::cout<<std::dec; + // m_scan->pause(); + //} + } + if(parsedsize!=0){ + m_dataProc->processData(link, m_parsedData, parsedsize); + } + // std::cout<<nL1A<<" events."<<std::endl; + // std::cout<<"Expecting "<<m_nL1AperEv<<std::endl; + //for (int i=size-4;i<size;i++)std::cout<<std::hex<<data[i]<<std::endl; + //m_timer.Start(); + if(nL1A!=0){ + omni_mutex_lock ml(m_nL1Alock); + //assert(m_linkToIndex[link]<m_L1Acounters.size()); + m_L1Acounters[m_linkToIndex[link]]+=nL1A; + // std::cout<<m_L1Acounters[m_linkToIndex[link]]<<" events so far."<<std::endl; + bool done=true; + //check if the event is complete. + for (int i=0;i<m_nModules;i++){ + //assert(m_L1Acounters[i]<=m_nL1AperEv); + if(m_L1Acounters[i]>m_nL1AperEv)std::cout<<m_L1Acounters[i]<<" L1Atriggers"<<std::endl; + if (m_L1Acounters[i]<m_nL1AperEv){ + done=false; + break; + } + } + if(done==true){ + //std::cout<<"Restarting scan "<<std::endl; + resetL1counters(); + // Next trigger + // m_scan->stopWaiting(); + omni_mutex_lock pl( m_dataCond.mutex ); + if(m_dataCond.waitingForData==true)m_dataCond.cond.signal(); + else std::cout<<"Scan was not waiting for data!"<<std::endl; + } + } + //m_timer.Stop(); +} diff --git a/rce/rcecalib/dataproc/RegularScanDataHandler.hh b/rce/rcecalib/dataproc/RegularScanDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..82199400103fb086d6b6a3492606064a2133f249 --- /dev/null +++ b/rce/rcecalib/dataproc/RegularScanDataHandler.hh @@ -0,0 +1,31 @@ +#ifndef REGULARSCANDATAHANDLER_HH +#define REGULARSCANDATAHANDLER_HH + +#include <vector> +#include <assert.h> + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/profiler/Profiler.hh" + +class AbsFormatter; +class DataCond; + +class RegularScanDataHandler: public AbsDataHandler{ +public: + RegularScanDataHandler(AbsDataProc* dataproc, DataCond& datacond, ConfigIF* cif, boost::property_tree::ptree* scanOptions); + virtual ~RegularScanDataHandler(); + void handle(unsigned link, unsigned* data, int size); + void timeoutOccurred(); + void resetL1counters(); +protected: + int m_nL1AperEv; + omni_mutex m_nL1Alock; + std::vector<int> m_L1Acounters; + int m_nModules; + int *m_linkToIndex; + unsigned *m_parsedData; + std::vector<AbsFormatter*> m_formatter; + Profiler::Timer m_timer; +}; +#endif diff --git a/rce/rcecalib/dataproc/RegularScanRawDataHandler.cc b/rce/rcecalib/dataproc/RegularScanRawDataHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..03061b1ee71ecb08271a5932740f87588ddcb0f9 --- /dev/null +++ b/rce/rcecalib/dataproc/RegularScanRawDataHandler.cc @@ -0,0 +1,91 @@ +#include "rcecalib/dataproc/RegularScanRawDataHandler.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/config/AbsFormatter.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <boost/property_tree/ptree.hpp> +#include <iostream> +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/util/DataCond.hh" + +RegularScanRawDataHandler::RegularScanRawDataHandler(AbsDataProc* dataproc, + DataCond& datacond, + ConfigIF* cif, + boost::property_tree::ptree* scanOptions) + :AbsDataHandler(dataproc, datacond, cif){ + std::cout<<"Regular raw data handler"<<std::endl; + m_nL1AperEv=scanOptions->get<int>("trigOpt.nL1AperEvent"); + int ntrigpergroup=scanOptions->get<int>("trigOpt.nTriggersPerGroup"); + if(ntrigpergroup!=0)m_nL1AperEv*=ntrigpergroup; + std::cout<<"Number of expected triggers is "<<m_nL1AperEv<<std::endl; + int maxlink=0; + m_nModules=m_configIF->getNmodules(); + m_L1Acounters=new int[m_nModules]; + resetL1counters(); + for (int i=0;i<m_nModules;i++){ + if(m_configIF->getModuleInfo(i).getOutLink()>maxlink)maxlink=m_configIF->getModuleInfo(i).getOutLink(); + } + maxlink++; + m_linkToIndex=new int[maxlink]; + for (unsigned int i=0;i<m_configIF->getNmodules();i++){ + m_linkToIndex[m_configIF->getModuleInfo(i).getOutLink()]=i; + } + //m_timer.Reset(); + m_counter=0; +} + +RegularScanRawDataHandler::~RegularScanRawDataHandler(){ + delete [] m_L1Acounters; + delete [] m_linkToIndex; + // m_timer.Print("RegularScanRawDataHandler"); +} + +void RegularScanRawDataHandler::timeoutOccurred(){ + //print out which modules timed out + for (int i=0;i<m_nModules;i++){ + if (m_L1Acounters[i]<m_nL1AperEv){ + std::cout<<m_configIF->getModuleInfo(i).getId()<<std::endl; + } + } + resetL1counters(); +} + +void RegularScanRawDataHandler::resetL1counters(){ + for (int i=0;i<m_nModules;i++){ + m_L1Acounters[i]=0; + } +} + +void RegularScanRawDataHandler::handle(unsigned link, unsigned *data, int size){ + // nL1A contains the number of L1A in the data chunk + //std::cout<<"Data from Link "<<link<<std::endl; + //m_timer.Start(); + int nL1A= m_dataProc->processData(link, data, size); + //if(nL1A==0){ + // std::cout<<"Size is "<<size<<std::endl; + // int msize=size>100? 100 : size; + // for(int a=0;a<msize;a++)printf("%08x\n",data[a]); + //} + //m_timer.Stop(); + //std::cout<<nL1A<<" events."<<std::endl; + // std::cout<<"Expecting "<<m_nL1AperEv<<std::endl; + //for (int i=size-4;i<size;i++)std::cout<<std::hex<<data[i]<<std::endl; + m_L1Acounters[m_linkToIndex[link]]+=nL1A; + // std::cout<<m_L1Acounters[m_linkToIndex[link]]<<" events so far."<<std::endl; + bool done=true; + //check if the event is complete. + for (int i=0;i<m_nModules;i++){ + //if(m_L1Acounters[i]>m_nL1AperEv)std::cout<<m_L1Acounters[i]<<" L1Atriggers"<<std::endl; + if (m_L1Acounters[i]<m_nL1AperEv){ + done=false; + break; + } + } + if(done){ + //std::cout<<"Restarting scan "<<std::endl; + resetL1counters(); + // Next trigger + omni_mutex_lock pl( m_dataCond.mutex ); + if(m_dataCond.waitingForData==true)m_dataCond.cond.signal(); + else std::cout<<"Scan was not waiting for data!"<<std::endl; + } +} diff --git a/rce/rcecalib/dataproc/RegularScanRawDataHandler.hh b/rce/rcecalib/dataproc/RegularScanRawDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..6bef5f8783a602268e3a59d0987a8a66d895b44f --- /dev/null +++ b/rce/rcecalib/dataproc/RegularScanRawDataHandler.hh @@ -0,0 +1,29 @@ +#ifndef REGULARSCANRAWDATAHANDLER_HH +#define REGULARSCANRAWDATAHANDLER_HH + +#include <omnithread.h> +#include <assert.h> + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/profiler/Profiler.hh" + +class AbsFormatter; +class DataCond; + +class RegularScanRawDataHandler: public AbsDataHandler{ +public: + RegularScanRawDataHandler(AbsDataProc* dataproc, DataCond& datacond, ConfigIF* cif, boost::property_tree::ptree* scanOptions); + virtual ~RegularScanRawDataHandler(); + inline void handle(unsigned link, unsigned* data, int size); + void timeoutOccurred(); + inline void resetL1counters(); +protected: + int m_nL1AperEv; + int* m_L1Acounters; + int m_nModules; + int *m_linkToIndex; + Profiler::Timer m_timer; + int m_counter; +}; +#endif diff --git a/rce/rcecalib/dataproc/SNDataProc.cc b/rce/rcecalib/dataproc/SNDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..68f55d4b5c17fbfeaabce216f884fcdc6938208d --- /dev/null +++ b/rce/rcecalib/dataproc/SNDataProc.cc @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/SNDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/config/FEI4/FEI4BRecord.hh" + +int SNDataProc::fit(std::string fitfun) { + return 0; +} + +int SNDataProc::processData(unsigned link, unsigned *buffer, int buflen){ + //m_timer.Start(); + if(buflen==0)return 0; + int nL1A=0; + int module=m_linkToIndex[link]; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4BRecord rec; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isData()){ //includes empty record type + //should not happen + } else if(rec.isDataHeader()){ + //should not happen, either + }else if(rec.isServiceRecord()){ + //no service records + }else if(rec.isValueRecord()){ //val rec without addr rec + int value=rec.getValue(); + std::cout<<"Value record! Value="<<rec.getValue()<<std::endl; + m_histo_occ[module]->set(0, value); + nL1A++; + }else if(rec.isAddressRecord()){ // address record + // Ignore address records + //std::cout<<"FE "<<m_info[module].getId()<<": Address record for "; + //if(rec.isGlobal())std::cout<<" global register "; + //else std::cout<<" shift register "; + //std::cout<<rec.getAddress()<<std::endl; + //std::cout<<"This should not happen."<<std::endl; + }else{ + std::cout<<"FE "<<m_info[module].getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + //return FEI4::FEI4ARecord::BadRecord; + return 0; + } + bytepointer+=3; + } + //m_timer.Stop(); + return nL1A; +} + +SNDataProc::SNDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + std::cout<<"SN Data Proc"<<std::endl; + try{ //catch bad scan option parameters + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + char name[128]; + char title[128]; + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + sprintf(name, "Mod_%d_SN", moduleId); + sprintf(title, "Module %d at %s Serial Number", moduleId, moduleName.c_str()); + m_histo_occ.push_back(new RceHisto1d<int, int>(name, title, 1, 0, 1)); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +SNDataProc::~SNDataProc(){ + for (size_t module=0;module<m_histo_occ.size();module++){ + delete m_histo_occ[module]; + } + +} + + diff --git a/rce/rcecalib/dataproc/SNDataProc.hh b/rce/rcecalib/dataproc/SNDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..f178b34678bb5bb247409c22590082df8ac58ef4 --- /dev/null +++ b/rce/rcecalib/dataproc/SNDataProc.hh @@ -0,0 +1,21 @@ +#ifndef SNDATAPROC_HH +#define SNDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" + +class SNDataProc: public AbsDataProc{ +public: + SNDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~SNDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + std::vector<RceHisto1d<int, int>*> m_histo_occ; +}; + +#endif diff --git a/rce/rcecalib/dataproc/SelftriggerDataProc.cc b/rce/rcecalib/dataproc/SelftriggerDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..c5c6d93a3e53b781125dadf899845535529dadeb --- /dev/null +++ b/rce/rcecalib/dataproc/SelftriggerDataProc.cc @@ -0,0 +1,393 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/SelftriggerDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/util/RceName.hh" + +int SelftriggerDataProc::fit(std::string fitfun){ + if(m_file){ + std::cout<<"Closing file."<<std::endl; + m_file->close(); + } + return 0; +} + +int SelftriggerDataProc::processData(unsigned link, unsigned *data, int size){ + if(m_counter++==0)usleep(1); + if(m_link10DataOn && link==10){ + //std::cout<<"Found link=10 for Trigger data, moving on"<<std::endl; + unsigned trgtime1=data[3]; + unsigned trgtime2=data[4]; + m_trgtime=trgtime1; + m_trgtime=(m_trgtime<<32) | trgtime2; + + unsigned int link10_l1id = ((data[0]>>24)&0xf); + + if(!m_trgtime_initial_set){ + m_trgtime_initial_set=true; + m_trgtime_initial=m_trgtime; + } + + int trigtimeDiff = (m_trgtime&0xff) - (m_trgtime_initial&0xff); + if(trigtimeDiff<0) trigtimeDiff+=256; + + m_trigtimeDiff_index_l1id[link10_l1id]= trigtimeDiff; + m_trigtime_index_l1id[link10_l1id]= (m_trgtime); + return 0; + } + + // std::cout<<"Process data"<<std::endl; + for (int i=0;i<size;i++) + { + int module=m_linkToIndex[link]; + FormattedRecord current(data[i]); + + if (current.isHeader()) + { + m_l1id[module] = current.getL1id(); + m_bcid[module] = current.getBxid(); + //printf("bcid : %x \n", bcid); + //printf("module %d l1id : %x \n", module, m_l1id[module]); + + if(m_link10DataOn && !m_bcid_initial_set[module]){ + m_bcid_initial_set[module]=true; + m_bcid_initial[module]=m_bcid[module]; + } + + if (m_l1id[module] != m_l1id_last[module]) + { + if(m_l1id_last[module]==0xffffffff) + //std::cout<<"Initial L1ID: m_l1id="<<m_l1id[module]<<" "<< (m_l1id[module]&0xf) <<" m_l1id_last="<<m_l1id_last[module]<<" "<<(m_l1id_last[module]&0xf)<<std::endl; + + if(m_l1id_last[module]!=0xffffffff){ + ///l1id skipping //// + int l1idDiff = (m_l1id[module]&0xf) - (m_l1id_last[module]&0xf); + if(l1idDiff<0) l1idDiff+=16; + if(l1idDiff!=1){ + //std::cout<<"L1ID Skip: m_l1id="<<m_l1id[module]<<" "<< (m_l1id[module]&0xf) <<" m_l1id_last="<<m_l1id_last[module]<<" "<<(m_l1id_last[module]&0xf)<<" l1idDiff="<<l1idDiff<<std::endl; + m_histo_l1idDiff[module]->increment(l1idDiff); + } + ///////////////////// + + + if(m_totev[module]>31) + m_totev[module]=31; //last bin is overflow + if(m_nhit[module]>15) + m_nhit[module]=15; //last bin is overflow + m_histo_totev[module]->increment(m_totev[module]); + m_histo_nhit[module]->increment(m_nhit[module]); + m_totev[module]=0; + m_nhit[module]=0; + + // Cluster Magic + m_cluster_proc[module].clusterize(); + } + m_l1id_last[module] = m_l1id[module]; + m_bcid_ref[module] = m_bcid[module]; + m_l1idchanged[module]=1; + + + //BCID skipping////////// + if(false&&m_link10DataOn) + { + int module_BCID_diff = (m_bcid_ref[module]&0xff) - (m_bcid_initial[module]&0xff); + if(module_BCID_diff<0) module_BCID_diff+=256; + + m_bcidDiff_index_l1id_vs_module[ m_l1id[module]&0xf ][module] = module_BCID_diff; + m_bcidDiff_index_l1id_vs_module_isSet[ m_l1id[module]&0xf ][module] = true; + + //check if all datat for event has arrived + bool all_arrived = true; + for(unsigned int imod=0; imod<nmod; imod++){ + all_arrived = all_arrived && m_bcidDiff_index_l1id_vs_module_isSet[ m_l1id[module]&0xf ][imod]; + } + if(all_arrived){ + for(unsigned int imod=0; imod<nmod; imod++){ + int event_diff = (m_bcidDiff_index_l1id_vs_module[ m_l1id[module]&0xf ][imod] & 0xff) - (m_trigtimeDiff_index_l1id[ m_l1id[module]&0xf ] & 0xff); + if(event_diff < 0) event_diff += 256; + + //if diff found, fill histo, and reset initial diff for module + if(event_diff>0){ + //std::cout<<"event "<< n_evt_skip<<" L1ID="<<(m_l1id[module]&0xf)<<" EVENT DIFF="<<event_diff<<" Mod="<<imod<<" BCID diff="<< (m_bcidDiff_index_l1id_vs_module[ m_l1id[module]&0xf ][imod] & 0xff )<<" BCID="<<(m_bcid_ref[module]&0xff)<<" BCID init="<<(m_bcid_initial[module]& 0xff)<<" Trig time="<< (m_trigtime_index_l1id[ m_l1id[module]&0xf ] & 0xff)<<" Trig diff="<< (m_trigtimeDiff_index_l1id[ m_l1id[module]&0xf ] & 0xff )<<" Trig init="<<(m_trgtime_initial & 0xff)<<std::endl; + + m_histo_bcidDiff[imod]->increment(event_diff); + + m_bcid_initial[imod] = ( (m_bcid_initial[imod] + (event_diff & 0xff)) & 0xff ); + + } + + m_bcidDiff_index_l1id_vs_module_isSet[ m_l1id[module]&0xf ][imod] = false; + } + } + } + //end BCID skipping///////// + + }//end L1ID != last L1ID + + if(m_bcid[module]>=m_bcid_ref[module]) + m_bcid[module] = m_bcid[module]-m_bcid_ref[module]; + else + m_bcid[module] = m_bcid[module] + (0xff - (0xff&m_bcid_ref[module]) ) ; //BCID counter rollover + + // printf("bcidafter : %x \n", bcid); + + }//end header check + else if (current.isData()) + { + unsigned int chip=current.getFE(); + unsigned int tot=current.getToT(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + if(m_file){ + if(m_l1idchanged[module]==1){ + m_l1idchanged[module]=0; + m_hiteventid[module]++; + } + unsigned word=((link&0xf)<<28)|((m_l1id[module]&0xf)<<24)|(tot<<16)|(row<<7)|col; + m_file->write((char*)&word, 4); + } + //printf("Hit col=%d row=%d tot=%d\n",col, row, tot); + + m_histo_occ[module]->increment(chip*m_info[module].getNColumns()+col,row); + m_histo_tot2d[module]->fill(chip*m_info[module].getNColumns()+col,row, tot); + m_histo_tot[module]->increment(tot); + m_histo_timing[module]->increment(m_bcid[module]); + m_totev[module]+=tot; + m_nhit[module]++; + + // Clustering (exclude ToT 14 hits) + m_cluster_proc[module].addHit(col, row, tot, m_bcid[module]); + + //printf("bcidafter : %x \n", bcid); + }//end data check + }//end for loop + return 0; +} + +SelftriggerDataProc::SelftriggerDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif), m_file(0), m_counter(0){ + + nmod=m_configIF->getNmodules(); + m_l1id_last = new unsigned int[nmod]; + m_l1id = new unsigned int[nmod]; + m_bcid_ref = new unsigned int[nmod]; + m_bcid = new unsigned int[nmod]; + m_totev=new int[nmod]; + m_nhit=new int[nmod]; + + + m_hiteventid = new unsigned int[nmod]; + m_l1idchanged = new unsigned int[nmod]; + + ///BCID skipping + m_link10DataOn = (bool) scanOptions->get<int>("trigOpt.triggerDataOn"); + + if(m_link10DataOn) + { + m_bcid_initial_set = new bool[nmod]; + m_bcid_initial = new unsigned int[nmod]; + + m_trgtime_initial_set=false; + m_trgtime_initial=(unsigned long long)(-1); + + + m_bcidDiff_index_l1id_vs_module = new unsigned int*[16]; + m_bcidDiff_index_l1id_vs_module_isSet = new bool*[16]; + for (int i=0;i<16;i++){ + m_bcidDiff_index_l1id_vs_module[i] = new unsigned int[nmod]; + m_bcidDiff_index_l1id_vs_module_isSet[i] = new bool[nmod]; + + for(unsigned int j=0; j<nmod; j++) + m_bcidDiff_index_l1id_vs_module_isSet[i][j] = false; + } + m_trigtimeDiff_index_l1id = new unsigned long long[16]; + m_trigtime_index_l1id = new unsigned long long[16]; + } + //// + + + m_cluster_proc = new ClusterProc[nmod]; + + try{ + std::string name=scanOptions->get<std::string>("Name"); + if(name!="Scan"){ + if(name.find("RUNNUM")!=std::string::npos){ //replace RUNNUM macro with run number + char runns[12]; + sprintf(runns, "%06d", scanOptions->get<int>("runNumber")); + name.replace(name.find("RUNNUM"), 6, runns); + } + std::string path="/nfs/"; + char rcename[32]; + sprintf(rcename, "_RCE_%d.", RceName::getRceNumber()); + if(name.find(".")!=std::string::npos){ + name.replace(name.find("."), 1, rcename); + }else{ + name+=rcename; + } + path+=name; + std::cout<<"Opening file "<<path<<std::endl; + m_file=new std::ofstream(path.c_str(), std::ios::binary); + } + for (unsigned int module=0;module<nmod;module++){ + m_l1id_last[module] = 0xffffffff; + m_l1id[module] = 0; + m_bcid_ref[module] = 0; + m_bcid[module] = 0; + m_totev[module] = 0; + m_nhit[module] = 0; + + m_hiteventid[module]=0; + m_l1idchanged[module]=0; + + if(m_link10DataOn){ + m_bcid_initial_set[module]=false; + m_bcid_initial[module]=0xffffffff; + } + + char name[128]; + char title[128]; + RceHisto2d<int, int> *histo; + RceHisto1d<int, int> *histoTot; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + + /* retrieve scan points - Vcal steps in this case */ + std::cout<<"Creating Occupancy histograms."<<std::endl; + std::cout<<"Creating ToT spectrum histograms."<<std::endl; + + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_Occupancy",moduleId); + histo=new RceHisto2d<int, int>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_occ.push_back(histo); + + sprintf(title,"ToT 2d Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_Occupancy_2d",moduleId); + histo=new RceHisto2d<int, int>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_tot2d.push_back(histo); + + sprintf(title,"ToT Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_ToT",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,16,-.5,15.5); + histoTot->setAxisTitle(0,"ToT"); + m_histo_tot.push_back(histoTot); + + sprintf(title,"ToT per event Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_ToT_event",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,32,-.5,31.5); + histoTot->setAxisTitle(0,"ToT"); + m_histo_totev.push_back(histoTot); + + sprintf(title,"Number of hits per event Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_nhits",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,16,-.5,15.5); + histoTot->setAxisTitle(0,"Number of hits"); + m_histo_nhit.push_back(histoTot); + + sprintf(title,"Timing of bunch per event Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_timing",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,16,-.5,15.5); + histoTot->setAxisTitle(0,"Hit timing"); + m_histo_timing.push_back(histoTot); + + sprintf(title,"Hits per cluster Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_nhits_cluster",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,20,-.5,19.5); + histoTot->setAxisTitle(0,"Hits per cluster"); + m_histo_nhits_cluster.push_back(histoTot) ; + m_cluster_proc[module].assignHitHisto(histoTot); + + sprintf(title,"Clustered ToT Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_tot_cluster",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,32,-.5,31.5); + histoTot->setAxisTitle(0,"Clustered ToT"); + m_histo_tot_cluster.push_back(histoTot) ; + m_cluster_proc[module].assignToTHisto(histoTot); + + sprintf(title,"Clustered ToT per Cluster Size Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_tot_per_clustersize",moduleId); + histo=new RceHisto2d<int, int>(name,title,32,-.5,31.5,20,-.5,19.5); + histo->setAxisTitle(0,"Clustered ToT"); + histo->setAxisTitle(1,"Cluster Size"); + m_histo_tot_size.push_back(histo); + m_cluster_proc[module].assignToTClusterSizeHisto(histo); + + sprintf(title,"L1ID difference per event Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_L1IDdiff",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,16,-0.5,15.5); + histoTot->setAxisTitle(0,"L1ID difference"); + m_histo_l1idDiff.push_back(histoTot); + + if(m_link10DataOn) + { + sprintf(title,"BCID difference per event Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Selftrigger_BCIDdiff",moduleId); + histoTot=new RceHisto1d<int, int>(name,title,256,-0.5,255.5); + histoTot->setAxisTitle(0,"BCID difference"); + m_histo_bcidDiff.push_back(histoTot); + } + + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +SelftriggerDataProc::~SelftriggerDataProc(){ + delete m_file; + for (size_t module=0;module<m_histo_tot.size();module++){ + delete m_histo_tot[module]; + delete m_histo_totev[module]; + delete m_histo_nhit[module]; + delete m_histo_occ[module]; + delete m_histo_tot2d[module]; + delete m_histo_timing[module]; + delete m_histo_tot_cluster[module]; + delete m_histo_nhits_cluster[module]; + delete m_histo_tot_size[module]; + delete m_histo_l1idDiff[module]; + if(m_link10DataOn) + delete m_histo_bcidDiff[module]; + } + delete [] m_totev; + delete [] m_nhit; + delete [] m_bcid_ref; + delete [] m_bcid; + delete [] m_l1id_last; + delete [] m_l1id; + delete [] m_cluster_proc; + + + delete [] m_l1idchanged; + delete [] m_hiteventid; + + if(m_link10DataOn) + { + delete [] m_bcid_initial_set; + delete [] m_bcid_initial; + + for (int i=0;i<16;i++){ + delete [] m_bcidDiff_index_l1id_vs_module[i]; + delete [] m_bcidDiff_index_l1id_vs_module_isSet[i]; + } + delete [] m_bcidDiff_index_l1id_vs_module; + delete [] m_bcidDiff_index_l1id_vs_module_isSet; + + delete [] m_trigtimeDiff_index_l1id; + delete [] m_trigtime_index_l1id; + } +} + + diff --git a/rce/rcecalib/dataproc/SelftriggerDataProc.hh b/rce/rcecalib/dataproc/SelftriggerDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..0a46eaf56b6406c00a14cce74007e8ab51f4af4d --- /dev/null +++ b/rce/rcecalib/dataproc/SelftriggerDataProc.hh @@ -0,0 +1,70 @@ +#ifndef SELFTRIGGERDATAPROC_HH +#define SELFTRIGGERDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include "rcecalib/dataproc/ClusterProc.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceHisto1d.cc" +#include <fstream> + +class SelftriggerDataProc: public AbsDataProc{ +public: + SelftriggerDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~SelftriggerDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + + std::vector<RceHisto2d<int, int>*> m_histo_occ; + std::vector<RceHisto2d<int, int>*> m_histo_tot2d; + std::vector<RceHisto1d<int, int>*> m_histo_tot; + std::vector<RceHisto1d<int, int>*> m_histo_nhit; + std::vector<RceHisto1d<int, int>*> m_histo_totev; + std::vector<RceHisto1d<int, int>*> m_histo_timing; + std::vector<RceHisto1d<int, int>*> m_histo_nhits_cluster; + std::vector<RceHisto1d<int, int>*> m_histo_tot_cluster; + std::vector<RceHisto2d<int, int>*> m_histo_tot_size; + std::vector<RceHisto1d<int, int>*> m_histo_bcidDiff; + std::vector<RceHisto1d<int, int>*> m_histo_l1idDiff; + + + //unsigned int m_bcid_ref; + //unsigned int m_bcid; + unsigned int* m_bcid_ref; + unsigned int* m_bcid; + unsigned int* m_l1id; + unsigned int* m_l1id_last; + int *m_totev, *m_nhit; + std::ofstream* m_file; + //bool m_occ, m_tot, m_bcid; + unsigned short m_counter; + + //BCID skipping stuff + bool* m_bcid_initial_set; + unsigned int* m_bcid_initial; + unsigned int* m_hiteventid; + unsigned int* m_l1idchanged; + + unsigned long long m_trgtime; //BCID coming from link-10 (tig info link) + bool m_trgtime_initial_set; + unsigned long long m_trgtime_initial; + + unsigned int ** m_bcidDiff_index_l1id_vs_module; + bool ** m_bcidDiff_index_l1id_vs_module_isSet; + + unsigned long long * m_trigtimeDiff_index_l1id; + unsigned long long * m_trigtime_index_l1id; + + unsigned int nmod; + + bool m_link10DataOn; + + // Clustering + ClusterProc *m_cluster_proc; +}; + +#endif diff --git a/rce/rcecalib/dataproc/SimpleDataHandler.hh b/rce/rcecalib/dataproc/SimpleDataHandler.hh new file mode 100644 index 0000000000000000000000000000000000000000..447ed84d9407298fc36bab466da8cdbc95e550b2 --- /dev/null +++ b/rce/rcecalib/dataproc/SimpleDataHandler.hh @@ -0,0 +1,24 @@ +#ifndef SIMPLEDATAHANDLER_HH +#define SIMPLEDATAHANDLER_HH + +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include "rcecalib/util/DataCond.hh" + +class SimpleDataHandler:public AbsDataHandler{ +public: + SimpleDataHandler(AbsDataProc* proc, DataCond& datacond): + AbsDataHandler(proc, datacond, 0){ + } + virtual ~SimpleDataHandler(){ + } + void handle(unsigned link, unsigned* data, int size) { + if(size>0){ + m_dataProc->processData(link, data, size); + } + //m_scan->stopWaiting(); + omni_mutex_lock pl( m_dataCond.mutex ); + if(m_dataCond.waitingForData==true)m_dataCond.cond.signal(); + }; + +}; +#endif diff --git a/rce/rcecalib/dataproc/SimpleReceiver.cc b/rce/rcecalib/dataproc/SimpleReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..adf6bd3526f9b7cba79fc6e74b8fd5877ff1c911 --- /dev/null +++ b/rce/rcecalib/dataproc/SimpleReceiver.cc @@ -0,0 +1,6 @@ +#include "rcecalib/dataproc/SimpleReceiver.hh" + +void SimpleReceiver::Receive(unsigned *data, int size){ + m_handler->handle(0, data,size); + return; +} diff --git a/rce/rcecalib/dataproc/SimpleReceiver.hh b/rce/rcecalib/dataproc/SimpleReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..4509c83781ac09ae0bfe6500592b71804e65be3d --- /dev/null +++ b/rce/rcecalib/dataproc/SimpleReceiver.hh @@ -0,0 +1,12 @@ +#ifndef SIMPLERECEIVER_HH +#define SIMPLERECEIVER_HH + +#include "rcecalib/dataproc/AbsReceiver.hh" +#include "rcecalib/config/TriggerReceiverIF.hh" + +class SimpleReceiver: public AbsReceiver, public TriggerReceiverIF{ +public: + SimpleReceiver(AbsDataHandler* handler):AbsReceiver(handler), TriggerReceiverIF(){} + void Receive(unsigned *data, int size); +}; +#endif diff --git a/rce/rcecalib/dataproc/TemperatureDataProc.cc b/rce/rcecalib/dataproc/TemperatureDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..7a62c7fa63edab99a5e3a765cc7cf0b022140a47 --- /dev/null +++ b/rce/rcecalib/dataproc/TemperatureDataProc.cc @@ -0,0 +1,132 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/TemperatureDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/config/FEI4/FEI4BRecord.hh" + +int TemperatureDataProc::fit(std::string fitfun) { + std::cout << "Running: " << fitfun << std::endl; + if(fitfun=="NORMALIZE") { + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + for(int j=0;j<m_nPoints;j++){ + float n=(float)(*m_histo_occ[module])(j); + float mean=0; + if(n>0)mean=(float)(*m_histo_adc[module])(j)/n; + m_histo_norm[module]->set(j, mean); + float err=0; + if(n>0)err=((*m_histo_adc2[module])(j)/n-mean*mean)/n; //error^2 on mean + if(err<0)err=0; //prevent rounding errors + m_histo_norm[module]->setBinError(j, err); + // std::cout<<"Bin content is "<<(*m_histo[module][i])(j)<<std::endl; + //std::cout<<"Bin error is "<<m_histo[module][i]->getBinError(j)<<std::endl; + } + } + } + return 0; +} + +int TemperatureDataProc::processData(unsigned link, unsigned *buffer, int buflen){ + //m_timer.Start(); + if(buflen==0)return 0; + int nL1A=0; + int module=m_linkToIndex[link]; + unsigned char* bytepointer=(unsigned char*)buffer; + unsigned char* last=bytepointer+buflen*sizeof(unsigned)-3; + FEI4::FEI4BRecord rec; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + if(rec.isData()){ //includes empty record type + //should not happen + } else if(rec.isDataHeader()){ + //should not happen, either + }else if(rec.isServiceRecord()){ + //no service records + }else if(rec.isValueRecord()){ //val rec without addr rec + int value=rec.getValue()>>4; + //std::cout<<"Link "<<link<<" value record! Value="<<std::hex<<rec.getValue()<<std::dec<<std::endl; + m_histo_occ[module]->increment(m_currentBin); + m_histo_adc[module]->fill(m_currentBin, value); + m_histo_adc2[module]->fill(m_currentBin, value*value); + nL1A++; + }else if(rec.isAddressRecord()){ // address record + // Ignore address records + //std::cout<<"FE "<<m_info[module].getId()<<": Address record for "; + //if(rec.isGlobal())std::cout<<" global register "; + //else std::cout<<" shift register "; + //std::cout<<rec.getAddress()<<std::endl; + //std::cout<<"This should not happen."<<std::endl; + }else{ + std::cout<<"FE "<<m_info[module].getId()<<": Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + //return FEI4::FEI4ARecord::BadRecord; + return 0; + } + bytepointer+=3; + } + //m_timer.Stop(); + return nL1A; +} + +TemperatureDataProc::TemperatureDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif),m_fit(0) { + std::cout<<"Temperature Data Proc"<<std::endl; + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + char name[128]; + char title[128]; + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + sprintf(name, "Mod_%d_nEvents", moduleId); + sprintf(title, "Module %d at %s Number of events", moduleId, moduleName.c_str()); + m_histo_occ.push_back(new RceHisto1d<int, int>(name, title, m_nPoints, 0, m_nPoints)); + m_histo_occ.back()->setAxisTitle(0, "Set point"); + sprintf(name, "Mod_%d_ADC", moduleId); + sprintf(title, "Module %d at %s ADC", moduleId, moduleName.c_str()); + m_histo_adc.push_back(new RceHisto1d<int, int>(name, title, m_nPoints, 0, m_nPoints)); + m_histo_adc.back()->setAxisTitle(0, "Set point"); + sprintf(name, "Mod_%d_ADC2", moduleId); + sprintf(title, "Module %d at %s ADC^2", moduleId, moduleName.c_str()); + m_histo_adc2.push_back(new RceHisto1d<int, int>(name, title, m_nPoints, 0, m_nPoints)); + m_histo_adc2.back()->setAxisTitle(0, "Set point"); + sprintf(name, "Mod_%d_Voltage", moduleId); + sprintf(title, "Module %d at %s Voltage", moduleId, moduleName.c_str()); + m_histo_norm.push_back(new RceHisto1d<float, float>(name, title, m_nPoints, 0, m_nPoints, true)); + m_histo_norm.back()->setAxisTitle(0, "Set point"); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + +TemperatureDataProc::~TemperatureDataProc(){ + for (size_t module=0;module<m_histo_occ.size();module++){ + delete m_histo_occ[module]; + delete m_histo_adc[module]; + delete m_histo_adc2[module]; + delete m_histo_norm[module]; + } + +} + + diff --git a/rce/rcecalib/dataproc/TemperatureDataProc.hh b/rce/rcecalib/dataproc/TemperatureDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..4cb1d2649d67ec35472ca84e64483a0a24804c70 --- /dev/null +++ b/rce/rcecalib/dataproc/TemperatureDataProc.hh @@ -0,0 +1,29 @@ +#ifndef TEMPERATUREDATAPROC_HH +#define TEMPERATUREDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include <vector> +#include "rcecalib/util/RceHisto1d.cc" + +class TemperatureDataProc: public AbsDataProc{ +public: + TemperatureDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + virtual ~TemperatureDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); + +protected: + std::vector<RceHisto1d<int, int>*> m_histo_occ; + std::vector<RceHisto1d<int, int>*> m_histo_adc; + std::vector<RceHisto1d<int, int>*> m_histo_adc2; + std::vector<RceHisto1d<float, float>*> m_histo_norm; + AbsFit *m_fit; + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; +}; + +#endif diff --git a/rce/rcecalib/dataproc/TotCalibDataProc.cc b/rce/rcecalib/dataproc/TotCalibDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..a153349c96fc5198fce750e7ee795d736fe03c07 --- /dev/null +++ b/rce/rcecalib/dataproc/TotCalibDataProc.cc @@ -0,0 +1,79 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "dataproc/TotCalibDataProc.hh" +#include "config/ConfigIF.hh" +#include "config/FormattedRecord.hh" +#include "dataproc/fit/CalculateMeanSigma.cc" + +int TotCalibDataProc::fit(std::string fitfun) { +#ifdef RCEPIXLIB + std::cout << "Running: " << fitfun << std::endl; + // if(fitfun=="CALCULATE_MEAN_SIGMA" && m_nPoints!=0) { + // calculateMeanSigma(m_histo_occ, m_histo_tot, m_histo_tot2, m_histo_tot_mean, m_histo_tot_sigma); + } +#endif + return 0; +} + +int TotCalibDataProc::processData(unsigned link, unsigned *data, int size){ + // std::cout<<"Process data"<<std::endl; + for (int i=0;i<size;i++){ + int module=m_linkToIndex[link]; // will be different when parser is fully there + FormattedRecord current(data[i]); + // if (current.isHeader()){ + // l1id = current.getL1id(); + // bcid = current.getBxid(); + //printf("bcid : %x \n", bcid); + //printf("l1id : %x \n", l1id); + // if (l1id != l1id_last) + //{ + // l1id_last = l1id; + // bcid_ref = bcid; + //} + // bcid = bcid-bcid_ref; + // printf("bcidafter : %x \n", bcid); + //} + if (current.isData()){ + unsigned int tot=current.getToT(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns()) && tot<15 && tot!=0) { + m_histo_tot[module][tot-1]->incrementFast(col,row); + } + } + } + return 0; +} + +TotCalibDataProc::TotCalibDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<char, char>* > vhcc; + m_histo_tot.push_back(vhcc); + char name[128]; + char title[128]; + RceHisto2d<char, char> *histoc; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + for(int i=1;i<15;i++){ //ToT loop + /* retrieve scan points - Vcal steps in this case */ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Occupancy_ToT_%02d", moduleId, i); + histoc=new RceHisto2d<char, char>(name,title,cols,0,cols,rows,0,rows); + histoc->setAxisTitle(0,"Column"); + histoc->setAxisTitle(1, "Row"); + m_histo_tot[module].push_back(histoc); + } + } +} + + +TotCalibDataProc::~TotCalibDataProc(){ + for (size_t module=0;module<m_histo_tot.size();module++) + for(size_t i=0;i<m_histo_tot[module].size();i++)delete m_histo_tot[module][i]; +} + + diff --git a/rce/rcecalib/dataproc/TotCalibDataProc.hh b/rce/rcecalib/dataproc/TotCalibDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..9f1ac6efe5bb427f6afe6bb6145e7ad340714958 --- /dev/null +++ b/rce/rcecalib/dataproc/TotCalibDataProc.hh @@ -0,0 +1,26 @@ +#ifndef TOTCALIBDATAPROC_HH +#define TOTCALIBDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "dataproc/AbsDataProc.hh" +#include <vector> +#include "util/RceHisto2d.cc" + +class TotCalibDataProc: public AbsDataProc{ +public: + TotCalibDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + + virtual ~TotCalibDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); +protected: + + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_tot; + + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; +}; + +#endif diff --git a/rce/rcecalib/dataproc/TotDataProc.cc b/rce/rcecalib/dataproc/TotDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..47bdf8e653e718060dd14827379561527b93272f --- /dev/null +++ b/rce/rcecalib/dataproc/TotDataProc.cc @@ -0,0 +1,162 @@ +#include <stdio.h> +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/TotDataProc.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/dataproc/fit/CalculateMeanSigma.cc" + +int TotDataProc::fit(std::string fitfun) { +#ifdef RCEPIXLIB + std::cout << "Running: " << fitfun << std::endl; + if(fitfun=="CALCULATE_MEAN_SIGMA" && m_nPoints!=0) { + calculateMeanSigma(m_histo_occ, m_histo_tot, m_histo_tot2, m_histo_tot_mean, m_histo_tot_sigma); + } +#endif + return 0; +} + +int TotDataProc::processData(unsigned link, unsigned *data, int size){ + // std::cout<<"Process data"<<std::endl; + for (int i=0;i<size;i++){ + int module=m_linkToIndex[link]; // will be different when parser is fully there + FormattedRecord current(data[i]); + // if (current.isHeader()){ + // l1id = current.getL1id(); + // bcid = current.getBxid(); + //printf("bcid : %x \n", bcid); + //printf("l1id : %x \n", l1id); + // if (l1id != l1id_last) + //{ + // l1id_last = l1id; + // bcid_ref = bcid; + //} + // bcid = bcid-bcid_ref; + // printf("bcidafter : %x \n", bcid); + //} + if (current.isData()){ + unsigned int chip=current.getFE(); + unsigned int tot=current.getToT(); + unsigned int col=current.getCol(); + unsigned int row=current.getRow(); + if((row<(unsigned)m_info[module].getNRows()) && (col<(unsigned)m_info[module].getNColumns())) { + if(chip==0){ //gives better performance for FEI4 + m_histo_occ[module][m_currentBin]->incrementFast(col,row); + m_histo_tot[module][m_currentBin]->fillFast(col,row,(unsigned int)tot); + m_histo_tot2[module][m_currentBin]->fillFast(col,row,(unsigned int)(tot*tot)); + }else if(chip<(unsigned)m_info[module].getNFrontends()){ + m_histo_occ[module][m_currentBin]->incrementFast(chip*m_info[module].getNColumns()+col,row); + m_histo_tot[module][m_currentBin]->fillFast(chip*m_info[module].getNColumns()+col,row,(unsigned int)tot); + m_histo_tot2[module][m_currentBin]->fillFast(chip*m_info[module].getNColumns()+col,row,(unsigned int)(tot*tot)); + } + } + } + } + return 0; +} + +TotDataProc::TotDataProc(ConfigIF* cif, boost::property_tree::ptree* scanOptions) + :AbsDataProc(cif) { + try{ //catch bad scan option parameters + m_nLoops = scanOptions->get<int>("nLoops"); + /* there is at least one parameter loop */ + /* TODO: fix in scan control */ + m_nPoints=1; + if(m_nLoops>0){ + m_nPoints=scanOptions->get<int>("scanLoop_0.nPoints"); + for(int i=0;i<m_nPoints;i++) { + char pointname[10]; + sprintf(pointname,"P_%d",i); + int vcal=scanOptions->get<int>(std::string("scanLoop_0.dataPoints.")+pointname); + //std::cout << "point vcal " << vcal << std::endl; + m_vcal.push_back(vcal); + } + } + m_nTrigger=scanOptions->get<int>("trigOpt.nEvents"); + + for (unsigned int module=0;module<m_configIF->getNmodules();module++){ + std::vector<RceHisto2d<char, char>* > vhc; + std::vector<RceHisto2d<short, short>* > vh; + m_histo_occ.push_back(vhc); + m_histo_tot.push_back(vh); + m_histo_tot2.push_back(vh); + m_histo_tot_sigma.push_back(vh); + m_histo_tot_mean.push_back(vh); + char name[128]; + char title[128]; + RceHisto2d<short, short> *histo; + RceHisto2d<char, char> *histoc; + unsigned int cols=m_info[module].getNColumns()*m_info[module].getNFrontends(); + unsigned int rows=m_info[module].getNRows(); + unsigned int moduleId=m_info[module].getId(); + std::string moduleName=m_info[module].getName(); + /* retrieve scan points - Vcal steps in this case */ + for (int point=0;point<m_nPoints;point++){ + sprintf(title,"OCCUPANCY Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_Occupancy_Point_%03d", moduleId,point); + histoc=new RceHisto2d<char, char>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histoc->setAxisTitle(0,"Column"); + else histoc->setAxisTitle(0,"FE*N_COL+Column"); + histoc->setAxisTitle(1, "Row"); + m_histo_occ[module].push_back(histoc); + sprintf(title,"ToT Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_ToT_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_tot[module].push_back(histo); + + sprintf(title,"ToT2 Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_ToT2_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_tot2[module].push_back(histo); + +#ifdef RCEPIXLIB + sprintf(title,"ToT_MEAN Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_ToTmean_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_tot_mean[module].push_back(histo); + + sprintf(title,"ToT_SIGMA Mod %d at %s", moduleId, moduleName.c_str()); + sprintf(name,"Mod_%d_ToTsigma_Point_%03d", moduleId,point); + histo=new RceHisto2d<short, short>(name,title,cols,0,cols,rows,0,rows); + if(m_info[module].getNFrontends()==1)histo->setAxisTitle(0,"Column"); + else histo->setAxisTitle(0,"FE*N_COL+Column"); + histo->setAxisTitle(1, "Row"); + m_histo_tot_sigma[module].push_back(histo); +#endif + } + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + ERS_ASSERT(0); + } +} + + +TotDataProc::~TotDataProc(){ + for (size_t module=0;module<m_histo_tot.size();module++) + for(size_t i=0;i<m_histo_tot[module].size();i++)delete m_histo_tot[module][i]; + for (size_t module=0;module<m_histo_tot2.size();module++) + for(size_t i=0;i<m_histo_tot2[module].size();i++)delete m_histo_tot2[module][i]; + for (size_t module=0;module<m_histo_occ.size();module++) + for(size_t i=0;i<m_histo_occ[module].size();i++)delete m_histo_occ[module][i]; +#ifdef RCEPIXLIB + for (size_t module=0;module<m_histo_tot_mean.size();module++) + for(size_t i=0;i<m_histo_tot_mean[module].size();i++)delete m_histo_tot_mean[module][i]; + for (size_t module=0;module<m_histo_tot_sigma.size();module++) + for(size_t i=0;i<m_histo_tot_sigma[module].size();i++)delete m_histo_tot_sigma[module][i]; +#endif + +} + + diff --git a/rce/rcecalib/dataproc/TotDataProc.hh b/rce/rcecalib/dataproc/TotDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..4247e600d85a6cba3d97922eefb93414e4e361d7 --- /dev/null +++ b/rce/rcecalib/dataproc/TotDataProc.hh @@ -0,0 +1,30 @@ +#ifndef TOTDATAPROC_HH +#define TOTDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include <vector> +#include "rcecalib/util/RceHisto2d.cc" + +class TotDataProc: public AbsDataProc{ +public: + TotDataProc(ConfigIF* cif,boost::property_tree::ptree* scanOptions ); + + virtual ~TotDataProc(); + int processData(unsigned link, unsigned *data, int size); + int fit(std::string fitfun); +protected: + + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_tot; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_tot2; + std::vector<std::vector<RceHisto2d<char, char>*> > m_histo_occ; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_tot_sigma; + std::vector<std::vector<RceHisto2d<short, short>*> > m_histo_tot_mean; + + std::vector<int> m_vcal; + int m_nTrigger; + int m_nLoops; + int m_nPoints; +}; + +#endif diff --git a/rce/rcecalib/dataproc/constituents.mk b/rce/rcecalib/dataproc/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..6c699252a7905b7033e522b6e4731b6f7758371b --- /dev/null +++ b/rce/rcecalib/dataproc/constituents.mk @@ -0,0 +1,99 @@ + +ifdef SWAP_DATA +CPPFLAGS += '-DSWAP_DATA' +endif +ifeq ($(profiler),y) +CPPFLAGS+='-D__PROFILER_ENABLED__' +endif + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +modlibnames := dataproc +libsrcs_dataproc := AbsDataProc.cc \ + RegularScanDataHandler.cc \ + RegularScanRawDataHandler.cc \ + ModuleCrosstalkRawDataHandler.cc \ + DelayScanDataHandler.cc \ + CosmicDataHandler.cc \ + DataProcFactory.cc \ + OccupancyDataProc.cc \ + RawFei4OccupancyDataProc.cc \ + NoiseOccupancyDataProc.cc \ + TotDataProc.cc \ + TotCalibDataProc.cc \ + BcidDataProc.cc \ + SelftriggerDataProc.cc \ + HitorDataProc.cc \ + CosmicDataProc.cc \ + CosmicEvent.cc \ + CosmicEventIterator.cc \ + DelayScanDataProc.cc \ + SimpleReceiver.cc \ + MeasurementReceiver.cc \ + MeasurementDataProc.cc \ + PgpReceiver.cc \ + PgpCosmicReceiver.cc \ + PgpCosmicNwReceiver.cc \ + fit/FitData.cc \ + MultiTrigOccupancyDataProc.cc \ + MultiTrigNoiseDataProc.cc \ + TemperatureDataProc.cc \ + MonleakDataProc.cc \ + SNDataProc.cc\ + Fei4RegisterTestDataProc.cc\ + ClusterProc.cc + +libincs_dataproc := rcecalib \ + $(ers_include_path) \ + $(owl_include_path) \ + $(ipc_include_path) \ + $(is_include_path) \ + $(oh_include_path) \ + $(boost_include_path) \ + $(omniorb_include_path) + + +endif + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := dataproc +libsrcs_dataproc := AbsDataProc.cc \ + RegularScanDataHandler.cc \ + RegularScanRawDataHandler.cc \ + ModuleCrosstalkRawDataHandler.cc \ + DelayScanDataHandler.cc \ + CosmicDataHandler.cc \ + DataProcFactory.cc \ + NoiseOccupancyDataProc.cc \ + OccupancyDataProc.cc \ + RawFei4OccupancyDataProc.cc \ + TotDataProc.cc \ + TotCalibDataProc.cc \ + BcidDataProc.cc \ + SelftriggerDataProc.cc \ + HitorDataProc.cc \ + CosmicDataProc.cc \ + CosmicEvent.cc \ + CosmicEventIterator.cc \ + DelayScanDataProc.cc \ + SimpleReceiver.cc \ + MeasurementDataProc.cc \ + fit/FitData.cc \ + MultiTrigOccupancyDataProc.cc \ + MultiTrigNoiseDataProc.cc \ + TemperatureDataProc.cc \ + MonleakDataProc.cc \ + SNDataProc.cc\ + Fei4RegisterTestDataProc.cc\ + ClusterProc.cc + +libincs_dataproc := rcecalib \ + $(ers_include_path) \ + $(owl_include_path) \ + $(ipc_include_path) \ + $(is_include_path) \ + $(oh_include_path) \ + $(boost_include_path) \ + $(omniorb_include_path) + + +endif diff --git a/rce/rcecalib/dataproc/fit/AbsFit.hh b/rce/rcecalib/dataproc/fit/AbsFit.hh new file mode 100644 index 0000000000000000000000000000000000000000..14e0de1f6e01d486b5b60cef68c1e4d48afd2a7b --- /dev/null +++ b/rce/rcecalib/dataproc/fit/AbsFit.hh @@ -0,0 +1,24 @@ +#ifndef ABSFIT_HH +#define ABSFIT_HH + +#include <string> +#include <vector> +#include "rcecalib/config/ModuleInfo.hh" + +class ConfigIF; + + +class AbsFit { +public: + enum FitOpt {NOCONV=0x1,XTALK=0x2}; + AbsFit(ConfigIF *cif,std::vector<int> &vcal,int nTrigger):m_config(cif),m_vcal(vcal),m_nTrigger(nTrigger){}; + virtual ~AbsFit(){}; + virtual int doFit(int fitopt=0) = 0; + +protected: + ConfigIF *m_config; + std::vector<int> m_vcal; + int m_nTrigger; +}; + +#endif diff --git a/rce/rcecalib/dataproc/fit/CalculateMeanSigma.cc b/rce/rcecalib/dataproc/fit/CalculateMeanSigma.cc new file mode 100644 index 0000000000000000000000000000000000000000..b02a67691c7e04e2222c0c2ff3e45fc300097d45 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/CalculateMeanSigma.cc @@ -0,0 +1,73 @@ + +namespace{ + + int SquareRootFunc(int variance) + { + int op, res, one; + op = variance; + res = 0; + + // "one" starts at the highest power of four <= than the argument. + // if this value is decreased, a smaller range of values is allowed. needs to be an even number + one = 1 << 30; + while (one > op) { + one >>= 2; + } + while (one != 0) { + if (op >= res + one) { + op = op - (res + one); + res = res + (one<<1); + } + res >>= 1; + one >>= 2; + } + return res; + } +} +template<typename H, typename HE> +int calculateMeanSigma( std::vector<std::vector<RceHisto2d<H, HE>*> > &histo_occ, std::vector<std::vector<RceHisto2d<short, short>*> > &hvalue, std::vector<std::vector<RceHisto2d<short, short>*> > &hvalue2, std::vector<std::vector<RceHisto2d<short, short>*> > &hmean, std::vector<std::vector<RceHisto2d<short, short>*> > &hsigma ) +{ + + unsigned int numberofmodules =histo_occ.size(); + + for(unsigned module=0;module<numberofmodules;module++) { + for(unsigned int bin=0;bin<histo_occ[module].size();bin++) { + for(int col=0;col<histo_occ[module][bin]->nBin(0);col++) { + for(int row=0;row<histo_occ[module][bin]->nBin(1);row++) { + int counting =(int) (*histo_occ[module][bin])(col,row); + int toting = (int)(*hvalue[module][bin])(col,row); + int tot2ing = (int)(*hvalue2[module][bin])(col,row); + int mean=0; + int variance=0; + if(counting>0)mean=(toting<<7)/counting; + if(mean>0) { + hmean[module][bin]->set(col,row,mean); + } + else { + if (counting>0) { + hmean[module][bin]->set(col,row,1); + } + else { + hmean[module][bin]->set(col,row,0); + } + } + + if(counting>1) variance= (((tot2ing<<14)/(counting))-mean*mean); + if(variance >0) { + int sigma = SquareRootFunc(variance); + hsigma[module][bin]->set(col,row,sigma); + } else{ + + if(counting>1) { + hsigma[module][bin]->set(col,row,1); + } + else { + hsigma[module][bin]->set(col,row,0); + } + } + } //rows + } //columns + } // bins + }//modules + return 0; +} diff --git a/rce/rcecalib/dataproc/fit/FitData.cc b/rce/rcecalib/dataproc/fit/FitData.cc new file mode 100644 index 0000000000000000000000000000000000000000..1040b1ed168dc1ba7239ec9ef1c445eb629a94ee --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitData.cc @@ -0,0 +1,35 @@ +#include "rcecalib/dataproc/fit/FitData.hh" + +const int FitDataInt::binomial_weight[WEIGHT_LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/binomial_weight_int.dat" +}; +const int FitDataInt::data_logx[2*LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/logx_ext_int.dat" +}; +const int FitDataInt::data_errf[LUT_LENGTH]={ +#include "errf_ext_int.dat" +}; + +const int FitDataFastInt::binomial_weight[WEIGHT_LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/binomial_weight_int.dat" +}; +const int FitDataFastInt::data_logx[2*FAST_LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/logx_ext_fastint.dat" +}; +const int FitDataFastInt::data_errf[FAST_LUT_LENGTH]={ +#include "errf_ext_fastint.dat" +}; + +#ifdef INCLUDE_FLOAT_FIT +const float FitDataFloat::binomial_weight[WEIGHT_LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/binomial_weight.dat" +}; +const float FitDataFloat::data_logx[2*LUT_LENGTH]={ +#include "rcecalib/dataproc/fit/logx_ext.dat" +}; +const float FitDataFloat::data_errf[LUT_LENGTH]={ +#include "errf_ext.dat" +}; +#endif + + diff --git a/rce/rcecalib/dataproc/fit/FitData.hh b/rce/rcecalib/dataproc/fit/FitData.hh new file mode 100644 index 0000000000000000000000000000000000000000..b04b90219958ec783a4ddeeddaab6f1156bcc576 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitData.hh @@ -0,0 +1,34 @@ +#ifndef FITDATA_HH +#define FITDATA_HH +#define WEIGHT_LUT_LENGTH 1001 +#define LUT_WIDTH 3500 +#define LUT_LENGTH (2*LUT_WIDTH+1) +#define FAST_LUT_WIDTH 4095 +#define FAST_LUT_LENGTH (2*FAST_LUT_WIDTH+1) +#define inverse_lut_interval 1000.f +#define inverse_weight_lut_interval 1000.f +class FitDataInt +{ +public: + static const int binomial_weight[]; + static const int data_logx[]; + static const int data_errf[]; +}; +class FitDataFastInt +{ +public: + static const int binomial_weight[]; + static const int data_logx[]; + static const int data_errf[]; +}; +#ifdef INCLUDE_FLOAT_FIT +class FitDataFloat +{ +public: + static const float binomial_weight[]; + static const float data_logx[]; + static const float data_errf[]; +}; +#endif + +#endif diff --git a/rce/rcecalib/dataproc/fit/FitFactory.cc b/rce/rcecalib/dataproc/fit/FitFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..5c621f6b9c5bdbd5c86478ea71bc9ab6979ec2a3 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitFactory.cc @@ -0,0 +1,28 @@ +#ifndef FITFACTORY_CC +#define FITFACTORY_CC + +#include "rcecalib/dataproc/fit/FitFactory.hh" + +#ifdef INCLUDE_FLOAT_FIT +#include "rcecalib/dataproc/fit/FitScurveLikelihoodFloat.cc" +#endif +#include "rcecalib/dataproc/fit/FitScurveLikelihoodInt.cc" +#include "rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.cc" + +template<typename H, typename HE> +AbsFit *FitFactory<H, HE>::createFit(const char * type,ConfigIF *cif, std::vector<std::vector<RceHisto2d<H, HE>*> > &histo, std::vector<int> &vcal,int nTrigger, const char* name) +{ +#ifdef INCLUDE_FLOAT_FIT + if(std::string(type)=="ScurveLikelihoodFloat") return new FitScurveLikelihoodFloat<H, HE>(cif,histo,vcal,nTrigger); +#endif + if(std::string(type)=="ScurveLikelihoodFastInt") return new FitScurveLikelihoodFastInt<H, HE>(cif,histo,vcal,nTrigger,name); + else if (std::string(type)=="ScurveLikelihoodInt") return new FitScurveLikelihoodInt<H, HE>(cif,histo,vcal,nTrigger,name); + else + return 0; +} +template<typename H, typename HE> +AbsFit *FitFactory<H, HE>::createFit(const char * type,ConfigIF *cif, std::vector<std::vector<RceHisto1d<H, HE>*> > &histo, std::vector<int> &vcal,int nTrigger, const char* name){ + return 0; +} + +#endif diff --git a/rce/rcecalib/dataproc/fit/FitFactory.hh b/rce/rcecalib/dataproc/fit/FitFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..64c8e00470e90e614a692e1a13cf3a455ceb4651 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitFactory.hh @@ -0,0 +1,18 @@ +#ifndef FITFACTORY_HH +#define FITFACTORY_HH + +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/util/RceHisto1d.cc" + + +template<typename H, typename HE> +class FitFactory{ +public: + FitFactory(){} + + AbsFit *createFit(const char *type,ConfigIF *cif,std::vector<std::vector<RceHisto2d<H, HE>*> > &histo,std::vector<int> &vcal,int nTrigger,const char* name=""); + AbsFit *createFit(const char *type,ConfigIF *cif,std::vector<std::vector<RceHisto1d<H, HE>*> > &histo,std::vector<int> &vcal,int nTrigger,const char* name=""); + +}; +#endif diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.cc b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.cc new file mode 100644 index 0000000000000000000000000000000000000000..8d5e9d60cdd842d61578ff7972894acd951416bd --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.cc @@ -0,0 +1,822 @@ +#include "rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.hh" +#include "rcecalib/dataproc/fit/FitData.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <iostream> +#include <stdio.h> +#include "namespace_aliases.hh" +template<typename TP, typename TE> +FitScurveLikelihoodFastInt<TP, TE>::FitScurveLikelihoodFastInt(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal,int nTrigger,const char* name):AbsFit(cif,vcal,nTrigger),m_histo(histo),m_name(name) { + initFit(&m_fit); +} + +template<typename TP, typename TE> +FitScurveLikelihoodFastInt<TP, TE>::~FitScurveLikelihoodFastInt(){ + for(unsigned int module=0;module<m_fithisto.size();module++) { + for(size_t i=0;i<m_fithisto[module].size();i++){ + delete m_fithisto[module][i]; + } + } +} + + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::doFit(int fitopt) { + FitData pfdi,pfdo; + GaussianCurve gc; +#if 0 + clock_t starttime,endtime; + starttime= RceSvc::ticks(); +#endif + int nBins=m_vcal.size(); + if(!nBins) return -1; + m_x=new UINT32[nBins]; + m_y=new UINT8[nBins]; + + for(unsigned int module=0;module<m_config->getNmodules();module++) { + int nRows= m_config->getModuleInfo(module).getNRows(); + int nCols=m_config->getModuleInfo(module).getNColumns(); + //int nHistos=m_histo[module].size(); + std::cout << "nTrigger " << m_nTrigger << std::endl; + for(int chip=0;chip<m_config->getModuleInfo(module).getNFrontends();chip++) { + if((fitopt&NOCONV)==0) { + /* apply dac to electron calibration */ + for(int bin=0;bin<nBins;bin++) { + /* for now we use float here */ + m_x[bin]=(UINT32)(m_config->dacToElectrons(module,chip,m_vcal[bin])*10); + } + } else { + for(int bin=0;bin<nBins;bin++) { + /* for now we use float here */ + m_x[bin]=m_vcal[bin]*10; + } + } + for(int col=0;col<nCols;col++) { + for(int row=0;row<nRows;row++) { + // extract S-Curve + for(int bin=0;bin<nBins;bin++) { + m_y[bin]=(UINT8)(*m_histo[module][bin])(row, chip*nCols+col); + } + pfdi.n=nBins; + pfdi.x=&m_x[0]; + pfdi.y=&m_y[0]; + + int goodBins = extractGoodData(&pfdi,&pfdo,m_nTrigger); + int maxVal = m_nTrigger; + + if(goodBins<2){ + if(fitopt&XTALK){ + goodBins = roughFitRange(&pfdi,&pfdo,maxVal); + } + } + if(goodBins<2){ + continue; + } + + if(goodBins<5){ + m_fit.curve=&gc; + m_fit.maxIters=100; + int result = sGuess(&pfdo,&m_fit); + + if(!result) { + + int lastbin = pfdi.n-1; + float fitmu = (float)gc.mu/10.f; + float fitsigma = (float)gc.sigma/1000.f; + //exclude extreme fit results from the histograms + if(10*fitmu < 2*pfdi.x[lastbin] && 10*fitsigma < 2*(pfdi.x[lastbin]-pfdi.x[0])){ + + //std::cout<<"we guess mu = "<<(float)gc.mu/10.f<<" ; sigma = "<<(float)gc.sigma/1000.f<<std::endl; + m_fithisto[module][0]->set(chip*nCols+col,row,(float)gc.mu/10.f); + m_fithisto[module][1]->set(chip*nCols+col,row,(float)gc.sigma/1000.f); + m_fithisto[module][2]->set(chip*nCols+col,row,(float) m_fit.chi2/(float) (m_fit.ndf* 100)); + m_fithisto[module][3]->set(chip*nCols+col,row,(float) m_fit.nIters); + + } + + } + + } + else{ + + m_fit.curve=&gc; + m_fit.maxIters=100; + gc.a0=maxVal; + int result=fitPixel(&pfdo,&m_fit); + if(!result) { + int lastbin = pfdi.n-1; + float fitmu = (float)gc.mu/10.f; + float fitsigma = (float)4634050/(float) gc.sigma; + //exclude extreme fit results from the histograms + if(10*fitmu < 2*pfdi.x[lastbin] && 10*fitsigma < 2*(pfdi.x[lastbin]-pfdi.x[0])){ + // printf("%d %d %d %d %f %f %f %d\n",gc.a0,chip,col,row,gc.mu/10000.,4634040./gc.sigma,m_fit.chi2/100.,m_fit.nIters); + m_fithisto[module][0]->set(chip*nCols+col,row,(float)gc.mu/10.f); + m_fithisto[module][1]->set(chip*nCols+col,row,(float) 4634050/(float) gc.sigma); + m_fithisto[module][2]->set(chip*nCols+col,row,(float) m_fit.chi2/(float) (m_fit.ndf* 100)); + m_fithisto[module][3]->set(chip*nCols+col,row,(float) m_fit.nIters); + } + + } + } + + } //rows + } //columns + } //chips + } // modules + delete [] m_x; + delete [] m_y; +#if 0 + endtime= RceSvc::ticks(); + printf("total fit time %f\n",(float)(endtime-starttime)/350.); +#endif + return 0; +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodFastInt<TP, TE>::INT32 *FitScurveLikelihoodFastInt<TP, TE>::log_ext(INT32 x, INT32 mu,INT32 sigma) { + INT32 u; + + u=(x - mu)*sigma + sc_lut_width; //may be negative and larger than lut length + if(u<0) u=0; + if(u > sc_lut_length) u = sc_lut_length; //trancate + u>>=15; + u&=0xfffe; // we need the index should always be even + return (INT32*) &FitDataFastInt::data_logx[u]; +} + + + +template<typename TP, typename TE> +typename FitScurveLikelihoodFastInt<TP, TE>::UINT32 FitScurveLikelihoodFastInt<TP, TE>::errf_ext(INT32 x, GaussianCurve *psp) { + INT32 u; + u=(x - psp->mu)*psp->sigma + sc_lut_width; //it may be negative and may exceed LUT length + if(u < 0) u=0; + if(u > sc_lut_length) u=sc_lut_length; + u>>=16; + return FitDataFastInt::data_errf[u]; +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodFastInt<TP, TE>::UINT32 FitScurveLikelihoodFastInt<TP, TE>::logLikelihood(FitData *pfd, GaussianCurve *s) { + INT32 N; + UINT32 *x; + UINT8 *y; + UINT32 acc; + INT32 *p; + UINT32 k; + INT32 mu,sigma; + mu=s->mu; + sigma=s->sigma; + + x = pfd->x; + y = pfd->y; + acc = 0; + N = s->a0; + for(k=0; k<pfd->n; ++k) + { + p = log_ext(*x++,mu,sigma); /* pointer to log(probability) */ + acc -= ((s->a0-(*y))*(*(p+1))+(*y)*(*p)); + y++; + } + return acc; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::initFit(Fit *pFit) { + pFit->maxIters = 100; + pFit->muEpsilon = 50; /* 0.01% */ + pFit->sigmaEpsilon = 50; /* 0.01% */ + for (unsigned int i=0;i<m_config->getNmodules();i++){ + std::vector<RceHisto2d<float, float>*> vh; + m_fithisto.push_back(vh); + char name[128]; + char title[128]; + char suffix[128]=""; + if(std::string(m_name)!=""){ + sprintf(suffix,"%s_",m_name); + } + + int rows=m_config->getModuleInfo(i).getNRows(); + int cols=m_config->getModuleInfo(i).getNColumns()*m_config->getModuleInfo(i).getNFrontends(); + int id=m_config->getModuleInfo(i).getId(); + std::string modName=m_config->getModuleInfo(i).getName(); + sprintf(name,"Mod_%d_%sMean", id, suffix); + sprintf(title,"MOD %d %s at %s SCURVE MEAN", id, suffix, modName.c_str()); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE SIGMA", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sSigma", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE CHI2", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sChiSquare", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE ITER", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sIter", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + } + return 0; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::extractGoodData(FitData *pfdi,FitData *pfdo, UINT32 nTriggers) { + int hitsStart, hitsEnd, nBins; + UINT32 a0; + UINT8 *y; + + nBins = pfdi->n; + y = pfdi->y; + + //new method to find hitsStart + + for(hitsStart = nBins-1;hitsStart >= 0; --hitsStart) + if(y[hitsStart] == 0) break; + + if(hitsStart ==0) + return 0; + if(hitsStart == nBins) + return 0; + + a0 = y[nBins - 1]; // last bin has at least 90% hits + if(a0*999 < nTriggers*900) + return 0; + //failure mode, never reaches A0 + + //dan's new method + for(hitsEnd = hitsStart; hitsEnd < nBins; ++hitsEnd) + if(y[hitsEnd] >= a0) break; + + // add 2 for old method or 1 for new method + // 1 because of where we start comparing and + // 1 because we want to include one instance of the maximum + nBins = 1 + hitsEnd - hitsStart; + + if(hitsStart < 0) hitsStart =0; + + if(hitsStart == hitsEnd) return 0; + + if(nBins < 2) { + return 0; + //failure mode :: not enough data points + } + if(nBins < 0) nBins = 0; + pfdo->n = nBins; + pfdo->y = &y[hitsStart]; + pfdo->x = &pfdi->x[hitsStart]; + return nBins; +} + + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::initialGuess(FitData *pfd, GaussianCurve *pSParams) { + + + UINT32 pt1, pt2, pt3; + UINT8 *pdlo; + UINT32 y_lo, sigma; + UINT32 *x; + UINT8 *y; + UINT32 a0; + UINT32 minSigma; + UINT32 k, n, lo1, lo2, lo3, status; + UINT32 x1,x2,x3; + INT32 xdiff; + + n = pfd->n; + if(n<5) return 1; + pSParams->a0 = pfd->y[pfd->n-1]; // assumes last data point sets plateau + a0 = pSParams->a0; + xdiff=pfd->x[1] - pfd->x[0]; + minSigma = (xdiff*2897)>>12; //This is actually division by sqrt of 2 + x = pfd->x; y = pfd->y; + pt1 = (16* a0)/100; + pt2 = (50* a0)/100; + pt3 = (84* a0)/100; + // find the range over which the data crosses the 16%, 50% and 84% points + lo1 = lo2 = lo3 = 0; // invalid values + pdlo = &y[0]; // y + for(k=0;k<n;++pdlo) + { + y_lo = *pdlo; + if(!lo1 && (y_lo >= pt1)) lo1 = k; + if(!lo2 && (y_lo >= pt2)) lo2 = k; + if(!lo3 && (y_lo >= pt3)) lo3 = k; + ++k; + } +// printf("sGuess lo1=%d lo2=%d lo3=%d \n",lo1,lo2,lo3); + x1 = (x[lo1] + x[lo1-1]) >> 1; + x2 = (x[lo2] + x[lo2-1]) >> 1; + x3 = (x[lo3] + x[lo3-1]) >> 1; +// printf("sGuess x1 x2 x3 %d %d %d\n",x1, x2,x3); + + // mu = threshold + + pSParams->mu = (UINT32) x2; + xdiff=(x3 - x1); + sigma = (xdiff*2897)>>12; //This is actually division by sqrt of 2 + if(sigma < minSigma) { + sigma = minSigma; + } + // change for inv sigma + pSParams->sigma=65536000/sigma; // do division *here* for speed; use large factor to prevent truncation; unclear this is large enough + status = 0; + return status; + +} +#define DMUMUL 50 +#define DSIGMUL 200 +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::fitPixel(FitData *pfd,void *vpfit) { + INT32 deltaSigma, deltaMu, sigma, chi2Min, *fptr; + INT32 chi2[9]; + GaussianCurve sParams, sParamsWork, *psp; + int muEpsilon,sigmaEpsilon; + int k, dirMin; + Fit *pFit; + pFit = (Fit *)vpfit; + + pFit->nIters = 0; + pFit->converge = 0; // assume no convergence + muEpsilon = pFit->muEpsilon; + sigmaEpsilon = pFit->sigmaEpsilon; + + pFit->ndf = pfd->n - 2; // degrees of freedom + // take a guess at the S-curve parameters + + if(initialGuess(pfd,&sParams)) + { + psp = (GaussianCurve *)pFit->curve; + psp->a0 = sParams.a0; + psp->mu = sParams.mu; + psp->sigma = sParams.sigma; + pFit->converge = 1; + pFit->chi2 = 0; + return 0; + } + + // initialize loop parameters + psp = &sParamsWork; + psp->a0 = sParams.a0; + deltaSigma = (sParams.sigma*DSIGMUL)/1000 ; // scaled estimated value + deltaMu = (sParams.mu*DMUMUL)/1000 ; // scaled estimated value + + // the loop begins + + while(!pFit->converge && (pFit->nIters++ < pFit->maxIters)) + { + dirMin = 0; + fptr = chi2; + for(k=0;k<9;++k) *fptr++ = 0; + while((dirMin >= 0) && (pFit->nIters++ < pFit->maxIters)) + { + // * calculate neighboring points * + + psp->sigma=sParams.sigma - deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[0] == 0) chi2[0] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[7] == 0) chi2[7] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[6] == 0) chi2[6] = logLikelihood(pfd,psp); + psp->sigma=sParams.sigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[1] == 0) chi2[1] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[8] == 0) chi2[8] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[5] == 0) chi2[5] = logLikelihood(pfd,psp); + psp->sigma=sParams.sigma+deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[2] == 0) chi2[2] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[3] == 0)chi2[3] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[4] == 0) chi2[4] = logLikelihood(pfd,psp); + + dirMin = -1; + chi2Min = chi2[8]; // first guess at minimum + for(k=0, fptr=chi2; k<8; ++k, ++fptr) + { + if(*fptr < chi2Min) + { + chi2Min = *fptr; + dirMin = k; + } + } +// printf("chi2: %d %d %d %d %d %d %d %d %d\n", +// chi2[0],chi2[1],chi2[2],chi2[3],chi2[4],chi2[5],chi2[6],chi2[7],chi2[8]); + switch(dirMin) + { + case -1: + if(!pFit->converge) + { + deltaSigma = deltaSigma >> 3; + deltaMu = deltaMu >> 3; + } + break; + case 0: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[0]; + chi2[3] = chi2[1]; + chi2[4] = chi2[8]; + chi2[5] = chi2[7]; + chi2[0] = chi2[1] = chi2[2] = + chi2[6] = chi2[7] = 0; + break; + case 1: + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[1]; + chi2[3] = chi2[2]; + chi2[4] = chi2[3]; + chi2[5] = chi2[8]; + chi2[6] = chi2[7]; + chi2[7] = chi2[0]; + chi2[0] = chi2[1] = chi2[2] = 0; + break; + case 2: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[2]; + chi2[5] = chi2[3]; + chi2[6] = chi2[8]; + chi2[7] = chi2[1]; + chi2[0] = chi2[1] = chi2[2] = + chi2[3] = chi2[4] = 0; + break; + case 3: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[3]; + chi2[5] = chi2[4]; + chi2[6] = chi2[5]; + chi2[7] = chi2[8]; + chi2[0] = chi2[1]; + chi2[1] = chi2[2]; + chi2[2] = chi2[3] = chi2[4] = 0; + break; + case 4: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[4]; + chi2[7] = chi2[5]; + chi2[0] = chi2[8]; + chi2[1] = chi2[3]; + chi2[2] = chi2[3] = chi2[4] = + chi2[5] = chi2[6] = 0; + break; + case 5: + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[5]; + chi2[7] = chi2[6]; + chi2[0] = chi2[7]; + chi2[1] = chi2[8]; + chi2[2] = chi2[3]; + chi2[3] = chi2[4]; + chi2[4] = chi2[5] = chi2[6] = 0; + break; + case 6: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[6]; + chi2[1] = chi2[7]; + chi2[2] = chi2[8]; + chi2[3] = chi2[5]; + chi2[4] = chi2[5] = chi2[6] = + chi2[7] = chi2[0] = 0; + break; + case 7: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[7]; + chi2[1] = chi2[0]; + chi2[2] = chi2[1]; + chi2[3] = chi2[8]; + chi2[4] = chi2[5]; + chi2[5] = chi2[6]; + chi2[6] = chi2[7] = chi2[0] = 0; + break; + } //end switch + } // end while dirMin >= 0 + if((deltaSigma < sigmaEpsilon) && (deltaMu < muEpsilon)) + { + pFit->converge = 1; + break; + } + } // end while !pFit->converge + psp = (GaussianCurve *)pFit->curve; + *psp = sParams; + pFit->chi2 = chiSquared(pfd,psp); + + // tot_itt+=pFit->nIters; + return pFit->converge ? 0 : 1; // 0 = success + +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodFastInt<TP, TE>::UINT32 FitScurveLikelihoodFastInt<TP, TE>::chiSquared(FitData *pfd,GaussianCurve *s) { + UINT32 acc,y3; + INT32 y0,y1,y2; + UINT32 a0, chi2; + UINT32 *x; + UINT8 *y; + INT32 x0; + int j, k, n; + + x = pfd->x; + y = pfd->y; + n = pfd->n; + acc = 0; + a0 = s->a0; + // use binomial weighting + for(k=0;k<n;++k) { + x0 = *x++; + y0 =(INT32) *y++; + y1 = errf_ext(x0,s); + j=y1>>10; + y2 = y0*1000 - (a0 * j); + y2/=100; + y3=(UINT32) (y2*y2); + y3*=FitDataFastInt::binomial_weight[j]; + y3>>=7; + acc+=y3; + + } + chi2=acc/a0; + return chi2; +} + + + +//Modified from /DAQ/IBLDAQ-0-0-0/RodDaq/NewDsp/SLAVE/fittingRoutines.c + +// \brief Guess S curve + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::sGuess(FitData *pfd, void *vpfit) { + + int j, k, n, lo1, lo2, lo3, hi1, hi2, hi3, status; + UINT32 *x, a0, minSigma, sigma, pt1, pt2, pt3, x1, x2, x3, hits, y_lo, y_hi; + UINT8 *y, *pdlo, *pdhi; + + +// clock_t time1,time2; +// #ifdef ppc405 +// time1= RceSvc::ticks(); +// #endif + + n = pfd->n; + + status = 1; //1: failure + + if(n<2){ + return 1; //not enough points + } + + UINT32 invroot6 = 4082; + + // std::cout<<"doing sGuess with n = "<<n<<std::endl; + + GaussianCurve *sParams; + + Fit *pFit; + pFit = (Fit *)vpfit; + + pFit->nIters = 0; + pFit->converge = 0; // assume no convergence + + sParams = (GaussianCurve *)pFit->curve; + + sParams->a0 = pfd->y[n-1]; // assumes last data point sets plateau + + +// for(int i=0; i<n; i++){ +// std::cout<<" "<<pfd->x[i]<<" ;"; +// } +// std::cout<<" | "; +// for(int i=0; i<n; i++){ +// std::cout<<" "<<(unsigned int)pfd->y[i]<<" ;"; +// } +// std::cout<<std::endl; + + a0 = sParams->a0; + + + minSigma = (pfd->x[1] - pfd->x[0]) * invroot6 / 100; +// std::cout<<"minSigma = "<<minSigma<<std::endl; + + if(n == 2) { + // no interesting data point + sParams->mu = (5 * (pfd->x[1] + pfd->x[0]) ) / 10; + sigma = minSigma; // we do not have accurate information + status = 0; + } else if(n == 3) { + // one interesting data point + // aSquared = a0 * a0; + hits = pfd->y[1]; + + // this next part is voodoo. being at such small number of interesting points, + //the maximum likelihood lies along a curve. Intuitively, we have a feel for where + ///the mean and sigma go. sigma varies continuously between sigma0 and 2 * sigma0, + //sigma0 = bin / root(6) + sigma = minSigma; + + INT32 factor = 400000*hits/a0; + factor *= (a0 - hits)/a0; + // std::cout<<"a0 = "<<a0<<" ; hits = "<<hits<<" ; factor = "<<factor<<std::endl; + + // sigma = sigma * ( 1.0f + 4.0f * hits * (a0 - hits) / aSquared ); + + factor = (100000 + factor)/1000; + // std::cout<<"now, factor = "<<factor<<" ; sigma = "<<sigma<<std::endl; + + sigma = (sigma/10) * factor; // we now have sigma(*100)(*100) + sigma = sigma/10; //we now have sigma*1000 + + + //crude estimate for mu, based on linear extrapolation + pt1 = 5 * a0; + hits = hits * 10; + + if(hits > pt1){ + lo1 = 0; + hi1 = 1; + } + else{ + lo1 = 1; + hi1 = 2; + } + + y_lo = pfd->y[lo1]; + y_hi = pfd->y[hi1]; + + x1 = pfd->x[lo1]; + x2 = pfd->x[hi1]; + + + INT32 invslope = (1000*(x2-x1))/ (y_hi-y_lo); // 10000/slope + + // std::cout<<"1/m = "<<invslope<<" pt1 = "<<pt1<<" ; y_l0 = "<<y_lo<<std::endl; + + sParams->mu = (pt1 - 10*y_lo) * invslope / 10000 + x1; + + // std::cout<<"mu = "<<sParams->mu<<std::endl; + + status = 0; + } + else { + x = pfd->x; y = pfd->y; + pt1 = 16 * a0; + pt2 = 50 * a0; + pt3 = 84 * a0; + // find the range over which the data crosses the 16%, 50% and 84% points + hi1 = hi2 = hi3 = 0; // invalid values + lo1 = lo2 = lo3 = 0; // invalid values + pdlo = &y[0]; // y + pdhi = &y[n-1]; // y + n - 1 + // important note: for the sake of speed we want to perform as few comparisons as + //possible. Therefore, the integer comparison occurs first in each of the + //following operations. Depending on the logical value thereof, the next + //comparison will be made only if necessary. To further expedite the code, + //arrays are not used because there are only three members + j = n - 1; + for(k=0;k<n;++pdlo, --pdhi) { + y_lo = *pdlo; + y_hi = *pdhi; + + y_lo = y_lo * 100; + y_hi = y_hi * 100; + + if(!lo1 && (y_lo >= pt1)) lo1 = k; + if(!lo2 && (y_lo >= pt2)) lo2 = k; + if(!lo3 && (y_lo >= pt3)) lo3 = k; + if(!hi1 && (y_hi <= pt1)) hi1 = j; + if(!hi2 && (y_hi <= pt2)) hi2 = j; + if(!hi3 && (y_hi <= pt3)) hi3 = j; + --j; + ++k; + } + + +// std::cout<<"xlo = "<<x[lo1]<<" ; "<<x[lo2]<<" ; "<<x[lo3]<<std::endl; +// std::cout<<"xhi = "<<x[hi1]<<" ; "<<x[hi2]<<" ; "<<x[hi3]<<std::endl; + + + x1 = (x[lo1] + x[hi1]) / 2; + x2 = (x[lo2] + x[hi2]) / 2; + x3 = (x[lo3] + x[hi3]) / 2; + +// std::cout<<"x(1,2,3) = "<<x1<<" ; "<<x2<<" ; "<<x3<<std::endl; + + + // mu = threshold + + sParams->mu = x2; + sigma = ( (x3 - x1) * 7071 ) / 100; + + if(sigma < minSigma) { + sigma = minSigma; + } + + status = 0; + } + + + sParams->sigma= sigma; // this should actually be 1000 * sigma. + + // std::cout<<"mu = "<<sParams->mu<<" ; sigma = "<<sigma<<std::endl; + +// #ifdef ppc405 +// time2= RceSvc::ticks(); +// printf("sGuess fit time %f\n",(float)(time2-time1)/350.); +// #endif + + + return status; //0 = success + + +} + + +template<typename TP, typename TE> +int FitScurveLikelihoodFastInt<TP, TE>::roughFitRange(FitData *pfdi, FitData *pfdo, int& maxVal) { + //For use in crosstalk scan. Determines the start and end of the fit range, without requirement + //that the data y-values reach a plateau close to the number of triggers. + //Sets maxVal to the highest y-value in the data, and the start and end of the fit range are + //the points where y<0.2*maxVal and y>0.8*maxVal, respectively. + + + int nBins, status; + UINT32 *x; + UINT8 *y; + + status = 1; //1: failure + + int hitsStart, hitsEnd; + + nBins = pfdi->n; + y = pfdi->y; + x = pfdi->x; + + for(hitsStart = 0; hitsStart < nBins; ++hitsStart){ + if(y[hitsStart] != 0) break; + } + + if(hitsStart == (nBins-1)) //require more than one bin containing hits + return status; + if(hitsStart == 0) //require first bin to be empty + return status; + + if(y[nBins - 1] ==0){ //require hits in final bin + return status; + } + + + maxVal=0; + //set maxVal equal to highest y value + for(int iBin = nBins-1; iBin >= 0; --iBin){ + if(y[iBin] > maxVal){ + maxVal = y[iBin]; + hitsEnd = iBin; + } + } + + if(hitsEnd<hitsStart){ + return status; + } + + int firstBin=0, lastBin=0; + + //std::cout<<"hitsStart = "<<hitsStart<<" ; hitsEnd = "<<hitsEnd<<std::endl; + + for(int iBin = (hitsStart-1); iBin <=hitsEnd; ++iBin){ + if(y[iBin] >= 0.8*maxVal){ + lastBin = iBin; + break; + } + } + + for(int iBin = (hitsStart-1); iBin <=hitsEnd; ++iBin){ + if(y[iBin] >= 0.2*maxVal){ + firstBin = iBin-1; + break; + } + } + + // std::cout<<"firstBin = "<<firstBin<<" ; LastBin = "<<lastBin<<std::endl; + + if(firstBin>=lastBin){ + return status; + } + + //Successfully determined first and last bin + nBins = 1 + lastBin - firstBin; + + pfdo->n = nBins; + pfdo->y = &y[firstBin]; + pfdo->x = &x[firstBin]; + + return nBins; + +} diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.hh b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.hh new file mode 100644 index 0000000000000000000000000000000000000000..1e92a06bfb5d854f2a2682b3196937b0609e303a --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFastInt.hh @@ -0,0 +1,77 @@ +#ifndef FITSCURVELIKELIHOODFASTINT_HH +#define FITSCURVELIKELIHOODFASTINT_HH +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include "rcecalib/util/RceHisto2d.cc" +#include <vector> + +template<typename TP, typename TE> +class FitScurveLikelihoodFastInt:public AbsFit { + +typedef unsigned int UINT32; +typedef int INT32; +typedef unsigned long long UINT64; +typedef long long INT64; +typedef unsigned char UINT8; + +typedef struct FitData_ +{ + UINT32 n; + UINT32 *x; + UINT8 *y; +} FitData; + +typedef struct FitResult_ +{ + INT32 ndf; + INT32 mu0; + INT32 sigma; //inverted sigma + INT32 chi2; +} FitResult; + +typedef struct GaussianCurve_ +{ + UINT32 mu, a0; + UINT32 sigma; +} GaussianCurve; + +typedef struct { + INT32 muEpsilon; + INT32 sigmaEpsilon; /* user provides convergence criterion */ + INT32 nIters; + INT32 ndf; /* number of degrees of freedom */ + INT32 chi2; /* final result for chi2 */ + INT32 converge; + INT32 maxIters; + void *curve; +} Fit; +#define sc_lut_width (FAST_LUT_WIDTH << 16) +#define logx_length (2*FAST_LUT_LENGTH) +#define sc_lut_length ((FAST_LUT_LENGTH - 1) << 16) + +public: +FitScurveLikelihoodFastInt(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal, int nTrigger, const char* name=""); + ~FitScurveLikelihoodFastInt(); + int doFit(int); +protected: + inline INT32 *log_ext(INT32 x, INT32 mu,INT32 sigma); + UINT32 errf_ext(INT32 x, GaussianCurve *psp); + inline UINT32 logLikelihood(FitData *pfd, GaussianCurve *s); + int initFit(Fit *pFit); + int extractGoodData(FitData *pfdi,FitData *pfdo, UINT32 nTriggers); + int initialGuess(FitData *pfd, GaussianCurve *pSParams); + int fitPixel(FitData *pfd,void *vpfit); + UINT32 chiSquared(FitData *pfd,GaussianCurve *s); + int sGuess(FitData *pfd, void *vpfit); + int roughFitRange(FitData *pfdi, FitData *pfdo, int& maxVal); + Fit m_fit; + UINT32 *m_x; + UINT8 *m_y; + std::vector<std::vector<RceHisto2d<TP, TE>*> > &m_histo; + std::vector<std::vector<RceHisto2d<float, float>*> > m_fithisto; + const char* m_name; + +}; + + + +#endif diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.cc b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.cc new file mode 100644 index 0000000000000000000000000000000000000000..ff99f23e72f238386825e187f9980b17306d665a --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.cc @@ -0,0 +1,461 @@ +#include "rcecalib/dataproc/fit/FitScurveLikelihoodFloat.hh" +#include "rcecalib/dataproc/fit/FitData.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <stdio.h> +#include <iostream> + +template<typename TP, typename TE> +FitScurveLikelihoodFloat<TP, TE>::FitScurveLikelihoodFloat(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal,int nTrigger):AbsFit(cif,vcal,nTrigger),m_histo(histo) { + initFit(&m_fit); +} + +template<typename TP, typename TE> +FitScurveLikelihoodFloat<TP, TE>::~FitScurveLikelihoodFloat() +{ + for(unsigned int module=0;module<m_config->getNmodules();module++) { + for(size_t i=0;i<m_fithisto[module].size();i++){ + delete m_fithisto[module][i]; + } + } +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFloat<TP, TE>::doFit() { + FitData pfdi,pfdo; + GaussianCurve gc; + int nBins=m_vcal.size(); + if(!nBins) return -1; + m_x=new float[nBins]; + m_y=new float[nBins]; + + for(unsigned int module=0;module<m_config->getNmodules();module++) { + int nRows= m_config->getModuleInfo(module).getNRows(); + int nCols=m_config->getModuleInfo(module).getNColumns(); + //int nHistos=m_histo[module].size(); + std::cout << "nTrigger " << m_nTrigger << std::endl; + for(int chip=0;chip<m_config->getModuleInfo(module).getNFrontends();chip++) { + /* apply dac to electron calibration */ + for(int bin=0;bin<nBins;bin++) { + m_x[bin]=m_config->dacToElectrons(module,chip,m_vcal[bin]); + } + for(int col=0;col<nCols;col++) { + for(int row=0;row<nRows;row++) { + // extract S-Curve + for(int bin=0;bin<nBins;bin++) { + m_y[bin]=(*m_histo[module][bin])(row, chip*nCols+col); + } + pfdi.n=nBins; + pfdi.x=&m_x[0]; + pfdi.y=&m_y[0]; + int goodBins=extractGoodData(&pfdi,&pfdo,m_nTrigger); + if(goodBins<5) continue; + m_fit.curve=&gc; + m_fit.maxIters=100; + gc.a0=m_nTrigger; + int result=fitPixel(&pfdo,&m_fit); + if(!result) { + m_fithisto[module][0]->set(chip*nCols+col,row,gc.mu); + m_fithisto[module][1]->set(chip*nCols+col,row,gc.sigma); + m_fithisto[module][2]->set(chip*nCols+col,row,m_fit.chi2); + m_fithisto[module][3]->set(chip*nCols+col,row,(float) m_fit.nIters); + printf("%d %d %d %f %f %f %d\n",chip,col,row,gc.mu,gc.sigma,m_fit.chi2,m_fit.nIters); + } + } //rows + } //columns + } //chips + } // modules + delete [] m_x; + delete [] m_y; + return 0; +} +template<typename TP, typename TE> +float* FitScurveLikelihoodFloat<TP, TE>::log_ext(float x, GaussianCurve *psp) { + float u, t; + int n; + u = (x - psp->mu) / psp->sigma; + t = u * inverse_lut_interval; + n = LUT_WIDTH + (int)t; + if(n < 0) n = 0; + if(n >= LUT_LENGTH) n = LUT_LENGTH-1; // truncate at last value + n = 2 * n; + return (float*)&FitDataFloat::data_logx[n]; +} +template<typename TP, typename TE> +float FitScurveLikelihoodFloat<TP, TE>::errf_ext(float x, GaussianCurve *psp) { + float u, t; + int n; + + u = (x - psp->mu) / psp->sigma; + t = u * inverse_lut_interval; + n = LUT_WIDTH + (int)t; + if(n < 0) n = 0; + if(n >= LUT_LENGTH) n = LUT_LENGTH-1; // truncate at last value + return FitDataFloat::data_errf[n]; +} +template<typename TP, typename TE> +float FitScurveLikelihoodFloat<TP, TE>::logLikelihood(FitData *pfd, GaussianCurve *s) { + float acc, r, y2, y3, N; + float *x, *y, *p; + int k, n; + x = pfd->x; y = pfd->y; n = pfd->n; + acc = 0.0f; + N = s->a0; + for(k=0;k<n;++k) { + r = *y++; /* data point */ + p = log_ext(*x++,s); /* pointer to log(probability) */ + y2 = r * (*p++); /* log(prob) */ + y3 = (N - r) * (*p); /* log(1-prob) */ + acc -= (y2 + y3); + } + return acc; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFloat<TP, TE>::initFit(Fit *pFit) { + pFit->deltaSigma = 0.1f; + pFit->deltaMu = 0.1f; + pFit->maxIters = 100; + pFit->muEpsilon = 0.0001f; /* 0.01% */ + pFit->sigmaEpsilon = 0.0001f; /* 0.01% */ + /* create histograms */ + for (unsigned int i=0;i<m_config->getNmodules();i++){ + std::vector<RceHisto2d<float, float>*> vh; + m_fithisto.push_back(vh); + char name[128]; + //char title[128]; + int rows=m_config->getModuleInfo(i).getNRows(); + int cols=m_config->getModuleInfo(i).getNColumns()*m_config->getModuleInfo(i).getNFrontends(); + int id=m_config->getModuleInfo(i).getId(); + sprintf(name,"Mod_%d_Mean",id); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,"SCURVE_MEAN",cols,0,cols,rows, 0, rows)); + sprintf(name,"Mod_%d_Sigma",id); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,"SCURVE_SIGMA",cols,0,cols,rows, 0, rows)); + sprintf(name,"Mod_%d_ChiSquare",id); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,"SCURVE_CHI2",cols,0,cols,rows, 0, rows)); + sprintf(name,"Mod_%d_Iter",id); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,"SCURVE_ITER",cols,0,cols,rows, 0, rows)); + } + // allocate fit data buffer + + + return 0; +} +template<typename TP, typename TE> +int FitScurveLikelihoodFloat<TP, TE>::extractGoodData(FitData *pfdi,FitData *pfdo, float scanA0) { + int hitsStart, hitsEnd, nBins; + float a0, *y; + + nBins = pfdi->n; + y = pfdi->y; + + //new method to find hitsStart + for(hitsStart = nBins-1;hitsStart >= 0; --hitsStart) + if(y[hitsStart] == 0) break; + + if(hitsStart ==0) + return 0; + if(hitsStart == nBins) + return 0; + a0 = 0.999f * y[nBins - 1]; // just under last bin + if(a0 < 0.9 * scanA0) + return 0; + //failure mode, never reaches A0 + + for(hitsEnd = hitsStart; hitsEnd < nBins; ++hitsEnd) + if(y[hitsEnd] > a0) break; + nBins = 1 + hitsEnd - hitsStart; + if(hitsStart < 0) + hitsStart =0; + + if(hitsStart == hitsEnd) + return 0; + + if(nBins < 2) { + return 0; + //failure mode :: not enough data points + } + if(nBins < 0) nBins = 0; + pfdo->n = nBins; + + pfdo->y = &y[hitsStart]; + pfdo->x = &pfdi->x[hitsStart]; + return nBins; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFloat<TP, TE>::initialGuess(FitData *pfd, GaussianCurve *pSParams){ +#define invRoot6f 0.40824829046f +#define invRoot2f 0.7071067811f + float pt1, pt2, pt3, *pdlo, *pdhi, y_lo, y_hi, x1, x2, x3, sigma; + float *x, *y, a0, minSigma; + int j, k, n, lo1, lo2, lo3, hi1, hi2, hi3, status; + + pSParams->a0 = pfd->y[pfd->n-1]; // assumes last data point sets plateau + a0 = pSParams->a0; + a0 -= 0.00001f; // skim a token amount to ensure comparisons succeed + + n = pfd->n; // number of samples + + minSigma = (pfd->x[1] - pfd->x[0]) * invRoot6f; + + x = pfd->x; y = pfd->y; + pt1 = 0.16f * a0; + pt2 = 0.50f * a0; + pt3 = 0.84f * a0; + // find the range over which the data crosses the 16%, 50% and 84% points + hi1 = hi2 = hi3 = 0; // invalid values + lo1 = lo2 = lo3 = 0; // invalid values + pdlo = &y[0]; // y + pdhi = &y[n-1]; // y + n - 1 + // important note: for the sake of speed we want to perform as few comparisons as + //possible. Therefore, the integer comparison occurs first in each of the + //following operations. Depending on the logical value thereof, the next + //comparison will be made only if necessary. To further expedite the code, + //arrays are not used because there are only three members + j = n - 1; + for(k=0;k<n;++pdlo, --pdhi) { + y_lo = *pdlo; + y_hi = *pdhi; + if(!lo1 && (y_lo >= pt1)) lo1 = k; + if(!lo2 && (y_lo >= pt2)) lo2 = k; + if(!lo3 && (y_lo >= pt3)) lo3 = k; + if(!hi1 && (y_hi <= pt1)) hi1 = j; + if(!hi2 && (y_hi <= pt2)) hi2 = j; + if(!hi3 && (y_hi <= pt3)) hi3 = j; + --j; + ++k; + } + x1 = (x[lo1] + x[hi1]) * 0.5f; + x2 = (x[lo2] + x[hi2]) * 0.5f; + x3 = (x[lo3] + x[hi3]) * 0.5f; + + pSParams->mu = x2; + + sigma = (x3 - x1) * invRoot2f; + + if(sigma < minSigma) { + sigma = minSigma; + } + pSParams->sigma=sigma; + status = 0; + + return status; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodFloat<TP, TE>::fitPixel(FitData *pfd,void *vpfit) +{ + float deltaSigma, deltaMu, sigma, chi2Min, *fptr; + float chi2[9]; + GaussianCurve sParams, sParamsWork, *psp; + int k, dirMin; + Fit *pFit; + pFit = (Fit *)vpfit; + + pFit->nIters = 0; + pFit->converge = 0; // assume no convergence + + pFit->ndf = pfd->n - 2; // degrees of freedom + + // take a guess at the S-curve parameters + + if(initialGuess(pfd,&sParams)) { + psp = (GaussianCurve *)pFit->curve; + psp->a0 = sParams.a0; + psp->mu = sParams.mu; + psp->sigma = sParams.sigma; + pFit->converge = 1; + pFit->muConverge = 0; + pFit->sigmaConverge = 0; + pFit->chi2 = 0.0f; + return 0; + } + + // initialize loop parameters + psp = &sParamsWork; + psp->a0 = sParams.a0; + deltaSigma = pFit->deltaSigma * sParams.sigma; // scaled + deltaMu = pFit->deltaMu * sParams.mu; // scaled + //* the loop begins * + // printf("delta %f %f\n",deltaSigma,deltaMu); + while(!pFit->converge && (pFit->nIters++ < pFit->maxIters)) { + + dirMin = 0; + fptr = chi2; + for(k=0;k<9;++k) *fptr++ = 0.0f; + + while((dirMin >= 0) && (pFit->nIters++ < pFit->maxIters)) { + //* calculate neighboring points * + //* calculate neighboring points * + psp->sigma=sParams.sigma - deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[0] == 0.0f) + chi2[0] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[7] == 0.0f) + chi2[7] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[6] == 0.0f) + chi2[6] = logLikelihood(pfd,psp); + + psp->sigma=sParams.sigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[1] == 0.0f) + chi2[1] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[8] == 0.0f) + chi2[8] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[5] == 0.0f) + chi2[5] = logLikelihood(pfd,psp); + + psp->sigma=sParams.sigma+deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[2] == 0.0f) + chi2[2] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[3] == 0.0f) + chi2[3] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[4] == 0.0f) + chi2[4] = logLikelihood(pfd,psp); + + dirMin = -1; + chi2Min = chi2[8]; // first guess at minimum + for(k=0, fptr=chi2;k<8;++k, ++fptr) { + if(*fptr < chi2Min) { + chi2Min = *fptr; + dirMin = k; + } + } + switch(dirMin) { + case -1: + deltaSigma = deltaSigma * 0.1f; + deltaMu = deltaMu * 0.1f; + break; + case 0: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[0]; + chi2[3] = chi2[1]; + chi2[4] = chi2[8]; + chi2[5] = chi2[7]; + chi2[0] = chi2[1] = chi2[2] = + chi2[6] = chi2[7] = 0.0f; + break; + case 1: + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[1]; + chi2[3] = chi2[2]; + chi2[4] = chi2[3]; + chi2[5] = chi2[8]; + chi2[6] = chi2[7]; + chi2[7] = chi2[0]; + chi2[0] = chi2[1] = chi2[2] = 0.0f; + break; + case 2: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[2]; + chi2[5] = chi2[3]; + chi2[6] = chi2[8]; + chi2[7] = chi2[1]; + chi2[0] = chi2[1] = chi2[2] = + chi2[3] = chi2[4] = 0.0f; + break; + case 3: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[3]; + chi2[5] = chi2[4]; + chi2[6] = chi2[5]; + chi2[7] = chi2[8]; + chi2[0] = chi2[1]; + chi2[1] = chi2[2]; + chi2[2] = chi2[3] = chi2[4] = 0.0f; + break; + case 4: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[4]; + chi2[7] = chi2[5]; + chi2[0] = chi2[8]; + chi2[1] = chi2[3]; + chi2[2] = chi2[3] = chi2[4] = + chi2[5] = chi2[6] = 0.0f; + break; + case 5: + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[5]; + chi2[7] = chi2[6]; + chi2[0] = chi2[7]; + chi2[1] = chi2[8]; + chi2[2] = chi2[3]; + chi2[3] = chi2[4]; + chi2[4] = chi2[5] = chi2[6] = 0.0f; + break; + case 6: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[6]; + chi2[1] = chi2[7]; + chi2[2] = chi2[8]; + chi2[3] = chi2[5]; + chi2[4] = chi2[5] = chi2[6] = + chi2[7] = chi2[0] = 0.0f; + break; + case 7: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[7]; + chi2[1] = chi2[0]; + chi2[2] = chi2[1]; + chi2[3] = chi2[8]; + chi2[4] = chi2[5]; + chi2[5] = chi2[6]; + chi2[6] = chi2[7] = chi2[0] = 0.0f; + break; + } + } + + if(deltaSigma < (pFit->sigmaEpsilon * sParams.sigma) && + deltaMu < (pFit->muEpsilon * sParams.mu)) { + pFit->converge = 1; + break; + } + } + psp = (GaussianCurve *)pFit->curve; + *psp = sParams; + pFit->chi2=chiSquared(pfd,psp)/(float) pFit->ndf; + //static int d=0; + + // printf("%f %f %f \n",psp->mu,psp->sigma,pFit->chi2); + + return pFit->converge ? 0 : 1; // 0 = success +} +template<typename TP, typename TE> +float FitScurveLikelihoodFloat<TP, TE>::chiSquared(FitData *pfd,GaussianCurve *s) { + float acc, y0,y1,y2,y3, a0, chi2; + float *x, *y; + float x0; + int j, k, n; + x = pfd->x; y = pfd->y; n = pfd->n; + acc = 0.0f; + a0 = s->a0; + /* use binomial weighting */ + for(k=0;k<n;++k) { + x0 = *x++; + y0 = *y++; + y1 = errf_ext(x0,s); + j = (int)(y1 * inverse_weight_lut_interval); + y2 = y0 - a0 * y1; + y3 = y2 * y2; + acc += (y3 * FitDataFloat::binomial_weight[j]); + } + chi2 = acc/ a0; + return chi2; +} diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.hh b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.hh new file mode 100644 index 0000000000000000000000000000000000000000..5c63d3cb8dee57bde2a69b69e99853c0afd903c9 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodFloat.hh @@ -0,0 +1,57 @@ +#ifndef FITSCURVELIKELIHOODFLOAT_HH +#define FITSCURVELIKELIHOODFLOAT_HH +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include "rcecalib/util/RceHisto2d.cc" +#include "rcecalib/config/ConfigIF.hh" + +template<typename TP, typename TE> +class FitScurveLikelihoodFloat:public AbsFit { + + + typedef struct + { + float mu, sigma, a0; + } GaussianCurve; + + typedef struct { + float deltaMu, deltaSigma; /* user provides initial deltaMu and deltaSigma */ + float muEpsilon, sigmaEpsilon; /* user provides convergence criterion */ + int nIters; + int ndf; /* number of degrees of freedom */ + float chi2; /* final result for chi2 */ + int converge; + float muConverge,sigmaConverge; + int maxIters; + void *curve; + } Fit; + + typedef struct + { + unsigned int n; + float *x; + float *y; + } FitData; + + +public: + FitScurveLikelihoodFloat(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal, int nTrigger); + int doFit(); + ~FitScurveLikelihoodFloat(); +protected: + inline float *log_ext(float x, GaussianCurve *psp); + float errf_ext(float x, GaussianCurve *psp); + float logLikelihood(FitData *pfd, GaussianCurve *s); + int initFit(Fit *pFit); + int extractGoodData(FitData *pfdi,FitData *pfdo, float scanA0); + int initialGuess(FitData *pfd, GaussianCurve *pSParams); + int fitPixel(FitData *pfd,void *vpfit); + float chiSquared(FitData *pfd,GaussianCurve *s); + Fit m_fit; + /* buffer for fit data */ + float *m_x; + float *m_y; + std::vector<std::vector<RceHisto2d<TP, TE>*> > &m_histo; + std::vector<std::vector<RceHisto2d<float, float>*> > m_fithisto; +}; + +#endif diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.cc b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.cc new file mode 100644 index 0000000000000000000000000000000000000000..640bfd14ab59d3c78f426fb40463c04c6cbb7e88 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.cc @@ -0,0 +1,543 @@ +#include "rcecalib/dataproc/fit/FitScurveLikelihoodInt.hh" +#include "rcecalib/dataproc/fit/FitData.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <iostream> +#include <stdio.h> + +template<typename TP, typename TE> +FitScurveLikelihoodInt<TP, TE>::FitScurveLikelihoodInt(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal,int nTrigger,const char* name):AbsFit(cif,vcal,nTrigger),m_histo(histo),m_name(name) { + initFit(&m_fit); +} + +template<typename TP, typename TE> +FitScurveLikelihoodInt<TP, TE>::~FitScurveLikelihoodInt(){ + for(unsigned int module=0;module<m_fithisto.size();module++) { + for(size_t i=0;i<m_fithisto[module].size();i++){ + delete m_fithisto[module][i]; + } + } +} + + +template<typename TP, typename TE> +int FitScurveLikelihoodInt<TP, TE>::doFit(int fitopt) { + FitData pfdi,pfdo; + GaussianCurve gc; + int nBins=m_vcal.size(); + if(!nBins) return -1; + m_x=new UINT32[nBins]; + m_y=new UINT8[nBins]; + + for(unsigned int module=0;module<m_config->getNmodules();module++) { + int nRows= m_config->getModuleInfo(module).getNRows(); + int nCols=m_config->getModuleInfo(module).getNColumns(); + //int nHistos=m_histo[module].size(); + std::cout << "nTrigger " << m_nTrigger << std::endl; + for(int chip=0;chip<m_config->getModuleInfo(module).getNFrontends();chip++) { + if((fitopt&NOCONV)==0) { + /* apply dac to electron calibration */ + for(int bin=0;bin<nBins;bin++) { + /* for now we use float here */ + m_x[bin]=(UINT32)m_config->dacToElectrons(module,chip,m_vcal[bin])*10; + } + } else { + for(int bin=0;bin<nBins;bin++) { + /* for now we use float here */ + m_x[bin]=m_vcal[bin]*10; + } + } + for(int col=0;col<nCols;col++) { + for(int row=0;row<nRows;row++) { + // extract S-Curve + for(int bin=0;bin<nBins;bin++) { + m_y[bin]=(UINT8)(*m_histo[module][bin])(row, chip*nCols+col); + } + pfdi.n=nBins; + pfdi.x=&m_x[0]; + pfdi.y=&m_y[0]; + int goodBins=extractGoodData(&pfdi,&pfdo,m_nTrigger); + if(goodBins<5) continue; + m_fit.curve=&gc; + m_fit.maxIters=100; + gc.a0=m_nTrigger; + int result=fitPixel(&pfdo,&m_fit); + if(!result) { + m_fithisto[module][0]->set(chip*nCols+col,row,(double)gc.mu/10000.); + m_fithisto[module][1]->set(chip*nCols+col,row,(double)gc.sigma/10000.); + m_fithisto[module][2]->set(chip*nCols+col,row,(double)m_fit.chi2/100000.); + m_fithisto[module][3]->set(chip*nCols+col,row,(double) m_fit.nIters); + // printf("%d %d %d %f %f %f %d\n",chip,col,row,gc.mu/10000.,gc.sigma/10000.,m_fit.chi2/100000.,m_fit.nIters); + } + } //rows + } //columns + } //chips + } // modules + delete [] m_x; + delete [] m_y; + return 0; +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodInt<TP, TE>::INT32 *FitScurveLikelihoodInt<TP, TE>::log_ext(INT32 x, GaussianCurve *psp) { + INT32 t; + INT32 u; + int n; + INT64 i64a,i64b; + u=(x*100 - psp->mu/100); + i64a=u; + i64a*=10000000LL; + i64b=(INT64) psp->sigma; + i64a/=i64b; + t = (INT32) i64a; + n = (UINT32) LUT_WIDTH + (UINT32)t; + if(n < 0) n = 0; + if(n >= LUT_LENGTH) n = LUT_LENGTH-1; // truncate at last value + n = 2 * n; + return (INT32*) &FitDataInt::data_logx[n]; +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodInt<TP, TE>::UINT32 FitScurveLikelihoodInt<TP, TE>::errf_ext(INT32 x, GaussianCurve *psp) { + INT32 t; + INT32 u; + INT64 i64a,i64b; + int n; + u = (x*100 - psp->mu/100); + i64a=(INT64) u; + i64a*=10000000LL; + i64b=(INT64) psp->sigma; + i64a/=i64b; + t = (INT32) i64a; + n = LUT_WIDTH + (UINT32)t; + if(n < 0) n = 0; + if(n >= LUT_LENGTH) n = LUT_LENGTH-1; // truncate at last value + return FitDataInt::data_errf[n]; +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodInt<TP, TE>::UINT32 FitScurveLikelihoodInt<TP, TE>::logLikelihood(FitData *pfd, GaussianCurve *s) { + INT32 r, N; + INT64 acc,y2,y3; + UINT32 *x; + UINT8 *y; + UINT32 ret; + INT32 *p; + INT64 i64; + int k, n; + x = pfd->x; y = pfd->y; n = pfd->n; + acc = 0; + N = s->a0; + for(k=0;k<n;++k) { + r = *y++; /* data point */ + p = log_ext(*x++,s); /* pointer to log(probability) */ + y2=(INT64) r; + i64=(INT64)*p++; + y2*=i64; + y3=(N - r); + i64=*p; + y3*=i64; + acc -= (y2 + y3); + } + acc/=10000ULL; + ret=(UINT32) (acc); + return (ret); +} + +template<typename TP, typename TE> +int FitScurveLikelihoodInt<TP, TE>::initFit(Fit *pFit) { + pFit->deltaSigma = 1000; + pFit->deltaMu = 1000; + pFit->maxIters = 100; + pFit->muEpsilon = 1; /* 0.01% */ + pFit->sigmaEpsilon = 1; /* 0.01% */ + for (unsigned int i=0;i<m_config->getNmodules();i++){ + std::vector<RceHisto2d<float, float>*> vh; + m_fithisto.push_back(vh); + char name[128]; + char title[128]; + char suffix[128]=""; + if(std::string(m_name)!=""){ + sprintf(suffix,"%s_",m_name); + } + + int rows=m_config->getModuleInfo(i).getNRows(); + int cols=m_config->getModuleInfo(i).getNColumns()*m_config->getModuleInfo(i).getNFrontends(); + int id=m_config->getModuleInfo(i).getId(); + std::string modName=m_config->getModuleInfo(i).getName(); + sprintf(name,"Mod_%d_%sMean", id, suffix); + sprintf(title,"MOD %d %s at %s SCURVE MEAN", id, suffix, modName.c_str()); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE SIGMA", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sSigma", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE CHI2", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sChiSquare", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + sprintf(title,"MOD %d %s at %s SCURVE ITER", id, suffix, modName.c_str()); + sprintf(name,"Mod_%d_%sIter", id, suffix); + m_fithisto[i].push_back(new RceHisto2d<float, float>(name,title,cols,0,cols,rows, 0, rows)); + } + return 0; +} + +template<typename TP, typename TE> +int FitScurveLikelihoodInt<TP, TE>::extractGoodData(FitData *pfdi,FitData *pfdo, UINT32 nTriggers) { + int hitsStart, hitsEnd, nBins; + UINT32 a0; + UINT8 *y; + + nBins = pfdi->n; + y = pfdi->y; + + //new method to find hitsStart + + for(hitsStart = nBins-1;hitsStart >= 0; --hitsStart) + if(y[hitsStart] == 0) break; + + if(hitsStart ==0) + return 0; + if(hitsStart == nBins) + return 0; + + a0 = y[nBins - 1]; // last bin has at least 90% hits + if(a0*999 < nTriggers*900) + return 0; + //failure mode, never reaches A0 + + //dan's new method + for(hitsEnd = hitsStart; hitsEnd < nBins; ++hitsEnd) + if(y[hitsEnd] >= a0) break; + + // add 2 for old method or 1 for new method + // 1 because of where we start comparing and + // 1 because we want to include one instance of the maximum + nBins = 1 + hitsEnd - hitsStart; + + if(hitsStart < 0) hitsStart =0; + + if(hitsStart == hitsEnd) return 0; + + if(nBins < 2) { + return 0; + //failure mode :: not enough data points + } + if(nBins < 0) nBins = 0; + pfdo->n = nBins; + pfdo->y = &y[hitsStart]; + pfdo->x = &pfdi->x[hitsStart]; + return nBins; +} + + +template<typename TP, typename TE> +int FitScurveLikelihoodInt<TP, TE>::initialGuess(FitData *pfd, GaussianCurve *pSParams) { +#define invRoot6 4082482904LL +#define invRoot2 7071067811ULL + UINT32 pt1, pt2, pt3; + UINT8 *pdlo, *pdhi; + UINT32 y_lo, y_hi, sigma; + UINT32 *x; + UINT8 *y; + UINT32 a0; + UINT32 minSigma; + UINT32 j, k, n, lo1, lo2, lo3, hi1, hi2, hi3, status; + UINT32 x1,x2,x3; + UINT64 u64; + INT64 i64; + INT32 xdiff; + + n = pfd->n; + if(n<5) return 1; + pSParams->a0 = pfd->y[pfd->n-1]; // assumes last data point sets plateau + a0 = pSParams->a0*100000-1; // skim a token amount to ensure comparisons succeed + xdiff=pfd->x[1] - pfd->x[0]; + i64=(INT64) xdiff; + i64*=invRoot6; + i64/=100000000000LL; + minSigma = (UINT32) i64; + // minSigma = (UINT32) (((INT64) (pfd->x[1] - pfd->x[0])) * invRoot6) / 1000000LL; + + x = pfd->x; y = pfd->y; + pt1 = 16* a0; + pt2 = 50* a0; + pt3 = 84* a0; + // find the range over which the data crosses the 16%, 50% and 84% points + hi1 = hi2 = hi3 = 0; // invalid values + lo1 = lo2 = lo3 = 0; // invalid values + pdlo = &y[0]; // y + pdhi = &y[n-1]; // y + n - 1 + // important note: for the sake of speed we want to perform as few comparisons as + //possible. Therefore, the integer comparison occurs first in each of the + //following operations. Depending on the logical value thereof, the next + //comparison will be made only if necessary. To further expedite the code, + //arrays are not used because there are only three members + j = n - 1; + for(k=0;k<n;++pdlo, --pdhi) { + y_lo = (*pdlo)*10000000; + y_hi = (*pdhi)*10000000; + if(!lo1 && (y_lo >= pt1)) lo1 = k; + if(!lo2 && (y_lo >= pt2)) lo2 = k; + if(!lo3 && (y_lo >= pt3)) lo3 = k; + if(!hi1 && (y_hi <= pt1)) hi1 = j; + if(!hi2 && (y_hi <= pt2)) hi2 = j; + if(!hi3 && (y_hi <= pt3)) hi3 = j; + --j; + ++k; + } + x1 = (x[lo1] + x[hi1]) *5; + x2 = (x[lo2] + x[hi2]) *5; + x3 = (x[lo3] + x[hi3]) *5; + + // mu = threshold + + pSParams->mu = (UINT32) x2; + xdiff=(x3 - x1); + u64=(UINT64) xdiff; + u64*=invRoot2; + u64/=100000000LL; + sigma=(UINT32) u64; + if(sigma < minSigma) { + sigma = minSigma; + } + pSParams->sigma=sigma; + status = 0; + return status; +} +template<typename TP, typename TE> +int FitScurveLikelihoodInt<TP, TE>::fitPixel(FitData *pfd,void *vpfit) { + INT32 deltaSigma, deltaMu, sigma, chi2Min, *fptr; + INT32 chi2[9]; + UINT64 u64; + GaussianCurve sParams, sParamsWork, *psp; + int k, dirMin; + Fit *pFit; + pFit = (Fit *)vpfit; + + pFit->nIters = 0; + pFit->converge = 0; // assume no convergence + + pFit->ndf = pfd->n - 2; // degrees of freedom + + // take a guess at the S-curve parameters + + if(initialGuess(pfd,&sParams)) { + psp = (GaussianCurve *)pFit->curve; + psp->a0 = sParams.a0; + psp->mu = sParams.mu; + psp->sigma = sParams.sigma; + pFit->converge = 1; + pFit->muConverge = 0; + pFit->sigmaConverge = 0; + pFit->chi2 = 0; + return 0; + } + + // initialize loop parameters + psp = &sParamsWork; + psp->a0 = sParams.a0; + deltaSigma = sParams.sigma*100; // scaled + deltaMu = sParams.mu*100; // scaled + sParams.sigma*= pFit->deltaSigma; + sParams.mu*= pFit->deltaMu; + + + //* the loop begins * + // printf("delta %d %d\n",deltaSigma,deltaMu); + while(!pFit->converge && (pFit->nIters++ < pFit->maxIters)) { + dirMin = 0; + fptr = chi2; + for(k=0;k<9;++k) *fptr++ = 0; + + while((dirMin >= 0) && (pFit->nIters++ < pFit->maxIters)) { + + //* calculate neighboring points * + //* calculate neighboring points * + // printf("!! %d %d\n",sParams.sigma,deltaSigma); + psp->sigma=sParams.sigma - deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[0] == 0) + chi2[0] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[7] == 0) + chi2[7] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[6] == 0) + chi2[6] = logLikelihood(pfd,psp); + + psp->sigma=sParams.sigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[1] == 0) + chi2[1] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[8] == 0) + chi2[8] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[5] == 0) + chi2[5] = logLikelihood(pfd,psp); + + psp->sigma=sParams.sigma+deltaSigma; + psp->mu = sParams.mu - deltaMu; + if(chi2[2] == 0) + chi2[2] = logLikelihood(pfd,psp); + psp->mu = sParams.mu; + if(chi2[3] == 0) + chi2[3] = logLikelihood(pfd,psp); + psp->mu = sParams.mu + deltaMu; + if(chi2[4] == 0) + chi2[4] = logLikelihood(pfd,psp); + + dirMin = -1; + chi2Min = chi2[8]; // first guess at minimum + for(k=0, fptr=chi2;k<8;++k, ++fptr) { + if(*fptr < chi2Min) { + chi2Min = *fptr; + dirMin = k; + } + } + // printf("\n"); + switch(dirMin) { + case -1: + deltaSigma = deltaSigma /10; + deltaMu = deltaMu /10; + break; + case 0: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[0]; + chi2[3] = chi2[1]; + chi2[4] = chi2[8]; + chi2[5] = chi2[7]; + chi2[0] = chi2[1] = chi2[2] = + chi2[6] = chi2[7] = 0; + break; + case 1: + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[1]; + chi2[3] = chi2[2]; + chi2[4] = chi2[3]; + chi2[5] = chi2[8]; + chi2[6] = chi2[7]; + chi2[7] = chi2[0]; + chi2[0] = chi2[1] = chi2[2] = 0; + break; + case 2: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu - deltaMu; + chi2[8] = chi2[2]; + chi2[5] = chi2[3]; + chi2[6] = chi2[8]; + chi2[7] = chi2[1]; + chi2[0] = chi2[1] = chi2[2] = + chi2[3] = chi2[4] = 0; + break; + case 3: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[3]; + chi2[5] = chi2[4]; + chi2[6] = chi2[5]; + chi2[7] = chi2[8]; + chi2[0] = chi2[1]; + chi2[1] = chi2[2]; + chi2[2] = chi2[3] = chi2[4] = 0; + break; + case 4: + sigma = sParams.sigma + deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[4]; + chi2[7] = chi2[5]; + chi2[0] = chi2[8]; + chi2[1] = chi2[3]; + chi2[2] = chi2[3] = chi2[4] = + chi2[5] = chi2[6] = 0; + break; + case 5: + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[5]; + chi2[7] = chi2[6]; + chi2[0] = chi2[7]; + chi2[1] = chi2[8]; + chi2[2] = chi2[3]; + chi2[3] = chi2[4]; + chi2[4] = chi2[5] = chi2[6] = 0; + break; + case 6: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + sParams.mu = sParams.mu + deltaMu; + chi2[8] = chi2[6]; + chi2[1] = chi2[7]; + chi2[2] = chi2[8]; + chi2[3] = chi2[5]; + chi2[4] = chi2[5] = chi2[6] = + chi2[7] = chi2[0] = 0; + break; + case 7: + sigma = sParams.sigma - deltaSigma; + sParams.sigma=sigma; + chi2[8] = chi2[7]; + chi2[1] = chi2[0]; + chi2[2] = chi2[1]; + chi2[3] = chi2[8]; + chi2[4] = chi2[5]; + chi2[5] = chi2[6]; + chi2[6] = chi2[7] = chi2[0] = 0; + break; + } + } + + + if((unsigned int)deltaSigma/10 < ((pFit->sigmaEpsilon * sParams.sigma)/100000) && + (unsigned int)deltaMu/10 < (pFit->muEpsilon * sParams.mu)/100000) { + pFit->converge = 1; + break; + } + } + psp = (GaussianCurve *)pFit->curve; + *psp = sParams; + pFit->chi2 = chiSquared(pfd,psp) / pFit->ndf; + u64=(UINT64) sParams.sigma; + u64*=70710678ULL; + u64/=10000000000ULL; + psp->sigma=(UINT32) (UINT64) u64; + + return pFit->converge ? 0 : 1; // 0 = success + +} + +template<typename TP, typename TE> +typename FitScurveLikelihoodInt<TP, TE>::UINT32 FitScurveLikelihoodInt<TP, TE>::chiSquared(FitData *pfd,GaussianCurve *s) { + UINT64 acc; + INT32 y0,y1,y2; + INT64 y3; + INT64 ui64; + UINT32 a0, chi2; + UINT32 *x; + UINT8 *y; + INT32 x0; + int j, k, n; + x = pfd->x; y = pfd->y; n = pfd->n; + acc = 0; + a0 = s->a0; + /* use binomial weighting */ + for(k=0;k<n;++k) { + x0 = *x++; + y0 = *y++; + y1 = errf_ext(x0,s); + j = (int)(y1/1000); + y2 = y0*1000000 - (a0 * y1); + y2/=1000; + y3=(INT64) y2; + y3*=y3; + ui64=(UINT64)FitDataInt::binomial_weight[j]; + ui64*=y3; + acc+=ui64; + } + acc/=10000000ULL; + chi2=(UINT32) acc; + chi2/=a0; + return chi2; +} diff --git a/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.hh b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.hh new file mode 100644 index 0000000000000000000000000000000000000000..15f75469cbb2a61e13bbc8652e6f1778faa0850e --- /dev/null +++ b/rce/rcecalib/dataproc/fit/FitScurveLikelihoodInt.hh @@ -0,0 +1,66 @@ +#ifndef FITSCURVELIKELIHOODINT_HH +#define FITSCURVELIKELIHOODINT_HH +#include "rcecalib/dataproc/fit/AbsFit.hh" +#include "rcecalib/util/RceHisto2d.cc" +#include <vector> + +template<typename TP, typename TE> +class FitScurveLikelihoodInt:public AbsFit { + +typedef unsigned int UINT32; +typedef int INT32; +typedef unsigned long long UINT64; +typedef long long INT64; +typedef unsigned char UINT8; + +typedef struct FitData_ +{ + UINT32 n; + UINT32 *x; + UINT8 *y; +} FitData; + + +typedef struct GaussianCurve_ +{ + UINT32 mu, sigma, a0; +} GaussianCurve; + +typedef struct { + INT32 deltaMu, deltaSigma; /* user provides initial deltaMu and deltaSigma */ + INT32 muEpsilon, sigmaEpsilon; /* user provides convergence criterion */ + INT32 nIters; + INT32 ndf; /* number of degrees of freedom */ + INT32 chi2; /* final result for chi2 */ + INT32 converge; + INT32 muConverge,sigmaConverge; + INT32 maxIters; + void *curve; +} Fit; + + +public: + FitScurveLikelihoodInt(ConfigIF *cif,std::vector<std::vector<RceHisto2d<TP, TE>*> > &histo,std::vector<int> &vcal, int nTrigger, const char* name=""); + ~FitScurveLikelihoodInt(); + int doFit(int); +protected: + inline INT32 *log_ext(INT32 x, GaussianCurve *psp); + UINT32 errf_ext(INT32 x, GaussianCurve *psp); + UINT32 logLikelihood(FitData *pfd, GaussianCurve *s); + int initFit(Fit *pFit); + int extractGoodData(FitData *pfdi,FitData *pfdo, UINT32 nTriggers); + int initialGuess(FitData *pfd, GaussianCurve *pSParams); + int fitPixel(FitData *pfd,void *vpfit); + UINT32 chiSquared(FitData *pfd,GaussianCurve *s); + Fit m_fit; + UINT32 *m_x; + UINT8 *m_y; + std::vector<std::vector<RceHisto2d<TP, TE>*> > &m_histo; + std::vector<std::vector<RceHisto2d<float, float>*> > m_fithisto; + const char* m_name; + +}; + + + +#endif diff --git a/rce/rcecalib/dataproc/fit/binomial_weight.dat b/rce/rcecalib/dataproc/fit/binomial_weight.dat new file mode 100644 index 0000000000000000000000000000000000000000..7c5736f56f4efebddcb85ec3e781664c085b22f9 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/binomial_weight.dat @@ -0,0 +1,1001 @@ +1001.000954f, +1001.000954f, +501.001980f, +334.336339f, +251.004004f, +201.005011f, +167.672701f, +143.864188f, +126.008059f, +112.120186f, +101.010094f, +91.920206f, +84.345478f, +77.936247f, +72.442768f, +67.681892f, +63.516257f, +59.840820f, +56.573882f, +53.650943f, +51.020405f, +48.640494f, +46.477037f, +44.501799f, +42.691256f, +41.025640f, +39.488232f, +38.064785f, +36.743091f, +35.512624f, +34.364260f, +33.290055f, +32.283056f, +31.337157f, +30.446960f, +29.607698f, +28.815120f, +28.065448f, +27.355289f, +26.681608f, +26.041665f, +25.432996f, +24.853363f, +24.300745f, +23.773296f, +23.269342f, +22.787347f, +22.325913f, +21.883753f, +21.459687f, +21.052631f, +20.661583f, +20.285621f, +19.923890f, +19.575600f, +19.240018f, +18.916464f, +18.604304f, +18.302950f, +18.011851f, +17.730496f, +17.458404f, +17.195130f, +16.940251f, +16.693375f, +16.454133f, +16.222179f, +15.997184f, +15.778843f, +15.566866f, +15.360983f, +15.160933f, +14.966474f, +14.777378f, +14.593427f, +14.414414f, +14.240145f, +14.070435f, +13.905111f, +13.744004f, +13.586956f, +13.433818f, +13.284446f, +13.138705f, +12.996464f, +12.857602f, +12.721998f, +12.589542f, +12.460127f, +12.333650f, +12.210012f, +12.089120f, +11.970886f, +11.855224f, +11.742050f, +11.631287f, +11.522861f, +11.416698f, +11.312729f, +11.210887f, +11.111111f, +11.013337f, +10.917507f, +10.823564f, +10.731456f, +10.641128f, +10.552530f, +10.465615f, +10.380335f, +10.296646f, +10.214504f, +10.133868f, +10.054697f, +9.976953f, +9.900597f, +9.825596f, +9.751911f, +9.679511f, +9.608363f, +9.538435f, +9.469697f, +9.402119f, +9.335673f, +9.270332f, +9.206068f, +9.142857f, +9.080673f, +9.019491f, +8.959289f, +8.900043f, +8.841732f, +8.784335f, +8.727831f, +8.672199f, +8.617421f, +8.563476f, +8.510348f, +8.458018f, +8.406469f, +8.355684f, +8.305648f, +8.256343f, +8.207754f, +8.159868f, +8.112668f, +8.066142f, +8.020275f, +7.975054f, +7.930466f, +7.886497f, +7.843137f, +7.800373f, +7.758192f, +7.716585f, +7.675539f, +7.635045f, +7.595090f, +7.555666f, +7.516762f, +7.478368f, +7.440476f, +7.403075f, +7.366157f, +7.329712f, +7.293733f, +7.258211f, +7.223137f, +7.188504f, +7.154304f, +7.120529f, +7.087172f, +7.054226f, +7.021683f, +6.989536f, +6.957780f, +6.926407f, +6.895410f, +6.864784f, +6.834522f, +6.804619f, +6.775068f, +6.745863f, +6.716999f, +6.688471f, +6.660272f, +6.632399f, +6.604845f, +6.577606f, +6.550676f, +6.524051f, +6.497725f, +6.471696f, +6.445957f, +6.420504f, +6.395334f, +6.370441f, +6.345822f, +6.321472f, +6.297388f, +6.273565f, +6.250000f, +6.226689f, +6.203628f, +6.180813f, +6.158242f, +6.135910f, +6.113814f, +6.091952f, +6.070318f, +6.048911f, +6.027727f, +6.006763f, +5.986016f, +5.965483f, +5.945161f, +5.925048f, +5.905140f, +5.885434f, +5.865928f, +5.846620f, +5.827506f, +5.808584f, +5.789851f, +5.771306f, +5.752945f, +5.734767f, +5.716768f, +5.698947f, +5.681301f, +5.663829f, +5.646527f, +5.629394f, +5.612428f, +5.595626f, +5.578987f, +5.562508f, +5.546188f, +5.530025f, +5.514017f, +5.498161f, +5.482456f, +5.466900f, +5.451492f, +5.436230f, +5.421112f, +5.406136f, +5.391300f, +5.376604f, +5.362045f, +5.347622f, +5.333333f, +5.319177f, +5.305152f, +5.291257f, +5.277490f, +5.263850f, +5.250336f, +5.236946f, +5.223678f, +5.210531f, +5.197505f, +5.184598f, +5.171807f, +5.159133f, +5.146574f, +5.134129f, +5.121796f, +5.109575f, +5.097463f, +5.085461f, +5.073567f, +5.061779f, +5.050097f, +5.038519f, +5.027045f, +5.015674f, +5.004404f, +4.993234f, +4.982164f, +4.971192f, +4.960317f, +4.949539f, +4.938857f, +4.928269f, +4.917775f, +4.907373f, +4.897064f, +4.886845f, +4.876716f, +4.866677f, +4.856726f, +4.846863f, +4.837087f, +4.827396f, +4.817791f, +4.808270f, +4.798833f, +4.789478f, +4.780206f, +4.771015f, +4.761905f, +4.752874f, +4.743923f, +4.735050f, +4.726255f, +4.717537f, +4.708896f, +4.700330f, +4.691840f, +4.683424f, +4.675082f, +4.666813f, +4.658617f, +4.650492f, +4.642439f, +4.634457f, +4.626545f, +4.618703f, +4.610930f, +4.603225f, +4.595588f, +4.588019f, +4.580516f, +4.573080f, +4.565710f, +4.558404f, +4.551164f, +4.543988f, +4.536876f, +4.529826f, +4.522840f, +4.515916f, +4.509054f, +4.502253f, +4.495513f, +4.488834f, +4.482214f, +4.475655f, +4.469154f, +4.462712f, +4.456328f, +4.450002f, +4.443733f, +4.437522f, +4.431367f, +4.425268f, +4.419225f, +4.413238f, +4.407305f, +4.401428f, +4.395604f, +4.389835f, +4.384119f, +4.378456f, +4.372846f, +4.367289f, +4.361784f, +4.356330f, +4.350928f, +4.345578f, +4.340278f, +4.335028f, +4.329829f, +4.324680f, +4.319580f, +4.314529f, +4.309527f, +4.304574f, +4.299670f, +4.294813f, +4.290004f, +4.285243f, +4.280529f, +4.275861f, +4.271241f, +4.266667f, +4.262138f, +4.257656f, +4.253220f, +4.248828f, +4.244482f, +4.240181f, +4.235924f, +4.231712f, +4.227543f, +4.223419f, +4.219338f, +4.215301f, +4.211306f, +4.207355f, +4.203447f, +4.199581f, +4.195757f, +4.191976f, +4.188236f, +4.184538f, +4.180882f, +4.177266f, +4.173692f, +4.170159f, +4.166667f, +4.163215f, +4.159803f, +4.156431f, +4.153100f, +4.149808f, +4.146556f, +4.143343f, +4.140170f, +4.137035f, +4.133940f, +4.130883f, +4.127865f, +4.124885f, +4.121943f, +4.119040f, +4.116175f, +4.113347f, +4.110558f, +4.107805f, +4.105090f, +4.102413f, +4.099772f, +4.097168f, +4.094602f, +4.092072f, +4.089578f, +4.087121f, +4.084700f, +4.082316f, +4.079967f, +4.077655f, +4.075378f, +4.073137f, +4.070932f, +4.068762f, +4.066628f, +4.064528f, +4.062464f, +4.060436f, +4.058442f, +4.056482f, +4.054558f, +4.052668f, +4.050813f, +4.048993f, +4.047207f, +4.045455f, +4.043737f, +4.042053f, +4.040404f, +4.038788f, +4.037207f, +4.035659f, +4.034145f, +4.032665f, +4.031218f, +4.029804f, +4.028425f, +4.027078f, +4.025765f, +4.024485f, +4.023238f, +4.022025f, +4.020844f, +4.019696f, +4.018582f, +4.017500f, +4.016451f, +4.015435f, +4.014452f, +4.013501f, +4.012583f, +4.011698f, +4.010845f, +4.010025f, +4.009237f, +4.008482f, +4.007759f, +4.007068f, +4.006410f, +4.005784f, +4.005191f, +4.004629f, +4.004100f, +4.003603f, +4.003138f, +4.002706f, +4.002305f, +4.001937f, +4.001601f, +4.001296f, +4.001024f, +4.000784f, +4.000576f, +4.000400f, +4.000256f, +4.000144f, +4.000064f, +4.000016f, +4.000000f, +4.000016f, +4.000064f, +4.000144f, +4.000256f, +4.000400f, +4.000576f, +4.000784f, +4.001024f, +4.001296f, +4.001601f, +4.001937f, +4.002305f, +4.002706f, +4.003138f, +4.003603f, +4.004100f, +4.004629f, +4.005191f, +4.005784f, +4.006410f, +4.007068f, +4.007759f, +4.008482f, +4.009237f, +4.010025f, +4.010845f, +4.011698f, +4.012583f, +4.013501f, +4.014452f, +4.015435f, +4.016451f, +4.017500f, +4.018582f, +4.019697f, +4.020844f, +4.022025f, +4.023238f, +4.024485f, +4.025765f, +4.027078f, +4.028425f, +4.029804f, +4.031218f, +4.032665f, +4.034145f, +4.035659f, +4.037207f, +4.038789f, +4.040404f, +4.042054f, +4.043737f, +4.045455f, +4.047207f, +4.048993f, +4.050814f, +4.052669f, +4.054558f, +4.056482f, +4.058442f, +4.060436f, +4.062465f, +4.064529f, +4.066628f, +4.068762f, +4.070932f, +4.073137f, +4.075378f, +4.077655f, +4.079967f, +4.082316f, +4.084700f, +4.087121f, +4.089578f, +4.092072f, +4.094602f, +4.097169f, +4.099772f, +4.102413f, +4.105090f, +4.107805f, +4.110558f, +4.113347f, +4.116175f, +4.119040f, +4.121944f, +4.124885f, +4.127865f, +4.130883f, +4.133940f, +4.137035f, +4.140170f, +4.143343f, +4.146556f, +4.149808f, +4.153100f, +4.156431f, +4.159803f, +4.163215f, +4.166667f, +4.170159f, +4.173693f, +4.177267f, +4.180882f, +4.184538f, +4.188236f, +4.191976f, +4.195757f, +4.199581f, +4.203447f, +4.207355f, +4.211307f, +4.215301f, +4.219338f, +4.223419f, +4.227544f, +4.231712f, +4.235924f, +4.240181f, +4.244482f, +4.248829f, +4.253220f, +4.257656f, +4.262139f, +4.266667f, +4.271241f, +4.275862f, +4.280529f, +4.285243f, +4.290005f, +4.294813f, +4.299670f, +4.304575f, +4.309528f, +4.314529f, +4.319580f, +4.324680f, +4.329829f, +4.335029f, +4.340278f, +4.345578f, +4.350929f, +4.356330f, +4.361784f, +4.367289f, +4.372847f, +4.378456f, +4.384119f, +4.389835f, +4.395605f, +4.401428f, +4.407306f, +4.413238f, +4.419226f, +4.425268f, +4.431367f, +4.437522f, +4.443734f, +4.450002f, +4.456328f, +4.462712f, +4.469154f, +4.475655f, +4.482215f, +4.488834f, +4.495514f, +4.502254f, +4.509054f, +4.515917f, +4.522840f, +4.529827f, +4.536876f, +4.543988f, +4.551164f, +4.558405f, +4.565710f, +4.573080f, +4.580517f, +4.588019f, +4.595588f, +4.603225f, +4.610930f, +4.618703f, +4.626545f, +4.634458f, +4.642440f, +4.650493f, +4.658617f, +4.666813f, +4.675082f, +4.683424f, +4.691840f, +4.700331f, +4.708896f, +4.717538f, +4.726256f, +4.735050f, +4.743923f, +4.752875f, +4.761905f, +4.771015f, +4.780206f, +4.789479f, +4.798833f, +4.808271f, +4.817791f, +4.827397f, +4.837087f, +4.846864f, +4.856727f, +4.866678f, +4.876717f, +4.886846f, +4.897064f, +4.907374f, +4.917775f, +4.928269f, +4.938858f, +4.949540f, +4.960318f, +4.971192f, +4.982165f, +4.993235f, +5.004404f, +5.015674f, +5.027046f, +5.038520f, +5.050097f, +5.061779f, +5.073567f, +5.085461f, +5.097464f, +5.109575f, +5.121797f, +5.134129f, +5.146575f, +5.159134f, +5.171808f, +5.184598f, +5.197505f, +5.210532f, +5.223678f, +5.236946f, +5.250336f, +5.263851f, +5.277491f, +5.291258f, +5.305153f, +5.319177f, +5.333334f, +5.347623f, +5.362046f, +5.376605f, +5.391301f, +5.406137f, +5.421113f, +5.436231f, +5.451493f, +5.466902f, +5.482457f, +5.498161f, +5.514017f, +5.530025f, +5.546190f, +5.562509f, +5.578988f, +5.595627f, +5.612428f, +5.629395f, +5.646528f, +5.663830f, +5.681302f, +5.698948f, +5.716769f, +5.734768f, +5.752946f, +5.771306f, +5.789853f, +5.808585f, +5.827506f, +5.846620f, +5.865930f, +5.885435f, +5.905141f, +5.925049f, +5.945162f, +5.965485f, +5.986018f, +6.006764f, +6.027728f, +6.048912f, +6.070320f, +6.091953f, +6.113815f, +6.135911f, +6.158244f, +6.180815f, +6.203629f, +6.226689f, +6.250000f, +6.273566f, +6.297389f, +6.321473f, +6.345822f, +6.370443f, +6.395335f, +6.420506f, +6.445958f, +6.471696f, +6.497727f, +6.524052f, +6.550677f, +6.577607f, +6.604846f, +6.632401f, +6.660274f, +6.688472f, +6.717000f, +6.745865f, +6.775069f, +6.804620f, +6.834523f, +6.864785f, +6.895412f, +6.926408f, +6.957781f, +6.989537f, +7.021685f, +7.054228f, +7.087174f, +7.120530f, +7.154305f, +7.188506f, +7.223139f, +7.258212f, +7.293734f, +7.329713f, +7.366159f, +7.403077f, +7.440477f, +7.478370f, +7.516765f, +7.555669f, +7.595092f, +7.635046f, +7.675540f, +7.716588f, +7.758195f, +7.800374f, +7.843138f, +7.886498f, +7.930468f, +7.975056f, +8.020277f, +8.066143f, +8.112672f, +8.159871f, +8.207757f, +8.256344f, +8.305649f, +8.355688f, +8.406472f, +8.458020f, +8.510350f, +8.563480f, +8.617424f, +8.672202f, +8.727833f, +8.784337f, +8.841737f, +8.900047f, +8.959291f, +9.019493f, +9.080673f, +9.142861f, +9.206072f, +9.270334f, +9.335675f, +9.402124f, +9.469701f, +9.538438f, +9.608365f, +9.679513f, +9.751916f, +9.825599f, +9.900601f, +9.976955f, +10.054703f, +10.133873f, +10.214508f, +10.296649f, +10.380337f, +10.465621f, +10.552535f, +10.641132f, +10.731459f, +10.823566f, +10.917513f, +11.013342f, +11.111115f, +11.210890f, +11.312736f, +11.416704f, +11.522866f, +11.631292f, +11.742053f, +11.855231f, +11.970893f, +12.089126f, +12.210015f, +12.333659f, +12.460135f, +12.589549f, +12.722003f, +12.857605f, +12.996475f, +13.138713f, +13.284453f, +13.433823f, +13.586959f, +13.744014f, +13.905120f, +14.070443f, +14.240150f, +14.414427f, +14.593438f, +14.777387f, +14.966481f, +15.160937f, +15.360997f, +15.566879f, +15.778853f, +15.997191f, +16.222182f, +16.454149f, +16.693388f, +16.940261f, +17.195136f, +17.458424f, +17.730512f, +18.011864f, +18.302960f, +18.604311f, +18.916486f, +19.240037f, +19.575614f, +19.923900f, +20.285649f, +20.661607f, +21.052651f, +21.459702f, +21.883763f, +22.325945f, +22.787375f, +23.269364f, +23.773313f, +24.300755f, +24.853401f, +25.433027f, +26.041690f, +26.681625f, +27.355340f, +28.065492f, +28.815158f, +29.607725f, +30.446979f, +31.337218f, +32.283111f, +33.290099f, +34.364293f, +35.512714f, +36.743172f, +38.064854f, +39.488287f, +41.025679f, +42.691379f, +44.501911f, +46.477133f, +48.640570f, +51.020456f, +53.651129f, +56.574049f, +59.840962f, +63.516366f, +67.682224f, +72.443082f, +77.936533f, +84.345724f, +91.920398f, +101.010792f, +112.120887f, +126.008742f, +143.864815f, +167.673193f, +201.007600f, +251.007235f, +334.340634f, +501.008441f, +1001.073485f, +1001.073486f diff --git a/rce/rcecalib/dataproc/fit/binomial_weight_fastint.dat b/rce/rcecalib/dataproc/fit/binomial_weight_fastint.dat new file mode 100644 index 0000000000000000000000000000000000000000..c2aee1d67626805ba4e5e7343756496a5584489d --- /dev/null +++ b/rce/rcecalib/dataproc/fit/binomial_weight_fastint.dat @@ -0,0 +1,1001 @@ +1001000954, +1001000954, +501001980, +334336339, +251004004, +201005011, +167672701, +143864188, +126008059, +112120186, +101010094, +91920206, +84345478, +77936247, +72442768, +67681892, +63516257, +59840820, +56573882, +53650943, +51020405, +48640494, +46477037, +44501799, +42691256, +41025640, +39488232, +38064785, +36743091, +35512624, +34364260, +33290055, +32283056, +31337157, +30446960, +29607698, +28815120, +28065448, +27355289, +26681608, +26041665, +25432996, +24853363, +24300745, +23773296, +23269342, +22787347, +22325913, +21883753, +21459687, +21052631, +20661583, +20285621, +19923890, +19575600, +19240018, +18916464, +18604304, +18302950, +18011851, +17730496, +17458404, +17195130, +16940251, +16693375, +16454132, +16222179, +15997184, +15778843, +15566866, +15360983, +15160933, +14966474, +14777378, +14593427, +14414414, +14240145, +14070435, +13905111, +13744004, +13586956, +13433818, +13284446, +13138705, +12996464, +12857602, +12721998, +12589542, +12460127, +12333650, +12210012, +12089120, +11970886, +11855224, +11742050, +11631287, +11522861, +11416698, +11312729, +11210887, +11111111, +11013337, +10917507, +10823564, +10731456, +10641128, +10552530, +10465615, +10380335, +10296646, +10214504, +10133868, +10054697, +9976953, +9900597, +9825596, +9751911, +9679511, +9608363, +9538435, +9469697, +9402119, +9335673, +9270332, +9206068, +9142857, +9080673, +9019491, +8959289, +8900043, +8841732, +8784335, +8727831, +8672199, +8617421, +8563476, +8510348, +8458018, +8406469, +8355684, +8305648, +8256342, +8207754, +8159867, +8112667, +8066141, +8020275, +7975054, +7930466, +7886497, +7843137, +7800373, +7758192, +7716585, +7675539, +7635045, +7595090, +7555666, +7516762, +7478368, +7440476, +7403075, +7366157, +7329712, +7293733, +7258211, +7223137, +7188504, +7154304, +7120529, +7087172, +7054226, +7021683, +6989536, +6957780, +6926407, +6895410, +6864784, +6834522, +6804619, +6775068, +6745863, +6716999, +6688471, +6660272, +6632399, +6604845, +6577606, +6550676, +6524051, +6497725, +6471696, +6445957, +6420504, +6395334, +6370441, +6345822, +6321472, +6297388, +6273565, +6250000, +6226689, +6203628, +6180813, +6158242, +6135910, +6113814, +6091952, +6070318, +6048911, +6027727, +6006763, +5986016, +5965483, +5945161, +5925048, +5905140, +5885434, +5865928, +5846620, +5827506, +5808584, +5789851, +5771306, +5752945, +5734767, +5716768, +5698947, +5681301, +5663829, +5646527, +5629394, +5612428, +5595626, +5578987, +5562508, +5546188, +5530025, +5514017, +5498161, +5482456, +5466900, +5451492, +5436230, +5421112, +5406136, +5391300, +5376604, +5362045, +5347622, +5333333, +5319177, +5305152, +5291257, +5277490, +5263850, +5250336, +5236946, +5223678, +5210531, +5197505, +5184598, +5171807, +5159133, +5146574, +5134129, +5121796, +5109575, +5097463, +5085461, +5073567, +5061779, +5050097, +5038519, +5027045, +5015674, +5004404, +4993234, +4982164, +4971192, +4960317, +4949539, +4938857, +4928269, +4917775, +4907373, +4897064, +4886845, +4876716, +4866677, +4856726, +4846863, +4837087, +4827396, +4817791, +4808270, +4798833, +4789478, +4780206, +4771015, +4761905, +4752874, +4743923, +4735050, +4726255, +4717537, +4708896, +4700330, +4691840, +4683424, +4675082, +4666813, +4658617, +4650492, +4642439, +4634457, +4626545, +4618703, +4610930, +4603225, +4595588, +4588019, +4580516, +4573080, +4565710, +4558404, +4551164, +4543988, +4536876, +4529826, +4522840, +4515916, +4509054, +4502253, +4495513, +4488834, +4482214, +4475655, +4469154, +4462712, +4456328, +4450002, +4443733, +4437522, +4431367, +4425268, +4419225, +4413238, +4407305, +4401428, +4395604, +4389835, +4384119, +4378456, +4372846, +4367289, +4361784, +4356330, +4350928, +4345578, +4340278, +4335028, +4329829, +4324680, +4319580, +4314529, +4309527, +4304574, +4299670, +4294813, +4290004, +4285243, +4280529, +4275861, +4271241, +4266667, +4262138, +4257656, +4253220, +4248828, +4244482, +4240181, +4235924, +4231712, +4227543, +4223419, +4219338, +4215301, +4211306, +4207355, +4203447, +4199581, +4195757, +4191976, +4188236, +4184538, +4180882, +4177266, +4173692, +4170159, +4166667, +4163215, +4159803, +4156431, +4153100, +4149808, +4146556, +4143343, +4140170, +4137035, +4133940, +4130883, +4127865, +4124885, +4121943, +4119040, +4116175, +4113347, +4110558, +4107805, +4105089, +4102413, +4099771, +4097168, +4094602, +4092072, +4089578, +4087121, +4084700, +4082315, +4079967, +4077655, +4075377, +4073137, +4070932, +4068762, +4066627, +4064528, +4062464, +4060436, +4058442, +4056482, +4054558, +4052667, +4050813, +4048993, +4047207, +4045454, +4043737, +4042053, +4040403, +4038788, +4037207, +4035659, +4034144, +4032664, +4031218, +4029804, +4028425, +4027078, +4025765, +4024485, +4023238, +4022025, +4020844, +4019695, +4018582, +4017500, +4016451, +4015435, +4014452, +4013500, +4012583, +4011698, +4010845, +4010024, +4009236, +4008482, +4007759, +4007068, +4006410, +4005784, +4005191, +4004629, +4004100, +4003603, +4003138, +4002706, +4002305, +4001937, +4001601, +4001296, +4001024, +4000784, +4000575, +4000400, +4000256, +4000143, +4000064, +4000015, +4000000, +4000015, +4000064, +4000143, +4000256, +4000400, +4000575, +4000784, +4001024, +4001296, +4001601, +4001937, +4002305, +4002706, +4003138, +4003603, +4004100, +4004629, +4005191, +4005784, +4006410, +4007068, +4007759, +4008482, +4009236, +4010024, +4010845, +4011698, +4012583, +4013500, +4014452, +4015435, +4016451, +4017500, +4018582, +4019697, +4020844, +4022025, +4023238, +4024485, +4025765, +4027078, +4028425, +4029804, +4031218, +4032664, +4034144, +4035659, +4037207, +4038789, +4040403, +4042054, +4043737, +4045454, +4047207, +4048993, +4050814, +4052669, +4054558, +4056482, +4058442, +4060436, +4062465, +4064529, +4066627, +4068762, +4070932, +4073137, +4075377, +4077655, +4079967, +4082315, +4084700, +4087121, +4089578, +4092072, +4094602, +4097169, +4099771, +4102413, +4105089, +4107805, +4110558, +4113347, +4116175, +4119040, +4121944, +4124885, +4127865, +4130883, +4133940, +4137035, +4140170, +4143343, +4146556, +4149808, +4153100, +4156431, +4159803, +4163215, +4166667, +4170159, +4173693, +4177266, +4180882, +4184538, +4188236, +4191976, +4195757, +4199581, +4203447, +4207355, +4211307, +4215301, +4219338, +4223419, +4227544, +4231712, +4235924, +4240181, +4244482, +4248829, +4253220, +4257656, +4262139, +4266667, +4271241, +4275862, +4280529, +4285243, +4290005, +4294813, +4299670, +4304575, +4309528, +4314529, +4319580, +4324680, +4329829, +4335029, +4340278, +4345578, +4350929, +4356330, +4361784, +4367289, +4372847, +4378456, +4384119, +4389835, +4395605, +4401428, +4407306, +4413238, +4419226, +4425268, +4431367, +4437522, +4443734, +4450002, +4456328, +4462712, +4469154, +4475655, +4482215, +4488834, +4495514, +4502254, +4509054, +4515917, +4522840, +4529827, +4536876, +4543988, +4551164, +4558405, +4565710, +4573080, +4580517, +4588019, +4595588, +4603225, +4610930, +4618703, +4626545, +4634458, +4642440, +4650493, +4658617, +4666813, +4675082, +4683424, +4691840, +4700331, +4708896, +4717538, +4726256, +4735050, +4743923, +4752875, +4761905, +4771015, +4780206, +4789479, +4798833, +4808271, +4817791, +4827397, +4837087, +4846864, +4856727, +4866678, +4876717, +4886846, +4897064, +4907374, +4917775, +4928269, +4938858, +4949540, +4960318, +4971192, +4982165, +4993235, +5004404, +5015674, +5027046, +5038520, +5050097, +5061779, +5073567, +5085461, +5097464, +5109575, +5121797, +5134129, +5146575, +5159134, +5171808, +5184598, +5197505, +5210532, +5223678, +5236946, +5250336, +5263851, +5277491, +5291258, +5305153, +5319177, +5333334, +5347623, +5362046, +5376605, +5391301, +5406137, +5421113, +5436231, +5451493, +5466902, +5482457, +5498161, +5514017, +5530025, +5546190, +5562509, +5578988, +5595627, +5612428, +5629395, +5646528, +5663830, +5681302, +5698948, +5716769, +5734768, +5752946, +5771306, +5789853, +5808585, +5827506, +5846620, +5865930, +5885435, +5905141, +5925049, +5945162, +5965485, +5986018, +6006764, +6027728, +6048912, +6070320, +6091953, +6113815, +6135911, +6158244, +6180815, +6203629, +6226689, +6250000, +6273566, +6297389, +6321473, +6345822, +6370443, +6395335, +6420506, +6445958, +6471696, +6497727, +6524052, +6550677, +6577607, +6604846, +6632401, +6660274, +6688472, +6717000, +6745865, +6775069, +6804620, +6834523, +6864785, +6895412, +6926408, +6957781, +6989537, +7021685, +7054228, +7087174, +7120530, +7154305, +7188506, +7223139, +7258212, +7293734, +7329713, +7366159, +7403077, +7440477, +7478370, +7516765, +7555669, +7595092, +7635046, +7675540, +7716588, +7758195, +7800374, +7843138, +7886498, +7930468, +7975056, +8020277, +8066143, +8112672, +8159871, +8207757, +8256344, +8305649, +8355688, +8406472, +8458020, +8510350, +8563480, +8617424, +8672202, +8727833, +8784337, +8841737, +8900047, +8959291, +9019493, +9080673, +9142861, +9206072, +9270334, +9335675, +9402124, +9469701, +9538438, +9608365, +9679513, +9751916, +9825599, +9900601, +9976955, +10054703, +10133873, +10214508, +10296649, +10380337, +10465621, +10552535, +10641132, +10731459, +10823566, +10917513, +11013342, +11111115, +11210890, +11312736, +11416704, +11522866, +11631292, +11742053, +11855231, +11970893, +12089126, +12210015, +12333659, +12460135, +12589549, +12722003, +12857605, +12996475, +13138713, +13284453, +13433823, +13586959, +13744014, +13905120, +14070443, +14240150, +14414427, +14593438, +14777387, +14966481, +15160937, +15360997, +15566879, +15778853, +15997191, +16222182, +16454149, +16693387, +16940261, +17195136, +17458424, +17730512, +18011864, +18302960, +18604311, +18916486, +19240037, +19575614, +19923900, +20285649, +20661607, +21052651, +21459702, +21883763, +22325945, +22787375, +23269364, +23773313, +24300755, +24853401, +25433027, +26041690, +26681625, +27355340, +28065492, +28815158, +29607725, +30446979, +31337218, +32283110, +33290098, +34364293, +35512714, +36743172, +38064854, +39488287, +41025679, +42691379, +44501911, +46477133, +48640570, +51020456, +53651129, +56574049, +59840962, +63516366, +67682224, +72443082, +77936533, +84345724, +91920398, +101010792, +112120887, +126008742, +143864815, +167673193, +201007600, +251007235, +334340634, +501008441, +1001073485, +1001073486 diff --git a/rce/rcecalib/dataproc/fit/binomial_weight_int.dat b/rce/rcecalib/dataproc/fit/binomial_weight_int.dat new file mode 100644 index 0000000000000000000000000000000000000000..80a304371e69c9a83c1f427ce0b0069aa1ac0e9a --- /dev/null +++ b/rce/rcecalib/dataproc/fit/binomial_weight_int.dat @@ -0,0 +1,1001 @@ +128128, +128128, +64128, +42795, +32129, +25729, +21462, +18415, +16129, +14351, +12929, +11766, +10796, +9976, +9273, +8663, +8130, +7660, +7241, +6867, +6531, +6226, +5949, +5696, +5464, +5251, +5054, +4872, +4703, +4546, +4399, +4261, +4132, +4011, +3897, +3790, +3688, +3592, +3501, +3415, +3333, +3255, +3181, +3110, +3043, +2978, +2917, +2858, +2801, +2747, +2695, +2645, +2597, +2550, +2506, +2463, +2421, +2381, +2343, +2306, +2270, +2235, +2201, +2168, +2137, +2106, +2076, +2048, +2020, +1993, +1966, +1941, +1916, +1892, +1868, +1845, +1823, +1801, +1780, +1759, +1739, +1720, +1700, +1682, +1664, +1646, +1628, +1611, +1595, +1579, +1563, +1547, +1532, +1517, +1503, +1489, +1475, +1461, +1448, +1435, +1422, +1410, +1397, +1385, +1374, +1362, +1351, +1340, +1329, +1318, +1307, +1297, +1287, +1277, +1267, +1258, +1248, +1239, +1230, +1221, +1212, +1203, +1195, +1187, +1178, +1170, +1162, +1154, +1147, +1139, +1132, +1124, +1117, +1110, +1103, +1096, +1089, +1083, +1076, +1070, +1063, +1057, +1051, +1044, +1038, +1032, +1027, +1021, +1015, +1009, +1004, +998, +993, +988, +982, +977, +972, +967, +962, +957, +952, +948, +943, +938, +934, +929, +925, +920, +916, +911, +907, +903, +899, +895, +891, +887, +883, +879, +875, +871, +867, +863, +860, +856, +853, +849, +845, +842, +838, +835, +832, +828, +825, +822, +819, +815, +812, +809, +806, +803, +800, +797, +794, +791, +788, +785, +783, +780, +777, +774, +772, +769, +766, +764, +761, +758, +756, +753, +751, +748, +746, +743, +741, +739, +736, +734, +732, +729, +727, +725, +723, +721, +718, +716, +714, +712, +710, +708, +706, +704, +702, +700, +698, +696, +694, +692, +690, +688, +686, +684, +683, +681, +679, +677, +676, +674, +672, +670, +669, +667, +665, +664, +662, +660, +659, +657, +656, +654, +652, +651, +649, +648, +646, +645, +643, +642, +641, +639, +638, +636, +635, +634, +632, +631, +629, +628, +627, +626, +624, +623, +622, +620, +619, +618, +617, +615, +614, +613, +612, +611, +610, +608, +607, +606, +605, +604, +603, +602, +601, +599, +598, +597, +596, +595, +594, +593, +592, +591, +590, +589, +588, +587, +586, +585, +584, +583, +583, +582, +581, +580, +579, +578, +577, +576, +575, +575, +574, +573, +572, +571, +570, +570, +569, +568, +567, +566, +566, +565, +564, +563, +563, +562, +561, +560, +560, +559, +558, +558, +557, +556, +556, +555, +554, +554, +553, +552, +552, +551, +550, +550, +549, +549, +548, +547, +547, +546, +546, +545, +544, +544, +543, +543, +542, +542, +541, +541, +540, +540, +539, +539, +538, +538, +537, +537, +536, +536, +535, +535, +534, +534, +533, +533, +532, +532, +532, +531, +531, +530, +530, +530, +529, +529, +528, +528, +528, +527, +527, +527, +526, +526, +525, +525, +525, +524, +524, +524, +523, +523, +523, +523, +522, +522, +522, +521, +521, +521, +521, +520, +520, +520, +519, +519, +519, +519, +519, +518, +518, +518, +518, +517, +517, +517, +517, +517, +516, +516, +516, +516, +516, +515, +515, +515, +515, +515, +515, +515, +514, +514, +514, +514, +514, +514, +514, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +512, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +513, +514, +514, +514, +514, +514, +514, +514, +515, +515, +515, +515, +515, +515, +515, +516, +516, +516, +516, +516, +517, +517, +517, +517, +517, +518, +518, +518, +518, +519, +519, +519, +519, +519, +520, +520, +520, +521, +521, +521, +521, +522, +522, +522, +523, +523, +523, +523, +524, +524, +524, +525, +525, +525, +526, +526, +527, +527, +527, +528, +528, +528, +529, +529, +530, +530, +530, +531, +531, +532, +532, +532, +533, +533, +534, +534, +535, +535, +536, +536, +537, +537, +538, +538, +539, +539, +540, +540, +541, +541, +542, +542, +543, +543, +544, +544, +545, +546, +546, +547, +547, +548, +549, +549, +550, +550, +551, +552, +552, +553, +554, +554, +555, +556, +556, +557, +558, +558, +559, +560, +560, +561, +562, +563, +563, +564, +565, +566, +566, +567, +568, +569, +570, +570, +571, +572, +573, +574, +575, +575, +576, +577, +578, +579, +580, +581, +582, +583, +583, +584, +585, +586, +587, +588, +589, +590, +591, +592, +593, +594, +595, +596, +597, +598, +599, +601, +602, +603, +604, +605, +606, +607, +608, +610, +611, +612, +613, +614, +615, +617, +618, +619, +620, +622, +623, +624, +626, +627, +628, +629, +631, +632, +634, +635, +636, +638, +639, +641, +642, +643, +645, +646, +648, +649, +651, +652, +654, +656, +657, +659, +660, +662, +664, +665, +667, +669, +670, +672, +674, +676, +677, +679, +681, +683, +684, +686, +688, +690, +692, +694, +696, +698, +700, +702, +704, +706, +708, +710, +712, +714, +716, +718, +721, +723, +725, +727, +729, +732, +734, +736, +739, +741, +743, +746, +748, +751, +753, +756, +758, +761, +764, +766, +769, +772, +774, +777, +780, +783, +785, +788, +791, +794, +797, +800, +803, +806, +809, +812, +815, +819, +822, +825, +828, +832, +835, +838, +842, +845, +849, +853, +856, +860, +863, +867, +871, +875, +879, +883, +887, +891, +895, +899, +903, +907, +911, +916, +920, +925, +929, +934, +938, +943, +948, +952, +957, +962, +967, +972, +977, +982, +988, +993, +998, +1004, +1009, +1015, +1021, +1027, +1032, +1038, +1044, +1051, +1057, +1063, +1070, +1076, +1083, +1089, +1096, +1103, +1110, +1117, +1124, +1132, +1139, +1147, +1154, +1162, +1170, +1178, +1187, +1195, +1203, +1212, +1221, +1230, +1239, +1248, +1258, +1267, +1277, +1287, +1297, +1307, +1318, +1329, +1340, +1351, +1362, +1374, +1385, +1397, +1410, +1422, +1435, +1448, +1461, +1475, +1489, +1503, +1517, +1532, +1547, +1563, +1579, +1595, +1611, +1628, +1646, +1664, +1682, +1700, +1720, +1739, +1759, +1780, +1801, +1823, +1845, +1868, +1892, +1916, +1941, +1966, +1993, +2020, +2048, +2076, +2106, +2137, +2168, +2201, +2235, +2270, +2306, +2343, +2381, +2421, +2463, +2506, +2550, +2597, +2645, +2695, +2747, +2801, +2858, +2917, +2978, +3043, +3110, +3181, +3255, +3333, +3415, +3501, +3592, +3688, +3790, +3897, +4011, +4132, +4261, +4399, +4546, +4703, +4872, +5055, +5251, +5464, +5696, +5949, +6226, +6531, +6867, +7241, +7660, +8130, +8663, +9273, +9976, +10796, +11766, +12929, +14351, +16129, +18415, +21462, +25729, +32129, +42796, +64129, +128137, +128137, diff --git a/rce/rcecalib/dataproc/fit/errf_ext.dat b/rce/rcecalib/dataproc/fit/errf_ext.dat new file mode 100644 index 0000000000000000000000000000000000000000..46c6ba216a62a461ac554e8f6de555dd68507519 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/errf_ext.dat @@ -0,0 +1,7001 @@ +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000000f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000001f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000002f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000003f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000004f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000005f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000006f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000007f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000008f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000009f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000010f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000011f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000012f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000013f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000014f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000015f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000016f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000017f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000018f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000019f, +0.000020f, +0.000020f, +0.000020f, +0.000020f, +0.000020f, +0.000020f, +0.000020f, +0.000020f, +0.000021f, +0.000021f, +0.000021f, +0.000021f, +0.000021f, +0.000021f, +0.000021f, +0.000021f, +0.000022f, +0.000022f, +0.000022f, +0.000022f, +0.000022f, +0.000022f, +0.000022f, +0.000023f, +0.000023f, +0.000023f, +0.000023f, +0.000023f, +0.000023f, +0.000023f, +0.000023f, +0.000024f, +0.000024f, +0.000024f, +0.000024f, +0.000024f, +0.000024f, +0.000025f, +0.000025f, +0.000025f, +0.000025f, +0.000025f, +0.000025f, +0.000025f, +0.000026f, +0.000026f, +0.000026f, +0.000026f, +0.000026f, +0.000026f, +0.000027f, +0.000027f, +0.000027f, +0.000027f, +0.000027f, +0.000027f, +0.000028f, +0.000028f, +0.000028f, +0.000028f, +0.000028f, +0.000028f, +0.000028f, +0.000029f, +0.000029f, +0.000029f, +0.000029f, +0.000029f, +0.000030f, +0.000030f, +0.000030f, +0.000030f, +0.000030f, +0.000030f, +0.000031f, +0.000031f, +0.000031f, +0.000031f, +0.000031f, +0.000032f, +0.000032f, +0.000032f, +0.000032f, +0.000032f, +0.000033f, +0.000033f, +0.000033f, +0.000033f, +0.000033f, +0.000033f, +0.000034f, +0.000034f, +0.000034f, +0.000034f, +0.000035f, +0.000035f, +0.000035f, +0.000035f, +0.000035f, +0.000036f, +0.000036f, +0.000036f, +0.000036f, +0.000036f, +0.000037f, +0.000037f, +0.000037f, +0.000037f, +0.000038f, +0.000038f, +0.000038f, +0.000038f, +0.000038f, +0.000039f, +0.000039f, +0.000039f, +0.000039f, +0.000040f, +0.000040f, +0.000040f, +0.000040f, +0.000041f, +0.000041f, +0.000041f, +0.000041f, +0.000041f, +0.000042f, +0.000042f, +0.000042f, +0.000042f, +0.000043f, +0.000043f, +0.000043f, +0.000043f, +0.000044f, +0.000044f, +0.000044f, +0.000044f, +0.000045f, +0.000045f, +0.000045f, +0.000046f, +0.000046f, +0.000046f, +0.000046f, +0.000047f, +0.000047f, +0.000047f, +0.000047f, +0.000048f, +0.000048f, +0.000048f, +0.000049f, +0.000049f, +0.000049f, +0.000049f, +0.000050f, +0.000050f, +0.000050f, +0.000051f, +0.000051f, +0.000051f, +0.000051f, +0.000052f, +0.000052f, +0.000052f, +0.000053f, +0.000053f, +0.000053f, +0.000054f, +0.000054f, +0.000054f, +0.000055f, +0.000055f, +0.000055f, +0.000056f, +0.000056f, +0.000056f, +0.000057f, +0.000057f, +0.000057f, +0.000057f, +0.000058f, +0.000058f, +0.000059f, +0.000059f, +0.000059f, +0.000060f, +0.000060f, +0.000060f, +0.000061f, +0.000061f, +0.000061f, +0.000062f, +0.000062f, +0.000062f, +0.000063f, +0.000063f, +0.000063f, +0.000064f, +0.000064f, +0.000065f, +0.000065f, +0.000065f, +0.000066f, +0.000066f, +0.000066f, +0.000067f, +0.000067f, +0.000068f, +0.000068f, +0.000068f, +0.000069f, +0.000069f, +0.000070f, +0.000070f, +0.000070f, +0.000071f, +0.000071f, +0.000072f, +0.000072f, +0.000072f, +0.000073f, +0.000073f, +0.000074f, +0.000074f, +0.000074f, +0.000075f, +0.000075f, +0.000076f, +0.000076f, +0.000077f, +0.000077f, +0.000077f, +0.000078f, +0.000078f, +0.000079f, +0.000079f, +0.000080f, +0.000080f, +0.000081f, +0.000081f, +0.000082f, +0.000082f, +0.000082f, +0.000083f, +0.000083f, +0.000084f, +0.000084f, +0.000085f, +0.000085f, +0.000086f, +0.000086f, +0.000087f, +0.000087f, +0.000088f, +0.000088f, +0.000089f, +0.000089f, +0.000090f, +0.000090f, +0.000091f, +0.000091f, +0.000092f, +0.000092f, +0.000093f, +0.000093f, +0.000094f, +0.000094f, +0.000095f, +0.000095f, +0.000096f, +0.000097f, +0.000097f, +0.000098f, +0.000098f, +0.000099f, +0.000099f, +0.000100f, +0.000100f, +0.000101f, +0.000102f, +0.000102f, +0.000103f, +0.000103f, +0.000104f, +0.000104f, +0.000105f, +0.000106f, +0.000106f, +0.000107f, +0.000107f, +0.000108f, +0.000109f, +0.000109f, +0.000110f, +0.000110f, +0.000111f, +0.000112f, +0.000112f, +0.000113f, +0.000114f, +0.000114f, +0.000115f, +0.000115f, +0.000116f, +0.000117f, +0.000117f, +0.000118f, +0.000119f, +0.000119f, +0.000120f, +0.000121f, +0.000121f, +0.000122f, +0.000123f, +0.000123f, +0.000124f, +0.000125f, +0.000125f, +0.000126f, +0.000127f, +0.000128f, +0.000128f, +0.000129f, +0.000130f, +0.000130f, +0.000131f, +0.000132f, +0.000133f, +0.000133f, +0.000134f, +0.000135f, +0.000135f, +0.000136f, +0.000137f, +0.000138f, +0.000138f, +0.000139f, +0.000140f, +0.000141f, +0.000142f, +0.000142f, +0.000143f, +0.000144f, +0.000145f, +0.000145f, +0.000146f, +0.000147f, +0.000148f, +0.000149f, +0.000150f, +0.000150f, +0.000151f, +0.000152f, +0.000153f, +0.000154f, +0.000154f, +0.000155f, +0.000156f, +0.000157f, +0.000158f, +0.000159f, +0.000160f, +0.000160f, +0.000161f, +0.000162f, +0.000163f, +0.000164f, +0.000165f, +0.000166f, +0.000167f, +0.000168f, +0.000169f, +0.000169f, +0.000170f, +0.000171f, +0.000172f, +0.000173f, +0.000174f, +0.000175f, +0.000176f, +0.000177f, +0.000178f, +0.000179f, +0.000180f, +0.000181f, +0.000182f, +0.000183f, +0.000184f, +0.000185f, +0.000186f, +0.000187f, +0.000188f, +0.000189f, +0.000190f, +0.000191f, +0.000192f, +0.000193f, +0.000194f, +0.000195f, +0.000196f, +0.000197f, +0.000198f, +0.000199f, +0.000200f, +0.000201f, +0.000202f, +0.000203f, +0.000205f, +0.000206f, +0.000207f, +0.000208f, +0.000209f, +0.000210f, +0.000211f, +0.000212f, +0.000214f, +0.000215f, +0.000216f, +0.000217f, +0.000218f, +0.000219f, +0.000220f, +0.000222f, +0.000223f, +0.000224f, +0.000225f, +0.000226f, +0.000228f, +0.000229f, +0.000230f, +0.000231f, +0.000232f, +0.000234f, +0.000235f, +0.000236f, +0.000237f, +0.000239f, +0.000240f, +0.000241f, +0.000243f, +0.000244f, +0.000245f, +0.000246f, +0.000248f, +0.000249f, +0.000250f, +0.000252f, +0.000253f, +0.000254f, +0.000256f, +0.000257f, +0.000258f, +0.000260f, +0.000261f, +0.000262f, +0.000264f, +0.000265f, +0.000267f, +0.000268f, +0.000270f, +0.000271f, +0.000272f, +0.000274f, +0.000275f, +0.000277f, +0.000278f, +0.000280f, +0.000281f, +0.000283f, +0.000284f, +0.000286f, +0.000287f, +0.000289f, +0.000290f, +0.000292f, +0.000293f, +0.000295f, +0.000296f, +0.000298f, +0.000299f, +0.000301f, +0.000302f, +0.000304f, +0.000306f, +0.000307f, +0.000309f, +0.000310f, +0.000312f, +0.000314f, +0.000315f, +0.000317f, +0.000319f, +0.000320f, +0.000322f, +0.000324f, +0.000325f, +0.000327f, +0.000329f, +0.000330f, +0.000332f, +0.000334f, +0.000335f, +0.000337f, +0.000339f, +0.000341f, +0.000342f, +0.000344f, +0.000346f, +0.000348f, +0.000350f, +0.000351f, +0.000353f, +0.000355f, +0.000357f, +0.000359f, +0.000361f, +0.000362f, +0.000364f, +0.000366f, +0.000368f, +0.000370f, +0.000372f, +0.000374f, +0.000376f, +0.000378f, +0.000380f, +0.000382f, +0.000384f, +0.000385f, +0.000387f, +0.000389f, +0.000391f, +0.000393f, +0.000396f, +0.000398f, +0.000400f, +0.000402f, +0.000404f, +0.000406f, +0.000408f, +0.000410f, +0.000412f, +0.000414f, +0.000416f, +0.000418f, +0.000420f, +0.000423f, +0.000425f, +0.000427f, +0.000429f, +0.000431f, +0.000434f, +0.000436f, +0.000438f, +0.000440f, +0.000442f, +0.000445f, +0.000447f, +0.000449f, +0.000451f, +0.000454f, +0.000456f, +0.000458f, +0.000461f, +0.000463f, +0.000465f, +0.000468f, +0.000470f, +0.000472f, +0.000475f, +0.000477f, +0.000480f, +0.000482f, +0.000485f, +0.000487f, +0.000489f, +0.000492f, +0.000494f, +0.000497f, +0.000499f, +0.000502f, +0.000504f, +0.000507f, +0.000510f, +0.000512f, +0.000515f, +0.000517f, +0.000520f, +0.000522f, +0.000525f, +0.000528f, +0.000530f, +0.000533f, +0.000536f, +0.000538f, +0.000541f, +0.000544f, +0.000547f, +0.000549f, +0.000552f, +0.000555f, +0.000558f, +0.000560f, +0.000563f, +0.000566f, +0.000569f, +0.000572f, +0.000574f, +0.000577f, +0.000580f, +0.000583f, +0.000586f, +0.000589f, +0.000592f, +0.000595f, +0.000598f, +0.000601f, +0.000604f, +0.000607f, +0.000610f, +0.000613f, +0.000616f, +0.000619f, +0.000622f, +0.000625f, +0.000628f, +0.000631f, +0.000634f, +0.000637f, +0.000641f, +0.000644f, +0.000647f, +0.000650f, +0.000653f, +0.000657f, +0.000660f, +0.000663f, +0.000666f, +0.000670f, +0.000673f, +0.000676f, +0.000680f, +0.000683f, +0.000686f, +0.000690f, +0.000693f, +0.000696f, +0.000700f, +0.000703f, +0.000707f, +0.000710f, +0.000714f, +0.000717f, +0.000721f, +0.000724f, +0.000728f, +0.000731f, +0.000735f, +0.000739f, +0.000742f, +0.000746f, +0.000749f, +0.000753f, +0.000757f, +0.000760f, +0.000764f, +0.000768f, +0.000772f, +0.000775f, +0.000779f, +0.000783f, +0.000787f, +0.000791f, +0.000794f, +0.000798f, +0.000802f, +0.000806f, +0.000810f, +0.000814f, +0.000818f, +0.000822f, +0.000826f, +0.000830f, +0.000834f, +0.000838f, +0.000842f, +0.000846f, +0.000850f, +0.000854f, +0.000858f, +0.000863f, +0.000867f, +0.000871f, +0.000875f, +0.000879f, +0.000884f, +0.000888f, +0.000892f, +0.000896f, +0.000901f, +0.000905f, +0.000909f, +0.000914f, +0.000918f, +0.000923f, +0.000927f, +0.000931f, +0.000936f, +0.000940f, +0.000945f, +0.000949f, +0.000954f, +0.000959f, +0.000963f, +0.000968f, +0.000972f, +0.000977f, +0.000982f, +0.000986f, +0.000991f, +0.000996f, +0.001001f, +0.001005f, +0.001010f, +0.001015f, +0.001020f, +0.001025f, +0.001030f, +0.001034f, +0.001039f, +0.001044f, +0.001049f, +0.001054f, +0.001059f, +0.001064f, +0.001069f, +0.001074f, +0.001080f, +0.001085f, +0.001090f, +0.001095f, +0.001100f, +0.001105f, +0.001111f, +0.001116f, +0.001121f, +0.001126f, +0.001132f, +0.001137f, +0.001142f, +0.001148f, +0.001153f, +0.001159f, +0.001164f, +0.001170f, +0.001175f, +0.001181f, +0.001186f, +0.001192f, +0.001197f, +0.001203f, +0.001209f, +0.001214f, +0.001220f, +0.001226f, +0.001232f, +0.001237f, +0.001243f, +0.001249f, +0.001255f, +0.001261f, +0.001267f, +0.001273f, +0.001278f, +0.001284f, +0.001290f, +0.001296f, +0.001303f, +0.001309f, +0.001315f, +0.001321f, +0.001327f, +0.001333f, +0.001339f, +0.001346f, +0.001352f, +0.001358f, +0.001364f, +0.001371f, +0.001377f, +0.001384f, +0.001390f, +0.001397f, +0.001403f, +0.001409f, +0.001416f, +0.001423f, +0.001429f, +0.001436f, +0.001442f, +0.001449f, +0.001456f, +0.001463f, +0.001469f, +0.001476f, +0.001483f, +0.001490f, +0.001497f, +0.001503f, +0.001510f, +0.001517f, +0.001524f, +0.001531f, +0.001538f, +0.001546f, +0.001553f, +0.001560f, +0.001567f, +0.001574f, +0.001581f, +0.001589f, +0.001596f, +0.001603f, +0.001611f, +0.001618f, +0.001625f, +0.001633f, +0.001640f, +0.001648f, +0.001655f, +0.001663f, +0.001670f, +0.001678f, +0.001686f, +0.001693f, +0.001701f, +0.001709f, +0.001717f, +0.001725f, +0.001732f, +0.001740f, +0.001748f, +0.001756f, +0.001764f, +0.001772f, +0.001780f, +0.001788f, +0.001796f, +0.001805f, +0.001813f, +0.001821f, +0.001829f, +0.001837f, +0.001846f, +0.001854f, +0.001863f, +0.001871f, +0.001879f, +0.001888f, +0.001896f, +0.001905f, +0.001914f, +0.001922f, +0.001931f, +0.001940f, +0.001948f, +0.001957f, +0.001966f, +0.001975f, +0.001984f, +0.001993f, +0.002001f, +0.002010f, +0.002020f, +0.002029f, +0.002038f, +0.002047f, +0.002056f, +0.002065f, +0.002074f, +0.002084f, +0.002093f, +0.002102f, +0.002112f, +0.002121f, +0.002131f, +0.002140f, +0.002150f, +0.002159f, +0.002169f, +0.002179f, +0.002188f, +0.002198f, +0.002208f, +0.002218f, +0.002228f, +0.002238f, +0.002248f, +0.002257f, +0.002268f, +0.002278f, +0.002288f, +0.002298f, +0.002308f, +0.002318f, +0.002329f, +0.002339f, +0.002349f, +0.002360f, +0.002370f, +0.002381f, +0.002391f, +0.002402f, +0.002412f, +0.002423f, +0.002434f, +0.002444f, +0.002455f, +0.002466f, +0.002477f, +0.002488f, +0.002499f, +0.002510f, +0.002521f, +0.002532f, +0.002543f, +0.002554f, +0.002565f, +0.002576f, +0.002588f, +0.002599f, +0.002611f, +0.002622f, +0.002633f, +0.002645f, +0.002657f, +0.002668f, +0.002680f, +0.002692f, +0.002703f, +0.002715f, +0.002727f, +0.002739f, +0.002751f, +0.002763f, +0.002775f, +0.002787f, +0.002799f, +0.002811f, +0.002823f, +0.002836f, +0.002848f, +0.002860f, +0.002873f, +0.002885f, +0.002898f, +0.002910f, +0.002923f, +0.002936f, +0.002948f, +0.002961f, +0.002974f, +0.002987f, +0.003000f, +0.003013f, +0.003026f, +0.003039f, +0.003052f, +0.003065f, +0.003078f, +0.003091f, +0.003105f, +0.003118f, +0.003132f, +0.003145f, +0.003159f, +0.003172f, +0.003186f, +0.003199f, +0.003213f, +0.003227f, +0.003241f, +0.003255f, +0.003269f, +0.003283f, +0.003297f, +0.003311f, +0.003325f, +0.003339f, +0.003354f, +0.003368f, +0.003382f, +0.003397f, +0.003411f, +0.003426f, +0.003440f, +0.003455f, +0.003470f, +0.003485f, +0.003499f, +0.003514f, +0.003529f, +0.003544f, +0.003559f, +0.003574f, +0.003590f, +0.003605f, +0.003620f, +0.003635f, +0.003651f, +0.003666f, +0.003682f, +0.003697f, +0.003713f, +0.003729f, +0.003745f, +0.003760f, +0.003776f, +0.003792f, +0.003808f, +0.003824f, +0.003840f, +0.003857f, +0.003873f, +0.003889f, +0.003905f, +0.003922f, +0.003938f, +0.003955f, +0.003972f, +0.003988f, +0.004005f, +0.004022f, +0.004039f, +0.004056f, +0.004073f, +0.004090f, +0.004107f, +0.004124f, +0.004141f, +0.004158f, +0.004176f, +0.004193f, +0.004211f, +0.004228f, +0.004246f, +0.004264f, +0.004282f, +0.004299f, +0.004317f, +0.004335f, +0.004353f, +0.004371f, +0.004390f, +0.004408f, +0.004426f, +0.004444f, +0.004463f, +0.004481f, +0.004500f, +0.004519f, +0.004537f, +0.004556f, +0.004575f, +0.004594f, +0.004613f, +0.004632f, +0.004651f, +0.004670f, +0.004690f, +0.004709f, +0.004728f, +0.004748f, +0.004767f, +0.004787f, +0.004807f, +0.004827f, +0.004846f, +0.004866f, +0.004886f, +0.004906f, +0.004927f, +0.004947f, +0.004967f, +0.004987f, +0.005008f, +0.005028f, +0.005049f, +0.005070f, +0.005090f, +0.005111f, +0.005132f, +0.005153f, +0.005174f, +0.005195f, +0.005216f, +0.005238f, +0.005259f, +0.005280f, +0.005302f, +0.005324f, +0.005345f, +0.005367f, +0.005389f, +0.005411f, +0.005433f, +0.005455f, +0.005477f, +0.005499f, +0.005521f, +0.005544f, +0.005566f, +0.005589f, +0.005611f, +0.005634f, +0.005657f, +0.005680f, +0.005703f, +0.005726f, +0.005749f, +0.005772f, +0.005795f, +0.005819f, +0.005842f, +0.005866f, +0.005889f, +0.005913f, +0.005937f, +0.005961f, +0.005984f, +0.006009f, +0.006033f, +0.006057f, +0.006081f, +0.006106f, +0.006130f, +0.006155f, +0.006179f, +0.006204f, +0.006229f, +0.006254f, +0.006279f, +0.006304f, +0.006329f, +0.006354f, +0.006379f, +0.006405f, +0.006430f, +0.006456f, +0.006482f, +0.006507f, +0.006533f, +0.006559f, +0.006585f, +0.006612f, +0.006638f, +0.006664f, +0.006691f, +0.006717f, +0.006744f, +0.006770f, +0.006797f, +0.006824f, +0.006851f, +0.006878f, +0.006905f, +0.006933f, +0.006960f, +0.006988f, +0.007015f, +0.007043f, +0.007071f, +0.007098f, +0.007126f, +0.007154f, +0.007183f, +0.007211f, +0.007239f, +0.007268f, +0.007296f, +0.007325f, +0.007353f, +0.007382f, +0.007411f, +0.007440f, +0.007469f, +0.007499f, +0.007528f, +0.007557f, +0.007587f, +0.007617f, +0.007646f, +0.007676f, +0.007706f, +0.007736f, +0.007766f, +0.007796f, +0.007827f, +0.007857f, +0.007888f, +0.007919f, +0.007949f, +0.007980f, +0.008011f, +0.008042f, +0.008073f, +0.008105f, +0.008136f, +0.008168f, +0.008199f, +0.008231f, +0.008263f, +0.008295f, +0.008327f, +0.008359f, +0.008391f, +0.008424f, +0.008456f, +0.008489f, +0.008521f, +0.008554f, +0.008587f, +0.008620f, +0.008653f, +0.008687f, +0.008720f, +0.008754f, +0.008787f, +0.008821f, +0.008855f, +0.008889f, +0.008923f, +0.008957f, +0.008991f, +0.009026f, +0.009060f, +0.009095f, +0.009130f, +0.009164f, +0.009199f, +0.009234f, +0.009270f, +0.009305f, +0.009340f, +0.009376f, +0.009412f, +0.009448f, +0.009483f, +0.009520f, +0.009556f, +0.009592f, +0.009628f, +0.009665f, +0.009702f, +0.009738f, +0.009775f, +0.009812f, +0.009849f, +0.009887f, +0.009924f, +0.009961f, +0.009999f, +0.010037f, +0.010075f, +0.010113f, +0.010151f, +0.010189f, +0.010227f, +0.010266f, +0.010305f, +0.010343f, +0.010382f, +0.010421f, +0.010460f, +0.010500f, +0.010539f, +0.010579f, +0.010618f, +0.010658f, +0.010698f, +0.010738f, +0.010778f, +0.010818f, +0.010859f, +0.010899f, +0.010940f, +0.010981f, +0.011022f, +0.011063f, +0.011104f, +0.011146f, +0.011187f, +0.011229f, +0.011270f, +0.011312f, +0.011354f, +0.011397f, +0.011439f, +0.011481f, +0.011524f, +0.011567f, +0.011609f, +0.011652f, +0.011696f, +0.011739f, +0.011782f, +0.011826f, +0.011869f, +0.011913f, +0.011957f, +0.012001f, +0.012046f, +0.012090f, +0.012135f, +0.012179f, +0.012224f, +0.012269f, +0.012314f, +0.012359f, +0.012405f, +0.012450f, +0.012496f, +0.012542f, +0.012588f, +0.012634f, +0.012680f, +0.012726f, +0.012773f, +0.012820f, +0.012867f, +0.012914f, +0.012961f, +0.013008f, +0.013055f, +0.013103f, +0.013151f, +0.013199f, +0.013247f, +0.013295f, +0.013343f, +0.013392f, +0.013440f, +0.013489f, +0.013538f, +0.013587f, +0.013637f, +0.013686f, +0.013736f, +0.013785f, +0.013835f, +0.013885f, +0.013935f, +0.013986f, +0.014036f, +0.014087f, +0.014138f, +0.014189f, +0.014240f, +0.014291f, +0.014343f, +0.014394f, +0.014446f, +0.014498f, +0.014550f, +0.014602f, +0.014655f, +0.014707f, +0.014760f, +0.014813f, +0.014866f, +0.014919f, +0.014972f, +0.015026f, +0.015080f, +0.015134f, +0.015188f, +0.015242f, +0.015296f, +0.015351f, +0.015406f, +0.015460f, +0.015515f, +0.015571f, +0.015626f, +0.015682f, +0.015737f, +0.015793f, +0.015849f, +0.015906f, +0.015962f, +0.016019f, +0.016075f, +0.016132f, +0.016189f, +0.016247f, +0.016304f, +0.016362f, +0.016419f, +0.016477f, +0.016536f, +0.016594f, +0.016652f, +0.016711f, +0.016770f, +0.016829f, +0.016888f, +0.016947f, +0.017007f, +0.017067f, +0.017127f, +0.017187f, +0.017247f, +0.017307f, +0.017368f, +0.017429f, +0.017490f, +0.017551f, +0.017612f, +0.017674f, +0.017736f, +0.017798f, +0.017860f, +0.017922f, +0.017984f, +0.018047f, +0.018110f, +0.018173f, +0.018236f, +0.018300f, +0.018363f, +0.018427f, +0.018491f, +0.018555f, +0.018619f, +0.018684f, +0.018749f, +0.018814f, +0.018879f, +0.018944f, +0.019009f, +0.019075f, +0.019141f, +0.019207f, +0.019273f, +0.019340f, +0.019406f, +0.019473f, +0.019540f, +0.019608f, +0.019675f, +0.019743f, +0.019810f, +0.019878f, +0.019947f, +0.020015f, +0.020084f, +0.020152f, +0.020222f, +0.020291f, +0.020360f, +0.020430f, +0.020500f, +0.020570f, +0.020640f, +0.020710f, +0.020781f, +0.020852f, +0.020923f, +0.020994f, +0.021065f, +0.021137f, +0.021209f, +0.021281f, +0.021353f, +0.021426f, +0.021498f, +0.021571f, +0.021644f, +0.021718f, +0.021791f, +0.021865f, +0.021939f, +0.022013f, +0.022088f, +0.022162f, +0.022237f, +0.022312f, +0.022387f, +0.022463f, +0.022538f, +0.022614f, +0.022690f, +0.022766f, +0.022843f, +0.022920f, +0.022997f, +0.023074f, +0.023151f, +0.023229f, +0.023307f, +0.023385f, +0.023463f, +0.023541f, +0.023620f, +0.023699f, +0.023778f, +0.023857f, +0.023937f, +0.024017f, +0.024097f, +0.024177f, +0.024258f, +0.024338f, +0.024419f, +0.024500f, +0.024582f, +0.024663f, +0.024745f, +0.024827f, +0.024910f, +0.024992f, +0.025075f, +0.025158f, +0.025241f, +0.025324f, +0.025408f, +0.025492f, +0.025576f, +0.025660f, +0.025745f, +0.025830f, +0.025915f, +0.026000f, +0.026086f, +0.026172f, +0.026258f, +0.026344f, +0.026430f, +0.026517f, +0.026604f, +0.026691f, +0.026779f, +0.026866f, +0.026954f, +0.027042f, +0.027131f, +0.027219f, +0.027308f, +0.027397f, +0.027487f, +0.027576f, +0.027666f, +0.027756f, +0.027846f, +0.027937f, +0.028028f, +0.028119f, +0.028210f, +0.028302f, +0.028394f, +0.028486f, +0.028578f, +0.028670f, +0.028763f, +0.028856f, +0.028950f, +0.029043f, +0.029137f, +0.029231f, +0.029325f, +0.029420f, +0.029515f, +0.029610f, +0.029705f, +0.029801f, +0.029896f, +0.029992f, +0.030089f, +0.030185f, +0.030282f, +0.030379f, +0.030477f, +0.030574f, +0.030672f, +0.030770f, +0.030869f, +0.030967f, +0.031066f, +0.031166f, +0.031265f, +0.031365f, +0.031465f, +0.031565f, +0.031665f, +0.031766f, +0.031867f, +0.031968f, +0.032070f, +0.032172f, +0.032274f, +0.032376f, +0.032479f, +0.032582f, +0.032685f, +0.032788f, +0.032892f, +0.032996f, +0.033100f, +0.033205f, +0.033310f, +0.033415f, +0.033520f, +0.033626f, +0.033731f, +0.033838f, +0.033944f, +0.034051f, +0.034158f, +0.034265f, +0.034372f, +0.034480f, +0.034588f, +0.034697f, +0.034805f, +0.034914f, +0.035023f, +0.035133f, +0.035243f, +0.035353f, +0.035463f, +0.035574f, +0.035684f, +0.035796f, +0.035907f, +0.036019f, +0.036131f, +0.036243f, +0.036356f, +0.036469f, +0.036582f, +0.036695f, +0.036809f, +0.036923f, +0.037037f, +0.037152f, +0.037267f, +0.037382f, +0.037497f, +0.037613f, +0.037729f, +0.037846f, +0.037962f, +0.038079f, +0.038196f, +0.038314f, +0.038432f, +0.038550f, +0.038668f, +0.038787f, +0.038906f, +0.039025f, +0.039145f, +0.039265f, +0.039385f, +0.039506f, +0.039626f, +0.039747f, +0.039869f, +0.039990f, +0.040112f, +0.040235f, +0.040357f, +0.040480f, +0.040603f, +0.040727f, +0.040851f, +0.040975f, +0.041099f, +0.041224f, +0.041349f, +0.041474f, +0.041600f, +0.041726f, +0.041852f, +0.041979f, +0.042106f, +0.042233f, +0.042361f, +0.042488f, +0.042617f, +0.042745f, +0.042874f, +0.043003f, +0.043132f, +0.043262f, +0.043392f, +0.043522f, +0.043653f, +0.043784f, +0.043915f, +0.044047f, +0.044179f, +0.044311f, +0.044443f, +0.044576f, +0.044710f, +0.044843f, +0.044977f, +0.045111f, +0.045245f, +0.045380f, +0.045515f, +0.045651f, +0.045787f, +0.045923f, +0.046059f, +0.046196f, +0.046333f, +0.046470f, +0.046608f, +0.046746f, +0.046884f, +0.047023f, +0.047162f, +0.047302f, +0.047441f, +0.047581f, +0.047722f, +0.047862f, +0.048003f, +0.048145f, +0.048286f, +0.048428f, +0.048571f, +0.048713f, +0.048856f, +0.049000f, +0.049143f, +0.049288f, +0.049432f, +0.049577f, +0.049722f, +0.049867f, +0.050013f, +0.050159f, +0.050305f, +0.050452f, +0.050599f, +0.050746f, +0.050894f, +0.051042f, +0.051191f, +0.051339f, +0.051489f, +0.051638f, +0.051788f, +0.051938f, +0.052089f, +0.052239f, +0.052391f, +0.052542f, +0.052694f, +0.052846f, +0.052999f, +0.053152f, +0.053305f, +0.053459f, +0.053613f, +0.053767f, +0.053922f, +0.054077f, +0.054232f, +0.054388f, +0.054544f, +0.054701f, +0.054857f, +0.055015f, +0.055172f, +0.055330f, +0.055488f, +0.055647f, +0.055806f, +0.055965f, +0.056125f, +0.056285f, +0.056445f, +0.056606f, +0.056767f, +0.056929f, +0.057090f, +0.057253f, +0.057415f, +0.057578f, +0.057741f, +0.057905f, +0.058069f, +0.058233f, +0.058398f, +0.058563f, +0.058729f, +0.058895f, +0.059061f, +0.059227f, +0.059394f, +0.059562f, +0.059729f, +0.059897f, +0.060066f, +0.060235f, +0.060404f, +0.060573f, +0.060743f, +0.060914f, +0.061084f, +0.061255f, +0.061427f, +0.061598f, +0.061771f, +0.061943f, +0.062116f, +0.062289f, +0.062463f, +0.062637f, +0.062811f, +0.062986f, +0.063161f, +0.063337f, +0.063513f, +0.063689f, +0.063866f, +0.064043f, +0.064220f, +0.064398f, +0.064576f, +0.064755f, +0.064934f, +0.065113f, +0.065293f, +0.065473f, +0.065654f, +0.065835f, +0.066016f, +0.066198f, +0.066380f, +0.066562f, +0.066745f, +0.066928f, +0.067112f, +0.067296f, +0.067480f, +0.067665f, +0.067850f, +0.068036f, +0.068222f, +0.068408f, +0.068595f, +0.068782f, +0.068969f, +0.069157f, +0.069346f, +0.069534f, +0.069724f, +0.069913f, +0.070103f, +0.070293f, +0.070484f, +0.070675f, +0.070867f, +0.071058f, +0.071251f, +0.071443f, +0.071636f, +0.071830f, +0.072024f, +0.072218f, +0.072413f, +0.072608f, +0.072803f, +0.072999f, +0.073196f, +0.073392f, +0.073589f, +0.073787f, +0.073985f, +0.074183f, +0.074382f, +0.074581f, +0.074781f, +0.074980f, +0.075181f, +0.075382f, +0.075583f, +0.075784f, +0.075986f, +0.076189f, +0.076392f, +0.076595f, +0.076798f, +0.077002f, +0.077207f, +0.077412f, +0.077617f, +0.077823f, +0.078029f, +0.078235f, +0.078442f, +0.078650f, +0.078857f, +0.079066f, +0.079274f, +0.079483f, +0.079693f, +0.079902f, +0.080113f, +0.080323f, +0.080534f, +0.080746f, +0.080958f, +0.081170f, +0.081383f, +0.081596f, +0.081810f, +0.082024f, +0.082238f, +0.082453f, +0.082669f, +0.082884f, +0.083100f, +0.083317f, +0.083534f, +0.083751f, +0.083969f, +0.084188f, +0.084406f, +0.084625f, +0.084845f, +0.085065f, +0.085285f, +0.085506f, +0.085727f, +0.085949f, +0.086171f, +0.086394f, +0.086617f, +0.086840f, +0.087064f, +0.087288f, +0.087513f, +0.087738f, +0.087964f, +0.088190f, +0.088416f, +0.088643f, +0.088870f, +0.089098f, +0.089326f, +0.089555f, +0.089784f, +0.090013f, +0.090243f, +0.090473f, +0.090704f, +0.090935f, +0.091167f, +0.091399f, +0.091632f, +0.091864f, +0.092098f, +0.092332f, +0.092566f, +0.092801f, +0.093036f, +0.093271f, +0.093507f, +0.093744f, +0.093981f, +0.094218f, +0.094456f, +0.094694f, +0.094933f, +0.095172f, +0.095412f, +0.095652f, +0.095892f, +0.096133f, +0.096374f, +0.096616f, +0.096858f, +0.097101f, +0.097344f, +0.097588f, +0.097832f, +0.098076f, +0.098321f, +0.098567f, +0.098812f, +0.099059f, +0.099305f, +0.099552f, +0.099800f, +0.100048f, +0.100297f, +0.100546f, +0.100795f, +0.101045f, +0.101295f, +0.101546f, +0.101797f, +0.102049f, +0.102301f, +0.102553f, +0.102806f, +0.103060f, +0.103314f, +0.103568f, +0.103823f, +0.104078f, +0.104334f, +0.104590f, +0.104847f, +0.105104f, +0.105362f, +0.105620f, +0.105878f, +0.106137f, +0.106396f, +0.106656f, +0.106917f, +0.107177f, +0.107439f, +0.107700f, +0.107962f, +0.108225f, +0.108488f, +0.108752f, +0.109016f, +0.109280f, +0.109545f, +0.109810f, +0.110076f, +0.110342f, +0.110609f, +0.110876f, +0.111144f, +0.111412f, +0.111681f, +0.111950f, +0.112219f, +0.112489f, +0.112760f, +0.113031f, +0.113302f, +0.113574f, +0.113846f, +0.114119f, +0.114392f, +0.114666f, +0.114940f, +0.115215f, +0.115490f, +0.115765f, +0.116041f, +0.116318f, +0.116595f, +0.116872f, +0.117150f, +0.117429f, +0.117707f, +0.117987f, +0.118267f, +0.118547f, +0.118828f, +0.119109f, +0.119390f, +0.119672f, +0.119955f, +0.120238f, +0.120522f, +0.120806f, +0.121090f, +0.121375f, +0.121660f, +0.121946f, +0.122233f, +0.122520f, +0.122807f, +0.123095f, +0.123383f, +0.123672f, +0.123961f, +0.124250f, +0.124541f, +0.124831f, +0.125122f, +0.125414f, +0.125706f, +0.125998f, +0.126291f, +0.126585f, +0.126879f, +0.127173f, +0.127468f, +0.127763f, +0.128059f, +0.128355f, +0.128652f, +0.128950f, +0.129247f, +0.129545f, +0.129844f, +0.130143f, +0.130443f, +0.130743f, +0.131044f, +0.131345f, +0.131646f, +0.131948f, +0.132251f, +0.132554f, +0.132857f, +0.133161f, +0.133466f, +0.133770f, +0.134076f, +0.134382f, +0.134688f, +0.134995f, +0.135302f, +0.135610f, +0.135918f, +0.136227f, +0.136536f, +0.136846f, +0.137156f, +0.137466f, +0.137778f, +0.138089f, +0.138401f, +0.138714f, +0.139027f, +0.139340f, +0.139654f, +0.139969f, +0.140284f, +0.140599f, +0.140915f, +0.141232f, +0.141549f, +0.141866f, +0.142184f, +0.142502f, +0.142821f, +0.143140f, +0.143460f, +0.143780f, +0.144101f, +0.144422f, +0.144744f, +0.145066f, +0.145389f, +0.145712f, +0.146036f, +0.146360f, +0.146684f, +0.147009f, +0.147335f, +0.147661f, +0.147987f, +0.148315f, +0.148642f, +0.148970f, +0.149298f, +0.149627f, +0.149957f, +0.150287f, +0.150617f, +0.150948f, +0.151279f, +0.151611f, +0.151944f, +0.152276f, +0.152610f, +0.152943f, +0.153278f, +0.153612f, +0.153948f, +0.154283f, +0.154620f, +0.154956f, +0.155293f, +0.155631f, +0.155969f, +0.156308f, +0.156647f, +0.156987f, +0.157327f, +0.157667f, +0.158008f, +0.158350f, +0.158692f, +0.159034f, +0.159377f, +0.159721f, +0.160065f, +0.160409f, +0.160754f, +0.161099f, +0.161445f, +0.161792f, +0.162138f, +0.162486f, +0.162834f, +0.163182f, +0.163531f, +0.163880f, +0.164230f, +0.164580f, +0.164931f, +0.165282f, +0.165634f, +0.165986f, +0.166338f, +0.166692f, +0.167045f, +0.167399f, +0.167754f, +0.168109f, +0.168464f, +0.168820f, +0.169177f, +0.169534f, +0.169891f, +0.170249f, +0.170608f, +0.170967f, +0.171326f, +0.171686f, +0.172047f, +0.172407f, +0.172769f, +0.173131f, +0.173493f, +0.173856f, +0.174219f, +0.174583f, +0.174947f, +0.175312f, +0.175677f, +0.176043f, +0.176409f, +0.176775f, +0.177142f, +0.177510f, +0.177878f, +0.178247f, +0.178616f, +0.178985f, +0.179355f, +0.179726f, +0.180097f, +0.180468f, +0.180840f, +0.181213f, +0.181586f, +0.181959f, +0.182333f, +0.182707f, +0.183082f, +0.183457f, +0.183833f, +0.184209f, +0.184586f, +0.184963f, +0.185341f, +0.185719f, +0.186098f, +0.186477f, +0.186856f, +0.187236f, +0.187617f, +0.187998f, +0.188380f, +0.188762f, +0.189144f, +0.189527f, +0.189910f, +0.190294f, +0.190679f, +0.191063f, +0.191449f, +0.191835f, +0.192221f, +0.192608f, +0.192995f, +0.193383f, +0.193771f, +0.194159f, +0.194549f, +0.194938f, +0.195328f, +0.195719f, +0.196110f, +0.196501f, +0.196893f, +0.197286f, +0.197679f, +0.198072f, +0.198466f, +0.198860f, +0.199255f, +0.199650f, +0.200046f, +0.200442f, +0.200839f, +0.201236f, +0.201634f, +0.202032f, +0.202430f, +0.202829f, +0.203229f, +0.203629f, +0.204029f, +0.204430f, +0.204832f, +0.205233f, +0.205636f, +0.206039f, +0.206442f, +0.206846f, +0.207250f, +0.207654f, +0.208059f, +0.208465f, +0.208871f, +0.209278f, +0.209685f, +0.210092f, +0.210500f, +0.210908f, +0.211317f, +0.211727f, +0.212136f, +0.212547f, +0.212957f, +0.213368f, +0.213780f, +0.214192f, +0.214605f, +0.215018f, +0.215431f, +0.215845f, +0.216259f, +0.216674f, +0.217090f, +0.217505f, +0.217922f, +0.218338f, +0.218755f, +0.219173f, +0.219591f, +0.220010f, +0.220429f, +0.220848f, +0.221268f, +0.221688f, +0.222109f, +0.222530f, +0.222952f, +0.223374f, +0.223797f, +0.224220f, +0.224643f, +0.225067f, +0.225492f, +0.225917f, +0.226342f, +0.226768f, +0.227194f, +0.227621f, +0.228048f, +0.228476f, +0.228904f, +0.229332f, +0.229761f, +0.230191f, +0.230620f, +0.231051f, +0.231481f, +0.231913f, +0.232344f, +0.232776f, +0.233209f, +0.233642f, +0.234075f, +0.234509f, +0.234943f, +0.235378f, +0.235813f, +0.236249f, +0.236685f, +0.237122f, +0.237559f, +0.237996f, +0.238434f, +0.238872f, +0.239311f, +0.239750f, +0.240190f, +0.240630f, +0.241070f, +0.241511f, +0.241953f, +0.242394f, +0.242837f, +0.243279f, +0.243722f, +0.244166f, +0.244610f, +0.245054f, +0.245499f, +0.245944f, +0.246390f, +0.246836f, +0.247283f, +0.247730f, +0.248177f, +0.248625f, +0.249073f, +0.249522f, +0.249971f, +0.250421f, +0.250871f, +0.251321f, +0.251772f, +0.252224f, +0.252675f, +0.253127f, +0.253580f, +0.254033f, +0.254486f, +0.254940f, +0.255395f, +0.255849f, +0.256304f, +0.256760f, +0.257216f, +0.257672f, +0.258129f, +0.258586f, +0.259044f, +0.259502f, +0.259961f, +0.260419f, +0.260879f, +0.261338f, +0.261799f, +0.262259f, +0.262720f, +0.263182f, +0.263643f, +0.264106f, +0.264568f, +0.265031f, +0.265495f, +0.265958f, +0.266423f, +0.266887f, +0.267353f, +0.267818f, +0.268284f, +0.268750f, +0.269217f, +0.269684f, +0.270152f, +0.270620f, +0.271088f, +0.271557f, +0.272026f, +0.272495f, +0.272965f, +0.273436f, +0.273906f, +0.274378f, +0.274849f, +0.275321f, +0.275793f, +0.276266f, +0.276739f, +0.277213f, +0.277687f, +0.278161f, +0.278636f, +0.279111f, +0.279587f, +0.280062f, +0.280539f, +0.281015f, +0.281493f, +0.281970f, +0.282448f, +0.282926f, +0.283405f, +0.283884f, +0.284363f, +0.284843f, +0.285323f, +0.285804f, +0.286285f, +0.286766f, +0.287248f, +0.287730f, +0.288212f, +0.288695f, +0.289179f, +0.289662f, +0.290146f, +0.290631f, +0.291115f, +0.291601f, +0.292086f, +0.292572f, +0.293058f, +0.293545f, +0.294032f, +0.294519f, +0.295007f, +0.295495f, +0.295984f, +0.296473f, +0.296962f, +0.297452f, +0.297942f, +0.298432f, +0.298923f, +0.299414f, +0.299905f, +0.300397f, +0.300889f, +0.301382f, +0.301875f, +0.302368f, +0.302862f, +0.303356f, +0.303850f, +0.304345f, +0.304840f, +0.305335f, +0.305831f, +0.306327f, +0.306824f, +0.307320f, +0.307818f, +0.308315f, +0.308813f, +0.309311f, +0.309810f, +0.310309f, +0.310808f, +0.311308f, +0.311808f, +0.312308f, +0.312809f, +0.313310f, +0.313811f, +0.314313f, +0.314815f, +0.315318f, +0.315821f, +0.316324f, +0.316827f, +0.317331f, +0.317835f, +0.318339f, +0.318844f, +0.319349f, +0.319855f, +0.320361f, +0.320867f, +0.321373f, +0.321880f, +0.322387f, +0.322895f, +0.323403f, +0.323911f, +0.324419f, +0.324928f, +0.325437f, +0.325946f, +0.326456f, +0.326966f, +0.327477f, +0.327987f, +0.328498f, +0.329010f, +0.329522f, +0.330034f, +0.330546f, +0.331059f, +0.331572f, +0.332085f, +0.332598f, +0.333112f, +0.333627f, +0.334141f, +0.334656f, +0.335171f, +0.335687f, +0.336202f, +0.336718f, +0.337235f, +0.337752f, +0.338269f, +0.338786f, +0.339304f, +0.339821f, +0.340340f, +0.340858f, +0.341377f, +0.341896f, +0.342416f, +0.342935f, +0.343455f, +0.343976f, +0.344496f, +0.345017f, +0.345538f, +0.346060f, +0.346582f, +0.347104f, +0.347626f, +0.348149f, +0.348672f, +0.349195f, +0.349719f, +0.350242f, +0.350767f, +0.351291f, +0.351816f, +0.352341f, +0.352866f, +0.353391f, +0.353917f, +0.354443f, +0.354969f, +0.355496f, +0.356023f, +0.356550f, +0.357078f, +0.357605f, +0.358133f, +0.358662f, +0.359190f, +0.359719f, +0.360248f, +0.360777f, +0.361307f, +0.361837f, +0.362367f, +0.362897f, +0.363428f, +0.363959f, +0.364490f, +0.365022f, +0.365553f, +0.366085f, +0.366617f, +0.367150f, +0.367683f, +0.368216f, +0.368749f, +0.369282f, +0.369816f, +0.370350f, +0.370884f, +0.371419f, +0.371954f, +0.372489f, +0.373024f, +0.373559f, +0.374095f, +0.374631f, +0.375167f, +0.375704f, +0.376241f, +0.376777f, +0.377315f, +0.377852f, +0.378390f, +0.378928f, +0.379466f, +0.380004f, +0.380543f, +0.381081f, +0.381621f, +0.382160f, +0.382699f, +0.383239f, +0.383779f, +0.384319f, +0.384860f, +0.385400f, +0.385941f, +0.386482f, +0.387023f, +0.387565f, +0.388107f, +0.388649f, +0.389191f, +0.389733f, +0.390276f, +0.390819f, +0.391362f, +0.391905f, +0.392448f, +0.392992f, +0.393536f, +0.394080f, +0.394624f, +0.395169f, +0.395714f, +0.396258f, +0.396804f, +0.397349f, +0.397894f, +0.398440f, +0.398986f, +0.399532f, +0.400078f, +0.400625f, +0.401172f, +0.401718f, +0.402266f, +0.402813f, +0.403360f, +0.403908f, +0.404456f, +0.405004f, +0.405552f, +0.406100f, +0.406649f, +0.407198f, +0.407747f, +0.408296f, +0.408845f, +0.409395f, +0.409944f, +0.410494f, +0.411044f, +0.411594f, +0.412145f, +0.412695f, +0.413246f, +0.413797f, +0.414348f, +0.414899f, +0.415450f, +0.416002f, +0.416554f, +0.417106f, +0.417658f, +0.418210f, +0.418762f, +0.419315f, +0.419867f, +0.420420f, +0.420973f, +0.421526f, +0.422080f, +0.422633f, +0.423187f, +0.423741f, +0.424295f, +0.424849f, +0.425403f, +0.425957f, +0.426512f, +0.427066f, +0.427621f, +0.428176f, +0.428731f, +0.429287f, +0.429842f, +0.430397f, +0.430953f, +0.431509f, +0.432065f, +0.432621f, +0.433177f, +0.433733f, +0.434290f, +0.434846f, +0.435403f, +0.435960f, +0.436517f, +0.437074f, +0.437631f, +0.438189f, +0.438746f, +0.439304f, +0.439861f, +0.440419f, +0.440977f, +0.441535f, +0.442093f, +0.442652f, +0.443210f, +0.443769f, +0.444327f, +0.444886f, +0.445445f, +0.446004f, +0.446563f, +0.447122f, +0.447681f, +0.448241f, +0.448800f, +0.449360f, +0.449919f, +0.450479f, +0.451039f, +0.451599f, +0.452159f, +0.452719f, +0.453280f, +0.453840f, +0.454400f, +0.454961f, +0.455522f, +0.456082f, +0.456643f, +0.457204f, +0.457765f, +0.458326f, +0.458887f, +0.459448f, +0.460010f, +0.460571f, +0.461133f, +0.461694f, +0.462256f, +0.462817f, +0.463379f, +0.463941f, +0.464503f, +0.465065f, +0.465627f, +0.466189f, +0.466751f, +0.467314f, +0.467876f, +0.468438f, +0.469001f, +0.469563f, +0.470126f, +0.470689f, +0.471251f, +0.471814f, +0.472377f, +0.472940f, +0.473503f, +0.474066f, +0.474629f, +0.475192f, +0.475755f, +0.476318f, +0.476881f, +0.477444f, +0.478008f, +0.478571f, +0.479135f, +0.479698f, +0.480261f, +0.480825f, +0.481388f, +0.481952f, +0.482516f, +0.483079f, +0.483643f, +0.484207f, +0.484771f, +0.485334f, +0.485898f, +0.486462f, +0.487026f, +0.487590f, +0.488154f, +0.488718f, +0.489282f, +0.489846f, +0.490410f, +0.490974f, +0.491538f, +0.492102f, +0.492666f, +0.493230f, +0.493794f, +0.494358f, +0.494922f, +0.495487f, +0.496051f, +0.496615f, +0.497179f, +0.497743f, +0.498307f, +0.498872f, +0.499436f, +0.500000f, +0.500000f, +0.500000f, +0.500564f, +0.501128f, +0.501693f, +0.502257f, +0.502821f, +0.503385f, +0.503949f, +0.504513f, +0.505078f, +0.505642f, +0.506206f, +0.506770f, +0.507334f, +0.507898f, +0.508462f, +0.509026f, +0.509590f, +0.510154f, +0.510718f, +0.511282f, +0.511846f, +0.512410f, +0.512974f, +0.513538f, +0.514102f, +0.514666f, +0.515229f, +0.515793f, +0.516357f, +0.516921f, +0.517484f, +0.518048f, +0.518612f, +0.519175f, +0.519739f, +0.520302f, +0.520865f, +0.521429f, +0.521992f, +0.522556f, +0.523119f, +0.523682f, +0.524245f, +0.524808f, +0.525371f, +0.525934f, +0.526497f, +0.527060f, +0.527623f, +0.528186f, +0.528749f, +0.529311f, +0.529874f, +0.530437f, +0.530999f, +0.531562f, +0.532124f, +0.532686f, +0.533249f, +0.533811f, +0.534373f, +0.534935f, +0.535497f, +0.536059f, +0.536621f, +0.537183f, +0.537744f, +0.538306f, +0.538867f, +0.539429f, +0.539990f, +0.540552f, +0.541113f, +0.541674f, +0.542235f, +0.542796f, +0.543357f, +0.543918f, +0.544478f, +0.545039f, +0.545600f, +0.546160f, +0.546720f, +0.547281f, +0.547841f, +0.548401f, +0.548961f, +0.549521f, +0.550081f, +0.550640f, +0.551200f, +0.551759f, +0.552319f, +0.552878f, +0.553437f, +0.553996f, +0.554555f, +0.555114f, +0.555673f, +0.556231f, +0.556790f, +0.557348f, +0.557907f, +0.558465f, +0.559023f, +0.559581f, +0.560139f, +0.560696f, +0.561254f, +0.561811f, +0.562369f, +0.562926f, +0.563483f, +0.564040f, +0.564597f, +0.565154f, +0.565710f, +0.566267f, +0.566823f, +0.567379f, +0.567935f, +0.568491f, +0.569047f, +0.569603f, +0.570158f, +0.570713f, +0.571269f, +0.571824f, +0.572379f, +0.572934f, +0.573488f, +0.574043f, +0.574597f, +0.575151f, +0.575705f, +0.576259f, +0.576813f, +0.577367f, +0.577920f, +0.578474f, +0.579027f, +0.579580f, +0.580133f, +0.580685f, +0.581238f, +0.581790f, +0.582342f, +0.582894f, +0.583446f, +0.583998f, +0.584550f, +0.585101f, +0.585652f, +0.586203f, +0.586754f, +0.587305f, +0.587855f, +0.588406f, +0.588956f, +0.589506f, +0.590056f, +0.590605f, +0.591155f, +0.591704f, +0.592253f, +0.592802f, +0.593351f, +0.593900f, +0.594448f, +0.594996f, +0.595544f, +0.596092f, +0.596640f, +0.597187f, +0.597734f, +0.598282f, +0.598828f, +0.599375f, +0.599922f, +0.600468f, +0.601014f, +0.601560f, +0.602106f, +0.602651f, +0.603196f, +0.603742f, +0.604286f, +0.604831f, +0.605376f, +0.605920f, +0.606464f, +0.607008f, +0.607552f, +0.608095f, +0.608638f, +0.609181f, +0.609724f, +0.610267f, +0.610809f, +0.611351f, +0.611893f, +0.612435f, +0.612977f, +0.613518f, +0.614059f, +0.614600f, +0.615140f, +0.615681f, +0.616221f, +0.616761f, +0.617301f, +0.617840f, +0.618379f, +0.618919f, +0.619457f, +0.619996f, +0.620534f, +0.621072f, +0.621610f, +0.622148f, +0.622685f, +0.623223f, +0.623759f, +0.624296f, +0.624833f, +0.625369f, +0.625905f, +0.626441f, +0.626976f, +0.627511f, +0.628046f, +0.628581f, +0.629116f, +0.629650f, +0.630184f, +0.630718f, +0.631251f, +0.631784f, +0.632317f, +0.632850f, +0.633383f, +0.633915f, +0.634447f, +0.634978f, +0.635510f, +0.636041f, +0.636572f, +0.637103f, +0.637633f, +0.638163f, +0.638693f, +0.639223f, +0.639752f, +0.640281f, +0.640810f, +0.641338f, +0.641867f, +0.642395f, +0.642922f, +0.643450f, +0.643977f, +0.644504f, +0.645031f, +0.645557f, +0.646083f, +0.646609f, +0.647134f, +0.647659f, +0.648184f, +0.648709f, +0.649233f, +0.649758f, +0.650281f, +0.650805f, +0.651328f, +0.651851f, +0.652374f, +0.652896f, +0.653418f, +0.653940f, +0.654462f, +0.654983f, +0.655504f, +0.656024f, +0.656545f, +0.657065f, +0.657584f, +0.658104f, +0.658623f, +0.659142f, +0.659660f, +0.660179f, +0.660696f, +0.661214f, +0.661731f, +0.662248f, +0.662765f, +0.663282f, +0.663798f, +0.664313f, +0.664829f, +0.665344f, +0.665859f, +0.666373f, +0.666888f, +0.667402f, +0.667915f, +0.668428f, +0.668941f, +0.669454f, +0.669966f, +0.670478f, +0.670990f, +0.671502f, +0.672013f, +0.672523f, +0.673034f, +0.673544f, +0.674054f, +0.674563f, +0.675072f, +0.675581f, +0.676089f, +0.676597f, +0.677105f, +0.677613f, +0.678120f, +0.678627f, +0.679133f, +0.679639f, +0.680145f, +0.680651f, +0.681156f, +0.681661f, +0.682165f, +0.682669f, +0.683173f, +0.683676f, +0.684179f, +0.684682f, +0.685185f, +0.685687f, +0.686189f, +0.686690f, +0.687191f, +0.687692f, +0.688192f, +0.688692f, +0.689192f, +0.689691f, +0.690190f, +0.690689f, +0.691187f, +0.691685f, +0.692182f, +0.692680f, +0.693176f, +0.693673f, +0.694169f, +0.694665f, +0.695160f, +0.695655f, +0.696150f, +0.696644f, +0.697138f, +0.697632f, +0.698125f, +0.698618f, +0.699111f, +0.699603f, +0.700095f, +0.700586f, +0.701077f, +0.701568f, +0.702058f, +0.702548f, +0.703038f, +0.703527f, +0.704016f, +0.704505f, +0.704993f, +0.705481f, +0.705968f, +0.706455f, +0.706942f, +0.707428f, +0.707914f, +0.708399f, +0.708885f, +0.709369f, +0.709854f, +0.710338f, +0.710821f, +0.711305f, +0.711788f, +0.712270f, +0.712752f, +0.713234f, +0.713715f, +0.714196f, +0.714677f, +0.715157f, +0.715637f, +0.716116f, +0.716595f, +0.717074f, +0.717552f, +0.718030f, +0.718507f, +0.718985f, +0.719461f, +0.719938f, +0.720413f, +0.720889f, +0.721364f, +0.721839f, +0.722313f, +0.722787f, +0.723261f, +0.723734f, +0.724207f, +0.724679f, +0.725151f, +0.725622f, +0.726094f, +0.726564f, +0.727035f, +0.727505f, +0.727974f, +0.728443f, +0.728912f, +0.729380f, +0.729848f, +0.730316f, +0.730783f, +0.731250f, +0.731716f, +0.732182f, +0.732647f, +0.733113f, +0.733577f, +0.734042f, +0.734505f, +0.734969f, +0.735432f, +0.735894f, +0.736357f, +0.736818f, +0.737280f, +0.737741f, +0.738201f, +0.738662f, +0.739121f, +0.739581f, +0.740039f, +0.740498f, +0.740956f, +0.741414f, +0.741871f, +0.742328f, +0.742784f, +0.743240f, +0.743696f, +0.744151f, +0.744605f, +0.745060f, +0.745514f, +0.745967f, +0.746420f, +0.746873f, +0.747325f, +0.747776f, +0.748228f, +0.748679f, +0.749129f, +0.749579f, +0.750029f, +0.750478f, +0.750927f, +0.751375f, +0.751823f, +0.752270f, +0.752717f, +0.753164f, +0.753610f, +0.754056f, +0.754501f, +0.754946f, +0.755390f, +0.755834f, +0.756278f, +0.756721f, +0.757163f, +0.757606f, +0.758047f, +0.758489f, +0.758930f, +0.759370f, +0.759810f, +0.760250f, +0.760689f, +0.761128f, +0.761566f, +0.762004f, +0.762441f, +0.762878f, +0.763315f, +0.763751f, +0.764187f, +0.764622f, +0.765057f, +0.765491f, +0.765925f, +0.766358f, +0.766791f, +0.767224f, +0.767656f, +0.768087f, +0.768519f, +0.768949f, +0.769380f, +0.769809f, +0.770239f, +0.770668f, +0.771096f, +0.771524f, +0.771952f, +0.772379f, +0.772806f, +0.773232f, +0.773658f, +0.774083f, +0.774508f, +0.774933f, +0.775357f, +0.775780f, +0.776203f, +0.776626f, +0.777048f, +0.777470f, +0.777891f, +0.778312f, +0.778732f, +0.779152f, +0.779571f, +0.779990f, +0.780409f, +0.780827f, +0.781245f, +0.781662f, +0.782078f, +0.782495f, +0.782910f, +0.783326f, +0.783741f, +0.784155f, +0.784569f, +0.784982f, +0.785395f, +0.785808f, +0.786220f, +0.786632f, +0.787043f, +0.787453f, +0.787864f, +0.788273f, +0.788683f, +0.789092f, +0.789500f, +0.789908f, +0.790315f, +0.790722f, +0.791129f, +0.791535f, +0.791941f, +0.792346f, +0.792750f, +0.793154f, +0.793558f, +0.793961f, +0.794364f, +0.794767f, +0.795168f, +0.795570f, +0.795971f, +0.796371f, +0.796771f, +0.797171f, +0.797570f, +0.797968f, +0.798366f, +0.798764f, +0.799161f, +0.799558f, +0.799954f, +0.800350f, +0.800745f, +0.801140f, +0.801534f, +0.801928f, +0.802321f, +0.802714f, +0.803107f, +0.803499f, +0.803890f, +0.804281f, +0.804672f, +0.805062f, +0.805451f, +0.805841f, +0.806229f, +0.806617f, +0.807005f, +0.807392f, +0.807779f, +0.808165f, +0.808551f, +0.808937f, +0.809321f, +0.809706f, +0.810090f, +0.810473f, +0.810856f, +0.811238f, +0.811620f, +0.812002f, +0.812383f, +0.812764f, +0.813144f, +0.813523f, +0.813902f, +0.814281f, +0.814659f, +0.815037f, +0.815414f, +0.815791f, +0.816167f, +0.816543f, +0.816918f, +0.817293f, +0.817667f, +0.818041f, +0.818414f, +0.818787f, +0.819160f, +0.819532f, +0.819903f, +0.820274f, +0.820645f, +0.821015f, +0.821384f, +0.821753f, +0.822122f, +0.822490f, +0.822858f, +0.823225f, +0.823591f, +0.823957f, +0.824323f, +0.824688f, +0.825053f, +0.825417f, +0.825781f, +0.826144f, +0.826507f, +0.826869f, +0.827231f, +0.827593f, +0.827953f, +0.828314f, +0.828674f, +0.829033f, +0.829392f, +0.829751f, +0.830109f, +0.830466f, +0.830823f, +0.831180f, +0.831536f, +0.831891f, +0.832246f, +0.832601f, +0.832955f, +0.833308f, +0.833662f, +0.834014f, +0.834366f, +0.834718f, +0.835069f, +0.835420f, +0.835770f, +0.836120f, +0.836469f, +0.836818f, +0.837166f, +0.837514f, +0.837862f, +0.838208f, +0.838555f, +0.838901f, +0.839246f, +0.839591f, +0.839935f, +0.840279f, +0.840623f, +0.840966f, +0.841308f, +0.841650f, +0.841992f, +0.842333f, +0.842673f, +0.843013f, +0.843353f, +0.843692f, +0.844031f, +0.844369f, +0.844707f, +0.845044f, +0.845380f, +0.845717f, +0.846052f, +0.846388f, +0.846722f, +0.847057f, +0.847390f, +0.847724f, +0.848056f, +0.848389f, +0.848721f, +0.849052f, +0.849383f, +0.849713f, +0.850043f, +0.850373f, +0.850702f, +0.851030f, +0.851358f, +0.851685f, +0.852013f, +0.852339f, +0.852665f, +0.852991f, +0.853316f, +0.853640f, +0.853964f, +0.854288f, +0.854611f, +0.854934f, +0.855256f, +0.855578f, +0.855899f, +0.856220f, +0.856540f, +0.856860f, +0.857179f, +0.857498f, +0.857816f, +0.858134f, +0.858451f, +0.858768f, +0.859085f, +0.859401f, +0.859716f, +0.860031f, +0.860346f, +0.860660f, +0.860973f, +0.861286f, +0.861599f, +0.861911f, +0.862222f, +0.862534f, +0.862844f, +0.863154f, +0.863464f, +0.863773f, +0.864082f, +0.864390f, +0.864698f, +0.865005f, +0.865312f, +0.865618f, +0.865924f, +0.866230f, +0.866534f, +0.866839f, +0.867143f, +0.867446f, +0.867749f, +0.868052f, +0.868354f, +0.868655f, +0.868956f, +0.869257f, +0.869557f, +0.869857f, +0.870156f, +0.870455f, +0.870753f, +0.871050f, +0.871348f, +0.871645f, +0.871941f, +0.872237f, +0.872532f, +0.872827f, +0.873121f, +0.873415f, +0.873709f, +0.874002f, +0.874294f, +0.874586f, +0.874878f, +0.875169f, +0.875459f, +0.875750f, +0.876039f, +0.876328f, +0.876617f, +0.876905f, +0.877193f, +0.877480f, +0.877767f, +0.878054f, +0.878340f, +0.878625f, +0.878910f, +0.879194f, +0.879478f, +0.879762f, +0.880045f, +0.880328f, +0.880610f, +0.880891f, +0.881172f, +0.881453f, +0.881733f, +0.882013f, +0.882293f, +0.882571f, +0.882850f, +0.883128f, +0.883405f, +0.883682f, +0.883959f, +0.884235f, +0.884510f, +0.884785f, +0.885060f, +0.885334f, +0.885608f, +0.885881f, +0.886154f, +0.886426f, +0.886698f, +0.886969f, +0.887240f, +0.887511f, +0.887781f, +0.888050f, +0.888319f, +0.888588f, +0.888856f, +0.889124f, +0.889391f, +0.889658f, +0.889924f, +0.890190f, +0.890455f, +0.890720f, +0.890984f, +0.891248f, +0.891512f, +0.891775f, +0.892038f, +0.892300f, +0.892561f, +0.892823f, +0.893083f, +0.893344f, +0.893604f, +0.893863f, +0.894122f, +0.894380f, +0.894638f, +0.894896f, +0.895153f, +0.895410f, +0.895666f, +0.895922f, +0.896177f, +0.896432f, +0.896686f, +0.896940f, +0.897194f, +0.897447f, +0.897699f, +0.897951f, +0.898203f, +0.898454f, +0.898705f, +0.898955f, +0.899205f, +0.899454f, +0.899703f, +0.899952f, +0.900200f, +0.900448f, +0.900695f, +0.900941f, +0.901188f, +0.901433f, +0.901679f, +0.901924f, +0.902168f, +0.902412f, +0.902656f, +0.902899f, +0.903142f, +0.903384f, +0.903626f, +0.903867f, +0.904108f, +0.904348f, +0.904588f, +0.904828f, +0.905067f, +0.905306f, +0.905544f, +0.905782f, +0.906019f, +0.906256f, +0.906493f, +0.906729f, +0.906964f, +0.907199f, +0.907434f, +0.907668f, +0.907902f, +0.908136f, +0.908368f, +0.908601f, +0.908833f, +0.909065f, +0.909296f, +0.909527f, +0.909757f, +0.909987f, +0.910216f, +0.910445f, +0.910674f, +0.910902f, +0.911130f, +0.911357f, +0.911584f, +0.911810f, +0.912036f, +0.912262f, +0.912487f, +0.912712f, +0.912936f, +0.913160f, +0.913383f, +0.913606f, +0.913829f, +0.914051f, +0.914273f, +0.914494f, +0.914715f, +0.914935f, +0.915155f, +0.915375f, +0.915594f, +0.915812f, +0.916031f, +0.916249f, +0.916466f, +0.916683f, +0.916900f, +0.917116f, +0.917331f, +0.917547f, +0.917762f, +0.917976f, +0.918190f, +0.918404f, +0.918617f, +0.918830f, +0.919042f, +0.919254f, +0.919466f, +0.919677f, +0.919887f, +0.920098f, +0.920307f, +0.920517f, +0.920726f, +0.920934f, +0.921143f, +0.921350f, +0.921558f, +0.921765f, +0.921971f, +0.922177f, +0.922383f, +0.922588f, +0.922793f, +0.922998f, +0.923202f, +0.923405f, +0.923608f, +0.923811f, +0.924014f, +0.924216f, +0.924417f, +0.924618f, +0.924819f, +0.925020f, +0.925219f, +0.925419f, +0.925618f, +0.925817f, +0.926015f, +0.926213f, +0.926411f, +0.926608f, +0.926804f, +0.927001f, +0.927197f, +0.927392f, +0.927587f, +0.927782f, +0.927976f, +0.928170f, +0.928364f, +0.928557f, +0.928749f, +0.928942f, +0.929133f, +0.929325f, +0.929516f, +0.929707f, +0.929897f, +0.930087f, +0.930276f, +0.930466f, +0.930654f, +0.930843f, +0.931031f, +0.931218f, +0.931405f, +0.931592f, +0.931778f, +0.931964f, +0.932150f, +0.932335f, +0.932520f, +0.932704f, +0.932888f, +0.933072f, +0.933255f, +0.933438f, +0.933620f, +0.933802f, +0.933984f, +0.934165f, +0.934346f, +0.934527f, +0.934707f, +0.934887f, +0.935066f, +0.935245f, +0.935424f, +0.935602f, +0.935780f, +0.935957f, +0.936134f, +0.936311f, +0.936487f, +0.936663f, +0.936839f, +0.937014f, +0.937189f, +0.937363f, +0.937537f, +0.937711f, +0.937884f, +0.938057f, +0.938229f, +0.938402f, +0.938573f, +0.938745f, +0.938916f, +0.939086f, +0.939257f, +0.939427f, +0.939596f, +0.939765f, +0.939934f, +0.940103f, +0.940271f, +0.940438f, +0.940606f, +0.940773f, +0.940939f, +0.941105f, +0.941271f, +0.941437f, +0.941602f, +0.941767f, +0.941931f, +0.942095f, +0.942259f, +0.942422f, +0.942585f, +0.942747f, +0.942910f, +0.943071f, +0.943233f, +0.943394f, +0.943555f, +0.943715f, +0.943875f, +0.944035f, +0.944194f, +0.944353f, +0.944512f, +0.944670f, +0.944828f, +0.944985f, +0.945143f, +0.945299f, +0.945456f, +0.945612f, +0.945768f, +0.945923f, +0.946078f, +0.946233f, +0.946387f, +0.946541f, +0.946695f, +0.946848f, +0.947001f, +0.947154f, +0.947306f, +0.947458f, +0.947609f, +0.947761f, +0.947911f, +0.948062f, +0.948212f, +0.948362f, +0.948511f, +0.948661f, +0.948809f, +0.948958f, +0.949106f, +0.949254f, +0.949401f, +0.949548f, +0.949695f, +0.949841f, +0.949987f, +0.950133f, +0.950278f, +0.950423f, +0.950568f, +0.950712f, +0.950857f, +0.951000f, +0.951144f, +0.951287f, +0.951429f, +0.951572f, +0.951714f, +0.951855f, +0.951997f, +0.952138f, +0.952278f, +0.952419f, +0.952559f, +0.952698f, +0.952838f, +0.952977f, +0.953116f, +0.953254f, +0.953392f, +0.953530f, +0.953667f, +0.953804f, +0.953941f, +0.954077f, +0.954213f, +0.954349f, +0.954485f, +0.954620f, +0.954755f, +0.954889f, +0.955023f, +0.955157f, +0.955290f, +0.955424f, +0.955557f, +0.955689f, +0.955821f, +0.955953f, +0.956085f, +0.956216f, +0.956347f, +0.956478f, +0.956608f, +0.956738f, +0.956868f, +0.956997f, +0.957126f, +0.957255f, +0.957383f, +0.957512f, +0.957639f, +0.957767f, +0.957894f, +0.958021f, +0.958148f, +0.958274f, +0.958400f, +0.958526f, +0.958651f, +0.958776f, +0.958901f, +0.959025f, +0.959149f, +0.959273f, +0.959397f, +0.959520f, +0.959643f, +0.959765f, +0.959888f, +0.960010f, +0.960131f, +0.960253f, +0.960374f, +0.960494f, +0.960615f, +0.960735f, +0.960855f, +0.960975f, +0.961094f, +0.961213f, +0.961332f, +0.961450f, +0.961568f, +0.961686f, +0.961804f, +0.961921f, +0.962038f, +0.962154f, +0.962271f, +0.962387f, +0.962503f, +0.962618f, +0.962733f, +0.962848f, +0.962963f, +0.963077f, +0.963191f, +0.963305f, +0.963418f, +0.963531f, +0.963644f, +0.963757f, +0.963869f, +0.963981f, +0.964093f, +0.964204f, +0.964316f, +0.964426f, +0.964537f, +0.964647f, +0.964757f, +0.964867f, +0.964977f, +0.965086f, +0.965195f, +0.965303f, +0.965412f, +0.965520f, +0.965628f, +0.965735f, +0.965842f, +0.965949f, +0.966056f, +0.966162f, +0.966269f, +0.966374f, +0.966480f, +0.966585f, +0.966690f, +0.966795f, +0.966900f, +0.967004f, +0.967108f, +0.967212f, +0.967315f, +0.967418f, +0.967521f, +0.967624f, +0.967726f, +0.967828f, +0.967930f, +0.968032f, +0.968133f, +0.968234f, +0.968335f, +0.968435f, +0.968535f, +0.968635f, +0.968735f, +0.968834f, +0.968934f, +0.969033f, +0.969131f, +0.969230f, +0.969328f, +0.969426f, +0.969523f, +0.969621f, +0.969718f, +0.969815f, +0.969911f, +0.970008f, +0.970104f, +0.970199f, +0.970295f, +0.970390f, +0.970485f, +0.970580f, +0.970675f, +0.970769f, +0.970863f, +0.970957f, +0.971050f, +0.971144f, +0.971237f, +0.971330f, +0.971422f, +0.971514f, +0.971606f, +0.971698f, +0.971790f, +0.971881f, +0.971972f, +0.972063f, +0.972154f, +0.972244f, +0.972334f, +0.972424f, +0.972513f, +0.972603f, +0.972692f, +0.972781f, +0.972869f, +0.972958f, +0.973046f, +0.973134f, +0.973221f, +0.973309f, +0.973396f, +0.973483f, +0.973570f, +0.973656f, +0.973742f, +0.973828f, +0.973914f, +0.974000f, +0.974085f, +0.974170f, +0.974255f, +0.974340f, +0.974424f, +0.974508f, +0.974592f, +0.974676f, +0.974759f, +0.974842f, +0.974925f, +0.975008f, +0.975090f, +0.975173f, +0.975255f, +0.975337f, +0.975418f, +0.975500f, +0.975581f, +0.975662f, +0.975742f, +0.975823f, +0.975903f, +0.975983f, +0.976063f, +0.976143f, +0.976222f, +0.976301f, +0.976380f, +0.976459f, +0.976537f, +0.976615f, +0.976693f, +0.976771f, +0.976849f, +0.976926f, +0.977003f, +0.977080f, +0.977157f, +0.977234f, +0.977310f, +0.977386f, +0.977462f, +0.977537f, +0.977613f, +0.977688f, +0.977763f, +0.977838f, +0.977912f, +0.977987f, +0.978061f, +0.978135f, +0.978209f, +0.978282f, +0.978356f, +0.978429f, +0.978502f, +0.978574f, +0.978647f, +0.978719f, +0.978791f, +0.978863f, +0.978935f, +0.979006f, +0.979077f, +0.979148f, +0.979219f, +0.979290f, +0.979360f, +0.979430f, +0.979500f, +0.979570f, +0.979640f, +0.979709f, +0.979778f, +0.979848f, +0.979916f, +0.979985f, +0.980053f, +0.980122f, +0.980190f, +0.980257f, +0.980325f, +0.980392f, +0.980460f, +0.980527f, +0.980594f, +0.980660f, +0.980727f, +0.980793f, +0.980859f, +0.980925f, +0.980991f, +0.981056f, +0.981121f, +0.981186f, +0.981251f, +0.981316f, +0.981381f, +0.981445f, +0.981509f, +0.981573f, +0.981637f, +0.981700f, +0.981764f, +0.981827f, +0.981890f, +0.981953f, +0.982016f, +0.982078f, +0.982140f, +0.982202f, +0.982264f, +0.982326f, +0.982388f, +0.982449f, +0.982510f, +0.982571f, +0.982632f, +0.982693f, +0.982753f, +0.982813f, +0.982873f, +0.982933f, +0.982993f, +0.983053f, +0.983112f, +0.983171f, +0.983230f, +0.983289f, +0.983348f, +0.983406f, +0.983464f, +0.983523f, +0.983581f, +0.983638f, +0.983696f, +0.983753f, +0.983811f, +0.983868f, +0.983925f, +0.983981f, +0.984038f, +0.984094f, +0.984151f, +0.984207f, +0.984263f, +0.984318f, +0.984374f, +0.984429f, +0.984485f, +0.984540f, +0.984594f, +0.984649f, +0.984704f, +0.984758f, +0.984812f, +0.984866f, +0.984920f, +0.984974f, +0.985028f, +0.985081f, +0.985134f, +0.985187f, +0.985240f, +0.985293f, +0.985345f, +0.985398f, +0.985450f, +0.985502f, +0.985554f, +0.985606f, +0.985657f, +0.985709f, +0.985760f, +0.985811f, +0.985862f, +0.985913f, +0.985964f, +0.986014f, +0.986065f, +0.986115f, +0.986165f, +0.986215f, +0.986264f, +0.986314f, +0.986363f, +0.986413f, +0.986462f, +0.986511f, +0.986560f, +0.986608f, +0.986657f, +0.986705f, +0.986753f, +0.986801f, +0.986849f, +0.986897f, +0.986945f, +0.986992f, +0.987039f, +0.987086f, +0.987133f, +0.987180f, +0.987227f, +0.987274f, +0.987320f, +0.987366f, +0.987412f, +0.987458f, +0.987504f, +0.987550f, +0.987595f, +0.987641f, +0.987686f, +0.987731f, +0.987776f, +0.987821f, +0.987865f, +0.987910f, +0.987954f, +0.987999f, +0.988043f, +0.988087f, +0.988131f, +0.988174f, +0.988218f, +0.988261f, +0.988304f, +0.988348f, +0.988391f, +0.988433f, +0.988476f, +0.988519f, +0.988561f, +0.988603f, +0.988646f, +0.988688f, +0.988730f, +0.988771f, +0.988813f, +0.988854f, +0.988896f, +0.988937f, +0.988978f, +0.989019f, +0.989060f, +0.989101f, +0.989141f, +0.989182f, +0.989222f, +0.989262f, +0.989302f, +0.989342f, +0.989382f, +0.989421f, +0.989461f, +0.989500f, +0.989540f, +0.989579f, +0.989618f, +0.989657f, +0.989695f, +0.989734f, +0.989773f, +0.989811f, +0.989849f, +0.989887f, +0.989925f, +0.989963f, +0.990001f, +0.990039f, +0.990076f, +0.990113f, +0.990151f, +0.990188f, +0.990225f, +0.990262f, +0.990298f, +0.990335f, +0.990372f, +0.990408f, +0.990444f, +0.990480f, +0.990517f, +0.990552f, +0.990588f, +0.990624f, +0.990660f, +0.990695f, +0.990730f, +0.990766f, +0.990801f, +0.990836f, +0.990870f, +0.990905f, +0.990940f, +0.990974f, +0.991009f, +0.991043f, +0.991077f, +0.991111f, +0.991145f, +0.991179f, +0.991213f, +0.991246f, +0.991280f, +0.991313f, +0.991347f, +0.991380f, +0.991413f, +0.991446f, +0.991479f, +0.991511f, +0.991544f, +0.991576f, +0.991609f, +0.991641f, +0.991673f, +0.991705f, +0.991737f, +0.991769f, +0.991801f, +0.991832f, +0.991864f, +0.991895f, +0.991927f, +0.991958f, +0.991989f, +0.992020f, +0.992051f, +0.992081f, +0.992112f, +0.992143f, +0.992173f, +0.992204f, +0.992234f, +0.992264f, +0.992294f, +0.992324f, +0.992354f, +0.992383f, +0.992413f, +0.992443f, +0.992472f, +0.992501f, +0.992531f, +0.992560f, +0.992589f, +0.992618f, +0.992647f, +0.992675f, +0.992704f, +0.992732f, +0.992761f, +0.992789f, +0.992817f, +0.992846f, +0.992874f, +0.992902f, +0.992929f, +0.992957f, +0.992985f, +0.993012f, +0.993040f, +0.993067f, +0.993095f, +0.993122f, +0.993149f, +0.993176f, +0.993203f, +0.993230f, +0.993256f, +0.993283f, +0.993309f, +0.993336f, +0.993362f, +0.993388f, +0.993415f, +0.993441f, +0.993467f, +0.993493f, +0.993518f, +0.993544f, +0.993570f, +0.993595f, +0.993621f, +0.993646f, +0.993671f, +0.993696f, +0.993721f, +0.993746f, +0.993771f, +0.993796f, +0.993821f, +0.993845f, +0.993870f, +0.993894f, +0.993919f, +0.993943f, +0.993967f, +0.993991f, +0.994016f, +0.994039f, +0.994063f, +0.994087f, +0.994111f, +0.994134f, +0.994158f, +0.994181f, +0.994205f, +0.994228f, +0.994251f, +0.994274f, +0.994297f, +0.994320f, +0.994343f, +0.994366f, +0.994389f, +0.994411f, +0.994434f, +0.994456f, +0.994479f, +0.994501f, +0.994523f, +0.994545f, +0.994567f, +0.994589f, +0.994611f, +0.994633f, +0.994655f, +0.994676f, +0.994698f, +0.994720f, +0.994741f, +0.994762f, +0.994784f, +0.994805f, +0.994826f, +0.994847f, +0.994868f, +0.994889f, +0.994910f, +0.994930f, +0.994951f, +0.994972f, +0.994992f, +0.995013f, +0.995033f, +0.995053f, +0.995073f, +0.995094f, +0.995114f, +0.995134f, +0.995154f, +0.995173f, +0.995193f, +0.995213f, +0.995233f, +0.995252f, +0.995272f, +0.995291f, +0.995310f, +0.995330f, +0.995349f, +0.995368f, +0.995387f, +0.995406f, +0.995425f, +0.995444f, +0.995463f, +0.995481f, +0.995500f, +0.995519f, +0.995537f, +0.995556f, +0.995574f, +0.995592f, +0.995610f, +0.995629f, +0.995647f, +0.995665f, +0.995683f, +0.995701f, +0.995718f, +0.995736f, +0.995754f, +0.995772f, +0.995789f, +0.995807f, +0.995824f, +0.995842f, +0.995859f, +0.995876f, +0.995893f, +0.995910f, +0.995927f, +0.995944f, +0.995961f, +0.995978f, +0.995995f, +0.996012f, +0.996028f, +0.996045f, +0.996062f, +0.996078f, +0.996095f, +0.996111f, +0.996127f, +0.996143f, +0.996160f, +0.996176f, +0.996192f, +0.996208f, +0.996224f, +0.996240f, +0.996255f, +0.996271f, +0.996287f, +0.996303f, +0.996318f, +0.996334f, +0.996349f, +0.996365f, +0.996380f, +0.996395f, +0.996410f, +0.996426f, +0.996441f, +0.996456f, +0.996471f, +0.996486f, +0.996501f, +0.996515f, +0.996530f, +0.996545f, +0.996560f, +0.996574f, +0.996589f, +0.996603f, +0.996618f, +0.996632f, +0.996646f, +0.996661f, +0.996675f, +0.996689f, +0.996703f, +0.996717f, +0.996731f, +0.996745f, +0.996759f, +0.996773f, +0.996787f, +0.996801f, +0.996814f, +0.996828f, +0.996841f, +0.996855f, +0.996868f, +0.996882f, +0.996895f, +0.996909f, +0.996922f, +0.996935f, +0.996948f, +0.996961f, +0.996974f, +0.996987f, +0.997000f, +0.997013f, +0.997026f, +0.997039f, +0.997052f, +0.997064f, +0.997077f, +0.997090f, +0.997102f, +0.997115f, +0.997127f, +0.997140f, +0.997152f, +0.997164f, +0.997177f, +0.997189f, +0.997201f, +0.997213f, +0.997225f, +0.997237f, +0.997249f, +0.997261f, +0.997273f, +0.997285f, +0.997297f, +0.997308f, +0.997320f, +0.997332f, +0.997343f, +0.997355f, +0.997367f, +0.997378f, +0.997389f, +0.997401f, +0.997412f, +0.997424f, +0.997435f, +0.997446f, +0.997457f, +0.997468f, +0.997479f, +0.997490f, +0.997501f, +0.997512f, +0.997523f, +0.997534f, +0.997545f, +0.997556f, +0.997566f, +0.997577f, +0.997588f, +0.997598f, +0.997609f, +0.997619f, +0.997630f, +0.997640f, +0.997651f, +0.997661f, +0.997671f, +0.997682f, +0.997692f, +0.997702f, +0.997712f, +0.997722f, +0.997732f, +0.997743f, +0.997752f, +0.997762f, +0.997772f, +0.997782f, +0.997792f, +0.997802f, +0.997812f, +0.997821f, +0.997831f, +0.997841f, +0.997850f, +0.997860f, +0.997869f, +0.997879f, +0.997888f, +0.997898f, +0.997907f, +0.997916f, +0.997926f, +0.997935f, +0.997944f, +0.997953f, +0.997962f, +0.997971f, +0.997980f, +0.997990f, +0.997999f, +0.998007f, +0.998016f, +0.998025f, +0.998034f, +0.998043f, +0.998052f, +0.998060f, +0.998069f, +0.998078f, +0.998086f, +0.998095f, +0.998104f, +0.998112f, +0.998121f, +0.998129f, +0.998137f, +0.998146f, +0.998154f, +0.998163f, +0.998171f, +0.998179f, +0.998187f, +0.998195f, +0.998204f, +0.998212f, +0.998220f, +0.998228f, +0.998236f, +0.998244f, +0.998252f, +0.998260f, +0.998268f, +0.998275f, +0.998283f, +0.998291f, +0.998299f, +0.998307f, +0.998314f, +0.998322f, +0.998330f, +0.998337f, +0.998345f, +0.998352f, +0.998360f, +0.998367f, +0.998375f, +0.998382f, +0.998389f, +0.998397f, +0.998404f, +0.998411f, +0.998419f, +0.998426f, +0.998433f, +0.998440f, +0.998447f, +0.998454f, +0.998462f, +0.998469f, +0.998476f, +0.998483f, +0.998490f, +0.998497f, +0.998503f, +0.998510f, +0.998517f, +0.998524f, +0.998531f, +0.998537f, +0.998544f, +0.998551f, +0.998558f, +0.998564f, +0.998571f, +0.998577f, +0.998584f, +0.998591f, +0.998597f, +0.998603f, +0.998610f, +0.998616f, +0.998623f, +0.998629f, +0.998636f, +0.998642f, +0.998648f, +0.998654f, +0.998661f, +0.998667f, +0.998673f, +0.998679f, +0.998685f, +0.998691f, +0.998697f, +0.998704f, +0.998710f, +0.998716f, +0.998722f, +0.998727f, +0.998733f, +0.998739f, +0.998745f, +0.998751f, +0.998757f, +0.998763f, +0.998768f, +0.998774f, +0.998780f, +0.998786f, +0.998791f, +0.998797f, +0.998803f, +0.998808f, +0.998814f, +0.998819f, +0.998825f, +0.998830f, +0.998836f, +0.998841f, +0.998847f, +0.998852f, +0.998858f, +0.998863f, +0.998868f, +0.998874f, +0.998879f, +0.998884f, +0.998889f, +0.998895f, +0.998900f, +0.998905f, +0.998910f, +0.998915f, +0.998920f, +0.998926f, +0.998931f, +0.998936f, +0.998941f, +0.998946f, +0.998951f, +0.998956f, +0.998961f, +0.998966f, +0.998970f, +0.998975f, +0.998980f, +0.998985f, +0.998990f, +0.998995f, +0.998999f, +0.999004f, +0.999009f, +0.999014f, +0.999018f, +0.999023f, +0.999028f, +0.999032f, +0.999037f, +0.999041f, +0.999046f, +0.999051f, +0.999055f, +0.999060f, +0.999064f, +0.999069f, +0.999073f, +0.999077f, +0.999082f, +0.999086f, +0.999091f, +0.999095f, +0.999099f, +0.999104f, +0.999108f, +0.999112f, +0.999116f, +0.999121f, +0.999125f, +0.999129f, +0.999133f, +0.999137f, +0.999142f, +0.999146f, +0.999150f, +0.999154f, +0.999158f, +0.999162f, +0.999166f, +0.999170f, +0.999174f, +0.999178f, +0.999182f, +0.999186f, +0.999190f, +0.999194f, +0.999198f, +0.999202f, +0.999206f, +0.999209f, +0.999213f, +0.999217f, +0.999221f, +0.999225f, +0.999228f, +0.999232f, +0.999236f, +0.999240f, +0.999243f, +0.999247f, +0.999251f, +0.999254f, +0.999258f, +0.999261f, +0.999265f, +0.999269f, +0.999272f, +0.999276f, +0.999279f, +0.999283f, +0.999286f, +0.999290f, +0.999293f, +0.999297f, +0.999300f, +0.999304f, +0.999307f, +0.999310f, +0.999314f, +0.999317f, +0.999320f, +0.999324f, +0.999327f, +0.999330f, +0.999334f, +0.999337f, +0.999340f, +0.999343f, +0.999347f, +0.999350f, +0.999353f, +0.999356f, +0.999359f, +0.999363f, +0.999366f, +0.999369f, +0.999372f, +0.999375f, +0.999378f, +0.999381f, +0.999384f, +0.999387f, +0.999390f, +0.999393f, +0.999396f, +0.999399f, +0.999402f, +0.999405f, +0.999408f, +0.999411f, +0.999414f, +0.999417f, +0.999420f, +0.999423f, +0.999426f, +0.999428f, +0.999431f, +0.999434f, +0.999437f, +0.999440f, +0.999442f, +0.999445f, +0.999448f, +0.999451f, +0.999453f, +0.999456f, +0.999459f, +0.999462f, +0.999464f, +0.999467f, +0.999470f, +0.999472f, +0.999475f, +0.999478f, +0.999480f, +0.999483f, +0.999485f, +0.999488f, +0.999490f, +0.999493f, +0.999496f, +0.999498f, +0.999501f, +0.999503f, +0.999506f, +0.999508f, +0.999511f, +0.999513f, +0.999515f, +0.999518f, +0.999520f, +0.999523f, +0.999525f, +0.999528f, +0.999530f, +0.999532f, +0.999535f, +0.999537f, +0.999539f, +0.999542f, +0.999544f, +0.999546f, +0.999549f, +0.999551f, +0.999553f, +0.999555f, +0.999558f, +0.999560f, +0.999562f, +0.999564f, +0.999566f, +0.999569f, +0.999571f, +0.999573f, +0.999575f, +0.999577f, +0.999580f, +0.999582f, +0.999584f, +0.999586f, +0.999588f, +0.999590f, +0.999592f, +0.999594f, +0.999596f, +0.999598f, +0.999600f, +0.999602f, +0.999604f, +0.999607f, +0.999609f, +0.999611f, +0.999613f, +0.999615f, +0.999616f, +0.999618f, +0.999620f, +0.999622f, +0.999624f, +0.999626f, +0.999628f, +0.999630f, +0.999632f, +0.999634f, +0.999636f, +0.999638f, +0.999639f, +0.999641f, +0.999643f, +0.999645f, +0.999647f, +0.999649f, +0.999650f, +0.999652f, +0.999654f, +0.999656f, +0.999658f, +0.999659f, +0.999661f, +0.999663f, +0.999665f, +0.999666f, +0.999668f, +0.999670f, +0.999671f, +0.999673f, +0.999675f, +0.999676f, +0.999678f, +0.999680f, +0.999681f, +0.999683f, +0.999685f, +0.999686f, +0.999688f, +0.999690f, +0.999691f, +0.999693f, +0.999694f, +0.999696f, +0.999698f, +0.999699f, +0.999701f, +0.999702f, +0.999704f, +0.999705f, +0.999707f, +0.999708f, +0.999710f, +0.999711f, +0.999713f, +0.999714f, +0.999716f, +0.999717f, +0.999719f, +0.999720f, +0.999722f, +0.999723f, +0.999725f, +0.999726f, +0.999728f, +0.999729f, +0.999730f, +0.999732f, +0.999733f, +0.999735f, +0.999736f, +0.999738f, +0.999739f, +0.999740f, +0.999742f, +0.999743f, +0.999744f, +0.999746f, +0.999747f, +0.999748f, +0.999750f, +0.999751f, +0.999752f, +0.999754f, +0.999755f, +0.999756f, +0.999757f, +0.999759f, +0.999760f, +0.999761f, +0.999763f, +0.999764f, +0.999765f, +0.999766f, +0.999768f, +0.999769f, +0.999770f, +0.999771f, +0.999772f, +0.999774f, +0.999775f, +0.999776f, +0.999777f, +0.999778f, +0.999780f, +0.999781f, +0.999782f, +0.999783f, +0.999784f, +0.999785f, +0.999786f, +0.999788f, +0.999789f, +0.999790f, +0.999791f, +0.999792f, +0.999793f, +0.999794f, +0.999795f, +0.999797f, +0.999798f, +0.999799f, +0.999800f, +0.999801f, +0.999802f, +0.999803f, +0.999804f, +0.999805f, +0.999806f, +0.999807f, +0.999808f, +0.999809f, +0.999810f, +0.999811f, +0.999812f, +0.999813f, +0.999814f, +0.999815f, +0.999816f, +0.999817f, +0.999818f, +0.999819f, +0.999820f, +0.999821f, +0.999822f, +0.999823f, +0.999824f, +0.999825f, +0.999826f, +0.999827f, +0.999828f, +0.999829f, +0.999830f, +0.999831f, +0.999831f, +0.999832f, +0.999833f, +0.999834f, +0.999835f, +0.999836f, +0.999837f, +0.999838f, +0.999839f, +0.999840f, +0.999840f, +0.999841f, +0.999842f, +0.999843f, +0.999844f, +0.999845f, +0.999846f, +0.999846f, +0.999847f, +0.999848f, +0.999849f, +0.999850f, +0.999850f, +0.999851f, +0.999852f, +0.999853f, +0.999854f, +0.999855f, +0.999855f, +0.999856f, +0.999857f, +0.999858f, +0.999858f, +0.999859f, +0.999860f, +0.999861f, +0.999862f, +0.999862f, +0.999863f, +0.999864f, +0.999865f, +0.999865f, +0.999866f, +0.999867f, +0.999867f, +0.999868f, +0.999869f, +0.999870f, +0.999870f, +0.999871f, +0.999872f, +0.999872f, +0.999873f, +0.999874f, +0.999875f, +0.999875f, +0.999876f, +0.999877f, +0.999877f, +0.999878f, +0.999879f, +0.999879f, +0.999880f, +0.999881f, +0.999881f, +0.999882f, +0.999883f, +0.999883f, +0.999884f, +0.999885f, +0.999885f, +0.999886f, +0.999886f, +0.999887f, +0.999888f, +0.999888f, +0.999889f, +0.999890f, +0.999890f, +0.999891f, +0.999891f, +0.999892f, +0.999893f, +0.999893f, +0.999894f, +0.999894f, +0.999895f, +0.999896f, +0.999896f, +0.999897f, +0.999897f, +0.999898f, +0.999898f, +0.999899f, +0.999900f, +0.999900f, +0.999901f, +0.999901f, +0.999902f, +0.999902f, +0.999903f, +0.999903f, +0.999904f, +0.999905f, +0.999905f, +0.999906f, +0.999906f, +0.999907f, +0.999907f, +0.999908f, +0.999908f, +0.999909f, +0.999909f, +0.999910f, +0.999910f, +0.999911f, +0.999911f, +0.999912f, +0.999912f, +0.999913f, +0.999913f, +0.999914f, +0.999914f, +0.999915f, +0.999915f, +0.999916f, +0.999916f, +0.999917f, +0.999917f, +0.999918f, +0.999918f, +0.999918f, +0.999919f, +0.999919f, +0.999920f, +0.999920f, +0.999921f, +0.999921f, +0.999922f, +0.999922f, +0.999923f, +0.999923f, +0.999923f, +0.999924f, +0.999924f, +0.999925f, +0.999925f, +0.999926f, +0.999926f, +0.999926f, +0.999927f, +0.999927f, +0.999928f, +0.999928f, +0.999928f, +0.999929f, +0.999929f, +0.999930f, +0.999930f, +0.999930f, +0.999931f, +0.999931f, +0.999932f, +0.999932f, +0.999932f, +0.999933f, +0.999933f, +0.999934f, +0.999934f, +0.999934f, +0.999935f, +0.999935f, +0.999935f, +0.999936f, +0.999936f, +0.999937f, +0.999937f, +0.999937f, +0.999938f, +0.999938f, +0.999938f, +0.999939f, +0.999939f, +0.999939f, +0.999940f, +0.999940f, +0.999940f, +0.999941f, +0.999941f, +0.999941f, +0.999942f, +0.999942f, +0.999943f, +0.999943f, +0.999943f, +0.999943f, +0.999944f, +0.999944f, +0.999944f, +0.999945f, +0.999945f, +0.999945f, +0.999946f, +0.999946f, +0.999946f, +0.999947f, +0.999947f, +0.999947f, +0.999948f, +0.999948f, +0.999948f, +0.999949f, +0.999949f, +0.999949f, +0.999949f, +0.999950f, +0.999950f, +0.999950f, +0.999951f, +0.999951f, +0.999951f, +0.999951f, +0.999952f, +0.999952f, +0.999952f, +0.999953f, +0.999953f, +0.999953f, +0.999953f, +0.999954f, +0.999954f, +0.999954f, +0.999954f, +0.999955f, +0.999955f, +0.999955f, +0.999956f, +0.999956f, +0.999956f, +0.999956f, +0.999957f, +0.999957f, +0.999957f, +0.999957f, +0.999958f, +0.999958f, +0.999958f, +0.999958f, +0.999959f, +0.999959f, +0.999959f, +0.999959f, +0.999959f, +0.999960f, +0.999960f, +0.999960f, +0.999960f, +0.999961f, +0.999961f, +0.999961f, +0.999961f, +0.999962f, +0.999962f, +0.999962f, +0.999962f, +0.999962f, +0.999963f, +0.999963f, +0.999963f, +0.999963f, +0.999964f, +0.999964f, +0.999964f, +0.999964f, +0.999964f, +0.999965f, +0.999965f, +0.999965f, +0.999965f, +0.999965f, +0.999966f, +0.999966f, +0.999966f, +0.999966f, +0.999967f, +0.999967f, +0.999967f, +0.999967f, +0.999967f, +0.999967f, +0.999968f, +0.999968f, +0.999968f, +0.999968f, +0.999968f, +0.999969f, +0.999969f, +0.999969f, +0.999969f, +0.999969f, +0.999970f, +0.999970f, +0.999970f, +0.999970f, +0.999970f, +0.999970f, +0.999971f, +0.999971f, +0.999971f, +0.999971f, +0.999971f, +0.999972f, +0.999972f, +0.999972f, +0.999972f, +0.999972f, +0.999972f, +0.999972f, +0.999973f, +0.999973f, +0.999973f, +0.999973f, +0.999973f, +0.999973f, +0.999974f, +0.999974f, +0.999974f, +0.999974f, +0.999974f, +0.999974f, +0.999975f, +0.999975f, +0.999975f, +0.999975f, +0.999975f, +0.999975f, +0.999975f, +0.999976f, +0.999976f, +0.999976f, +0.999976f, +0.999976f, +0.999976f, +0.999977f, +0.999977f, +0.999977f, +0.999977f, +0.999977f, +0.999977f, +0.999977f, +0.999977f, +0.999978f, +0.999978f, +0.999978f, +0.999978f, +0.999978f, +0.999978f, +0.999978f, +0.999979f, +0.999979f, +0.999979f, +0.999979f, +0.999979f, +0.999979f, +0.999979f, +0.999979f, +0.999980f, +0.999980f, +0.999980f, +0.999980f, +0.999980f, +0.999980f, +0.999980f, +0.999980f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999981f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999982f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999983f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999984f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999985f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999986f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999987f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999988f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999989f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999990f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999991f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999992f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999993f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999994f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999995f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999996f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999997f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999998f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +0.999999f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f, +1.000000f diff --git a/rce/rcecalib/dataproc/fit/errf_ext_fastint.dat b/rce/rcecalib/dataproc/fit/errf_ext_fastint.dat new file mode 100644 index 0000000000000000000000000000000000000000..8d27297caa7380038ef173e26a8393cbd31b422a --- /dev/null +++ b/rce/rcecalib/dataproc/fit/errf_ext_fastint.dat @@ -0,0 +1,8191 @@ +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +15, +15, +15, +15, +15, +15, +15, +15, +15, +15, +15, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +17, +17, +17, +17, +17, +17, +17, +17, +17, +18, +18, +18, +18, +18, +18, +18, +18, +18, +19, +19, +19, +19, +19, +19, +19, +19, +19, +20, +20, +20, +20, +20, +20, +20, +20, +21, +21, +21, +21, +21, +21, +21, +21, +22, +22, +22, +22, +22, +22, +22, +23, +23, +23, +23, +23, +23, +23, +23, +24, +24, +24, +24, +24, +24, +25, +25, +25, +25, +25, +25, +25, +26, +26, +26, +26, +26, +26, +27, +27, +27, +27, +27, +27, +27, +28, +28, +28, +28, +28, +29, +29, +29, +29, +29, +29, +30, +30, +30, +30, +30, +30, +31, +31, +31, +31, +31, +32, +32, +32, +32, +32, +33, +33, +33, +33, +33, +34, +34, +34, +34, +34, +35, +35, +35, +35, +35, +36, +36, +36, +36, +36, +37, +37, +37, +37, +38, +38, +38, +38, +38, +39, +39, +39, +39, +40, +40, +40, +40, +41, +41, +41, +41, +41, +43, +43, +43, +43, +44, +44, +44, +44, +45, +45, +45, +45, +46, +46, +46, +47, +47, +47, +47, +48, +48, +48, +48, +49, +49, +49, +50, +50, +50, +50, +51, +51, +51, +52, +52, +52, +52, +53, +53, +53, +54, +54, +54, +55, +55, +55, +56, +56, +56, +57, +57, +57, +58, +58, +58, +58, +59, +59, +60, +60, +60, +61, +61, +61, +62, +62, +62, +63, +63, +63, +64, +64, +64, +65, +65, +66, +66, +66, +67, +67, +67, +68, +68, +69, +69, +69, +70, +70, +71, +71, +71, +72, +72, +73, +73, +73, +74, +74, +75, +75, +75, +76, +76, +77, +77, +78, +78, +78, +79, +79, +80, +80, +81, +81, +82, +82, +83, +83, +83, +84, +84, +86, +86, +87, +87, +88, +88, +89, +89, +90, +90, +91, +91, +92, +92, +93, +93, +94, +94, +95, +95, +96, +96, +97, +97, +98, +99, +99, +100, +100, +101, +101, +102, +102, +103, +104, +104, +105, +105, +106, +106, +107, +108, +108, +109, +109, +110, +111, +111, +112, +112, +113, +114, +114, +115, +116, +116, +117, +117, +118, +119, +119, +120, +121, +121, +122, +123, +123, +124, +125, +125, +126, +128, +128, +129, +130, +131, +131, +132, +133, +133, +134, +135, +136, +136, +137, +138, +138, +139, +140, +141, +141, +142, +143, +144, +145, +145, +146, +147, +148, +148, +149, +150, +151, +152, +153, +153, +154, +155, +156, +157, +157, +158, +159, +160, +161, +162, +163, +163, +164, +165, +166, +167, +168, +169, +171, +172, +173, +173, +174, +175, +176, +177, +178, +179, +180, +181, +182, +183, +184, +185, +186, +187, +188, +189, +190, +191, +192, +193, +194, +195, +196, +197, +198, +199, +200, +201, +202, +203, +204, +205, +206, +207, +209, +210, +211, +212, +214, +215, +216, +217, +219, +220, +221, +222, +223, +224, +225, +227, +228, +229, +230, +231, +233, +234, +235, +236, +237, +239, +240, +241, +242, +244, +245, +246, +248, +249, +250, +251, +253, +254, +256, +258, +259, +260, +262, +263, +264, +266, +267, +269, +270, +271, +273, +274, +276, +277, +278, +280, +281, +283, +284, +286, +287, +289, +290, +292, +293, +295, +296, +299, +300, +302, +303, +305, +306, +308, +309, +311, +313, +314, +316, +317, +319, +321, +322, +324, +326, +327, +329, +331, +332, +334, +336, +337, +339, +342, +343, +345, +347, +349, +350, +352, +354, +356, +358, +359, +361, +363, +365, +367, +369, +370, +372, +374, +376, +378, +380, +382, +385, +387, +389, +391, +393, +395, +396, +398, +400, +402, +404, +407, +409, +411, +413, +415, +417, +419, +421, +423, +425, +428, +430, +433, +435, +437, +439, +441, +443, +446, +448, +450, +452, +455, +457, +459, +461, +464, +466, +468, +472, +474, +476, +479, +481, +483, +486, +488, +491, +493, +496, +498, +500, +503, +505, +508, +510, +514, +516, +519, +522, +524, +527, +529, +532, +534, +537, +540, +542, +545, +548, +550, +553, +557, +560, +562, +565, +568, +571, +573, +576, +579, +582, +585, +587, +590, +593, +596, +600, +603, +606, +609, +612, +615, +618, +621, +624, +627, +630, +633, +636, +639, +643, +646, +649, +652, +656, +659, +662, +665, +668, +672, +675, +678, +681, +686, +689, +692, +696, +699, +702, +706, +709, +712, +716, +719, +723, +727, +731, +734, +738, +741, +745, +748, +752, +756, +759, +763, +766, +771, +775, +778, +782, +786, +790, +793, +797, +801, +805, +809, +813, +817, +821, +825, +829, +833, +837, +841, +845, +849, +854, +858, +862, +866, +870, +874, +878, +883, +887, +891, +896, +900, +905, +909, +913, +917, +922, +926, +930, +935, +940, +945, +949, +953, +958, +962, +967, +971, +976, +982, +986, +991, +995, +1000, +1005, +1009, +1014, +1019, +1025, +1029, +1034, +1039, +1044, +1049, +1054, +1058, +1063, +1069, +1074, +1079, +1084, +1089, +1094, +1099, +1105, +1111, +1116, +1121, +1126, +1131, +1137, +1142, +1147, +1153, +1159, +1164, +1169, +1175, +1180, +1186, +1191, +1198, +1203, +1209, +1214, +1220, +1225, +1231, +1238, +1243, +1249, +1255, +1261, +1266, +1272, +1278, +1285, +1291, +1297, +1303, +1308, +1314, +1320, +1327, +1334, +1340, +1346, +1352, +1358, +1364, +1371, +1378, +1384, +1390, +1397, +1403, +1410, +1417, +1423, +1429, +1436, +1442, +1449, +1457, +1463, +1470, +1476, +1483, +1490, +1498, +1504, +1511, +1518, +1525, +1532, +1540, +1546, +1553, +1560, +1567, +1574, +1583, +1590, +1597, +1604, +1611, +1618, +1627, +1634, +1641, +1649, +1656, +1664, +1672, +1679, +1687, +1694, +1702, +1710, +1718, +1726, +1733, +1741, +1750, +1758, +1766, +1773, +1781, +1789, +1798, +1806, +1814, +1822, +1830, +1839, +1848, +1856, +1864, +1872, +1881, +1890, +1898, +1907, +1915, +1924, +1933, +1941, +1950, +1959, +1968, +1977, +1986, +1994, +2003, +2013, +2022, +2031, +2040, +2050, +2058, +2068, +2077, +2086, +2096, +2105, +2114, +2123, +2134, +2143, +2152, +2162, +2171, +2182, +2191, +2201, +2210, +2221, +2231, +2240, +2250, +2260, +2271, +2281, +2291, +2301, +2312, +2322, +2332, +2342, +2353, +2363, +2373, +2384, +2395, +2405, +2416, +2426, +2438, +2448, +2459, +2469, +2481, +2492, +2502, +2513, +2525, +2536, +2547, +2558, +2570, +2581, +2592, +2604, +2615, +2626, +2637, +2650, +2661, +2673, +2684, +2696, +2708, +2720, +2732, +2744, +2756, +2767, +2780, +2792, +2804, +2817, +2829, +2841, +2853, +2866, +2878, +2890, +2904, +2916, +2928, +2941, +2954, +2967, +2979, +2993, +3006, +3018, +3032, +3045, +3058, +3072, +3085, +3098, +3111, +3125, +3138, +3151, +3165, +3179, +3192, +3207, +3220, +3234, +3248, +3262, +3275, +3290, +3304, +3318, +3333, +3347, +3361, +3376, +3390, +3404, +3419, +3434, +3448, +3463, +3478, +3492, +3508, +3522, +3537, +3553, +3568, +3582, +3598, +3613, +3629, +3644, +3659, +3676, +3691, +3706, +3722, +3738, +3753, +3770, +3785, +3802, +3818, +3834, +3850, +3866, +3883, +3899, +3915, +3932, +3949, +3965, +3982, +3998, +4016, +4032, +4049, +4067, +4083, +4101, +4118, +4135, +4153, +4170, +4188, +4205, +4222, +4240, +4257, +4276, +4293, +4312, +4329, +4347, +4366, +4384, +4402, +4420, +4439, +4457, +4475, +4495, +4513, +4532, +4550, +4570, +4588, +4607, +4627, +4645, +4665, +4684, +4704, +4723, +4743, +4762, +4782, +4802, +4822, +4841, +4861, +4881, +4901, +4922, +4942, +4962, +4982, +5003, +5023, +5045, +5065, +5086, +5106, +5128, +5148, +5170, +5191, +5212, +5233, +5255, +5276, +5298, +5319, +5341, +5363, +5385, +5407, +5429, +5451, +5473, +5495, +5518, +5540, +5563, +5585, +5608, +5630, +5653, +5677, +5699, +5723, +5745, +5769, +5792, +5816, +5839, +5863, +5886, +5910, +5934, +5958, +5982, +6006, +6030, +6054, +6079, +6104, +6127, +6153, +6177, +6202, +6226, +6252, +6277, +6302, +6327, +6352, +6378, +6404, +6429, +6455, +6480, +6506, +6532, +6558, +6584, +6610, +6637, +6663, +6689, +6716, +6743, +6770, +6797, +6823, +6851, +6878, +6905, +6932, +6960, +6987, +7015, +7043, +7070, +7099, +7127, +7155, +7183, +7212, +7240, +7268, +7297, +7325, +7355, +7384, +7412, +7442, +7471, +7500, +7529, +7559, +7588, +7618, +7648, +7678, +7708, +7738, +7769, +7799, +7829, +7860, +7890, +7921, +7952, +7983, +8014, +8045, +8077, +8109, +8139, +8171, +8203, +8235, +8266, +8299, +8331, +8364, +8395, +8428, +8461, +8494, +8526, +8559, +8592, +8626, +8658, +8692, +8726, +8759, +8793, +8826, +8860, +8895, +8929, +8964, +8997, +9032, +9067, +9102, +9137, +9171, +9206, +9242, +9277, +9313, +9349, +9383, +9419, +9455, +9492, +9528, +9564, +9601, +9637, +9674, +9710, +9748, +9785, +9822, +9859, +9896, +9934, +9971, +10009, +10047, +10085, +10124, +10162, +10200, +10238, +10277, +10316, +10355, +10394, +10433, +10472, +10512, +10552, +10591, +10631, +10671, +10711, +10751, +10791, +10832, +10872, +10913, +10954, +10995, +11036, +11077, +11119, +11160, +11202, +11244, +11286, +11328, +11370, +11413, +11455, +11498, +11540, +11583, +11626, +11670, +11713, +11756, +11800, +11844, +11887, +11931, +11976, +12020, +12064, +12109, +12153, +12198, +12243, +12289, +12335, +12380, +12426, +12471, +12517, +12563, +12609, +12655, +12702, +12748, +12795, +12843, +12890, +12937, +12984, +13031, +13079, +13127, +13175, +13223, +13272, +13320, +13368, +13417, +13466, +13515, +13564, +13614, +13663, +13713, +13762, +13812, +13862, +13913, +13964, +14014, +14065, +14115, +14167, +14218, +14269, +14321, +14372, +14425, +14477, +14529, +14581, +14633, +14687, +14739, +14792, +14845, +14899, +14952, +15006, +15059, +15114, +15168, +15222, +15277, +15331, +15386, +15441, +15497, +15552, +15607, +15663, +15719, +15775, +15831, +15887, +15944, +16001, +16058, +16114, +16172, +16229, +16287, +16345, +16403, +16460, +16519, +16577, +16636, +16695, +16754, +16813, +16872, +16932, +16992, +17051, +17112, +17172, +17232, +17293, +17353, +17415, +17476, +17538, +17599, +17660, +17722, +17784, +17847, +17909, +17972, +18034, +18098, +18161, +18225, +18288, +18352, +18415, +18480, +18544, +18609, +18673, +18739, +18803, +18869, +18934, +19000, +19065, +19132, +19198, +19265, +19332, +19398, +19465, +19532, +19600, +19667, +19735, +19804, +19871, +19940, +20008, +20078, +20147, +20216, +20285, +20355, +20425, +20495, +20566, +20635, +20707, +20777, +20848, +20920, +20992, +21063, +21135, +21207, +21279, +21352, +21425, +21497, +21570, +21644, +21718, +21791, +21865, +21940, +22013, +22088, +22163, +22239, +22313, +22389, +22465, +22541, +22618, +22693, +22770, +22847, +22924, +23002, +23078, +23156, +23234, +23312, +23391, +23470, +23548, +23627, +23706, +23786, +23866, +23946, +24026, +24105, +24186, +24267, +24348, +24429, +24511, +24593, +24675, +24757, +24840, +24922, +25005, +25087, +25171, +25254, +25338, +25422, +25507, +25591, +25676, +25761, +25846, +25931, +26017, +26103, +26189, +26275, +26362, +26449, +26536, +26624, +26712, +26800, +26888, +26976, +27064, +27153, +27242, +27331, +27421, +27510, +27600, +27691, +27782, +27872, +27963, +28054, +28146, +28237, +28329, +28422, +28514, +28607, +28700, +28793, +28887, +28981, +29075, +29169, +29263, +29358, +29453, +29548, +29644, +29740, +29836, +29932, +30028, +30126, +30223, +30320, +30417, +30516, +30613, +30711, +30811, +30909, +31008, +31108, +31208, +31307, +31408, +31508, +31609, +31710, +31811, +31913, +32015, +32117, +32220, +32322, +32424, +32528, +32631, +32735, +32839, +32944, +33048, +33153, +33258, +33363, +33469, +33574, +33681, +33787, +33894, +34001, +34109, +34216, +34324, +34433, +34540, +34650, +34758, +34868, +34977, +35087, +35196, +35307, +35418, +35529, +35640, +35751, +35863, +35976, +36088, +36201, +36314, +36427, +36541, +36655, +36768, +36883, +36998, +37112, +37228, +37344, +37459, +37575, +37692, +37809, +37925, +38043, +38161, +38279, +38397, +38515, +38634, +38754, +38873, +38992, +39112, +39233, +39354, +39475, +39596, +39717, +39839, +39961, +40084, +40207, +40330, +40454, +40577, +40700, +40825, +40949, +41074, +41200, +41325, +41451, +41577, +41704, +41831, +41958, +42085, +42213, +42341, +42469, +42598, +42727, +42856, +42986, +43116, +43246, +43377, +43507, +43639, +43770, +43902, +44035, +44167, +44300, +44433, +44566, +44700, +44834, +44968, +45104, +45239, +45374, +45509, +45645, +45782, +45919, +46056, +46193, +46330, +46469, +46607, +46746, +46885, +47025, +47164, +47304, +47444, +47585, +47726, +47867, +48009, +48151, +48293, +48437, +48579, +48722, +48867, +49010, +49155, +49300, +49444, +49590, +49736, +49882, +50028, +50175, +50322, +50470, +50618, +50766, +50915, +51063, +51213, +51362, +51512, +51662, +51813, +51963, +52115, +52267, +52419, +52571, +52724, +52877, +53030, +53184, +53339, +53492, +53648, +53803, +53958, +54114, +54270, +54427, +54584, +54742, +54899, +55057, +55216, +55374, +55533, +55693, +55853, +56013, +56173, +56335, +56496, +56657, +56819, +56982, +57145, +57308, +57472, +57635, +57799, +57964, +58129, +58295, +58460, +58627, +58792, +58959, +59126, +59294, +59462, +59630, +59799, +59968, +60138, +60308, +60478, +60648, +60819, +60991, +61162, +61334, +61507, +61680, +61853, +62026, +62200, +62375, +62550, +62725, +62901, +63076, +63253, +63429, +63606, +63783, +63962, +64140, +64318, +64497, +64676, +64857, +65037, +65217, +65398, +65580, +65761, +65943, +66125, +66309, +66492, +66675, +66860, +67044, +67229, +67415, +67600, +67786, +67973, +68159, +68346, +68534, +68722, +68911, +69099, +69288, +69478, +69668, +69859, +70049, +70241, +70432, +70624, +70816, +71010, +71202, +71397, +71590, +71785, +71980, +72175, +72371, +72567, +72763, +72961, +73157, +73355, +73553, +73752, +73951, +74150, +74350, +74550, +74750, +74952, +75153, +75355, +75557, +75760, +75963, +76167, +76370, +76575, +76779, +76985, +77191, +77396, +77602, +77809, +78017, +78225, +78433, +78641, +78850, +79059, +79269, +79479, +79690, +79901, +80112, +80324, +80537, +80749, +80963, +81176, +81390, +81605, +81819, +82035, +82250, +82466, +82683, +82900, +83118, +83336, +83554, +83773, +83992, +84211, +84431, +84653, +84873, +85094, +85316, +85538, +85761, +85984, +86208, +86431, +86655, +86881, +87106, +87331, +87558, +87784, +88011, +88239, +88467, +88695, +88924, +89153, +89382, +89613, +89843, +90075, +90306, +90537, +90770, +91002, +91236, +91469, +91704, +91938, +92173, +92408, +92644, +92880, +93117, +93355, +93592, +93831, +94068, +94308, +94547, +94787, +95028, +95268, +95509, +95751, +95993, +96236, +96479, +96722, +96966, +97211, +97456, +97701, +97947, +98193, +98440, +98686, +98934, +99182, +99431, +99680, +99930, +100179, +100429, +100680, +100932, +101183, +101436, +101688, +101941, +102195, +102449, +102704, +102959, +103214, +103470, +103726, +103983, +104240, +104498, +104756, +105014, +105273, +105533, +105793, +106053, +106314, +106575, +106838, +107100, +107363, +107626, +107890, +108154, +108419, +108684, +108949, +109215, +109483, +109749, +110017, +110284, +110553, +110822, +111091, +111362, +111632, +111902, +112174, +112445, +112717, +112990, +113263, +113537, +113811, +114085, +114361, +114636, +114912, +115188, +115466, +115743, +116021, +116299, +116578, +116857, +117137, +117417, +117698, +117980, +118261, +118543, +118825, +119109, +119393, +119676, +119961, +120247, +120531, +120818, +121105, +121392, +121679, +121967, +122255, +122544, +122833, +123123, +123414, +123705, +123996, +124288, +124579, +124872, +125166, +125460, +125754, +126049, +126344, +126640, +126936, +127232, +127529, +127826, +128124, +128423, +128722, +129021, +129321, +129623, +129924, +130225, +130527, +130829, +131132, +131435, +131739, +132044, +132348, +132654, +132960, +133266, +133573, +133880, +134189, +134497, +134805, +135114, +135425, +135735, +136045, +136356, +136669, +136980, +137293, +137607, +137920, +138234, +138549, +138864, +139180, +139496, +139812, +140130, +140447, +140765, +141084, +141403, +141722, +142043, +142363, +142684, +143005, +143328, +143650, +143973, +144296, +144621, +144946, +145270, +145596, +145922, +146248, +146575, +146903, +147230, +147559, +147888, +148217, +148547, +148878, +149209, +149540, +149872, +150204, +150537, +150871, +151204, +151538, +151874, +152209, +152545, +152881, +153218, +153555, +153893, +154231, +154570, +154909, +155249, +155590, +155930, +156272, +156613, +156956, +157298, +157642, +157985, +158330, +158674, +159020, +159366, +159712, +160059, +160406, +160754, +161102, +161451, +161800, +162150, +162500, +162850, +163202, +163554, +163906, +164258, +164612, +164965, +165319, +165675, +166029, +166385, +166742, +167098, +167455, +167813, +168171, +168529, +168889, +169248, +169609, +169969, +170330, +170692, +171054, +171416, +171780, +172143, +172507, +172871, +173237, +173602, +173968, +174334, +174702, +175070, +175437, +175806, +176176, +176544, +176915, +177286, +177656, +178028, +178400, +178772, +179145, +179519, +179893, +180268, +180642, +181017, +181393, +181770, +182147, +182524, +182902, +183280, +183659, +184039, +184419, +184799, +185180, +185562, +185944, +186326, +186708, +187091, +187475, +187859, +188244, +188630, +189016, +189402, +189789, +190176, +190564, +190952, +191340, +191729, +192119, +192509, +192901, +193292, +193683, +194075, +194467, +194861, +195255, +195648, +196043, +196439, +196834, +197230, +197626, +198024, +198421, +198818, +199218, +199616, +200015, +200416, +200816, +201217, +201618, +202020, +202423, +202825, +203229, +203632, +204037, +204441, +204847, +205252, +205659, +206065, +206473, +206880, +207288, +207696, +208106, +208516, +208925, +209336, +209747, +210158, +210571, +210983, +211396, +211810, +212223, +212637, +213052, +213468, +213883, +214300, +214717, +215134, +215552, +215969, +216388, +216808, +217227, +217648, +218067, +218488, +218910, +219332, +219755, +220178, +220601, +221025, +221449, +221874, +222300, +222725, +223152, +223578, +224005, +224433, +224861, +225290, +225719, +226148, +226578, +227008, +227439, +227870, +228302, +228734, +229168, +229601, +230034, +230468, +230903, +231339, +231774, +232210, +232646, +233083, +233521, +233959, +234397, +234835, +235275, +235715, +236154, +236596, +237036, +237478, +237920, +238362, +238806, +239249, +239692, +240137, +240581, +241027, +241472, +241918, +242365, +242812, +243260, +243707, +244156, +244604, +245054, +245503, +245954, +246405, +246855, +247307, +247759, +248211, +248665, +249117, +249571, +250025, +250480, +250935, +251390, +251846, +252303, +252760, +253217, +253675, +254133, +254591, +255050, +255510, +255970, +256431, +256891, +257352, +257814, +258277, +258739, +259202, +259665, +260129, +260593, +261058, +261524, +261989, +262455, +262922, +263389, +263856, +264324, +264792, +265261, +265730, +266200, +266669, +267140, +267610, +268082, +268553, +269025, +269498, +269970, +270444, +270917, +271391, +271866, +272341, +272817, +273292, +273769, +274245, +274722, +275200, +275678, +276156, +276635, +277114, +277594, +278074, +278554, +279034, +279516, +279998, +280479, +280963, +281445, +281928, +282412, +282896, +283380, +283866, +284351, +284836, +285323, +285809, +286297, +286783, +287271, +287759, +288248, +288737, +289226, +289716, +290206, +290697, +291187, +291679, +292170, +292663, +293155, +293648, +294141, +294635, +295129, +295623, +296119, +296613, +297109, +297606, +298101, +298599, +299096, +299593, +300091, +300590, +301088, +301587, +302087, +302586, +303087, +303588, +304089, +304590, +305092, +305594, +306097, +306599, +307102, +307606, +308110, +308615, +309119, +309624, +310130, +310636, +311142, +311649, +312156, +312663, +313170, +313678, +314187, +314695, +315205, +315714, +316224, +316734, +317245, +317756, +318267, +318779, +319291, +319803, +320316, +320829, +321342, +321856, +322370, +322885, +323400, +323915, +324430, +324946, +325463, +325979, +326496, +327013, +327531, +328049, +328567, +329085, +329605, +330124, +330644, +331164, +331684, +332205, +332726, +333247, +333768, +334290, +334813, +335336, +335858, +336381, +336906, +337430, +337954, +338479, +339004, +339529, +340055, +340580, +341106, +341634, +342160, +342687, +343215, +343743, +344270, +344799, +345328, +345858, +346387, +346916, +347447, +347976, +348508, +349038, +349570, +350101, +350633, +351165, +351697, +352231, +352763, +353297, +353830, +354365, +354899, +355434, +355969, +356504, +357040, +357575, +358112, +358647, +359185, +359721, +360259, +360797, +361334, +361872, +362411, +362949, +363488, +364027, +364567, +365107, +365647, +366187, +366728, +367269, +367810, +368352, +368893, +369435, +369978, +370521, +371063, +371606, +372150, +372694, +373237, +373782, +374326, +374871, +375415, +375961, +376507, +377053, +377598, +378144, +378691, +379238, +379785, +380333, +380880, +381428, +381976, +382524, +383073, +383622, +384171, +384720, +385270, +385819, +386370, +386920, +387471, +388022, +388573, +389124, +389676, +390226, +390779, +391331, +391883, +392436, +392989, +393542, +394096, +394649, +395203, +395757, +396311, +396866, +397421, +397976, +398531, +399086, +399642, +400198, +400754, +401310, +401866, +402423, +402980, +403537, +404094, +404653, +405211, +405768, +406327, +406885, +407443, +408002, +408561, +409120, +409679, +410239, +410800, +411359, +411920, +412480, +413040, +413601, +414162, +414724, +415285, +415846, +416408, +416970, +417532, +418095, +418657, +419220, +419782, +420345, +420909, +421472, +422036, +422599, +423163, +423728, +424292, +424856, +425420, +425986, +426551, +427116, +427681, +428247, +428812, +429378, +429943, +430510, +431076, +431642, +432209, +432776, +433343, +433910, +434478, +435045, +435612, +436179, +436748, +437315, +437883, +438452, +439020, +439589, +440158, +440726, +441295, +441865, +442434, +443003, +443573, +444142, +444712, +445282, +445852, +446423, +446993, +447563, +448134, +448705, +449275, +449847, +450417, +450989, +451560, +452131, +452703, +453275, +453847, +454419, +454990, +455563, +456135, +456708, +457280, +457852, +458425, +458998, +459571, +460144, +460717, +461290, +461863, +462437, +463010, +463584, +464158, +464732, +465305, +465880, +466454, +467027, +467602, +468176, +468751, +469325, +469900, +470474, +471050, +471624, +472200, +472774, +473350, +473924, +474500, +475075, +475651, +476226, +476802, +477377, +477953, +478529, +479105, +479680, +480257, +480832, +481409, +481985, +482561, +483137, +483714, +484290, +484867, +485443, +486020, +486596, +487173, +487749, +488326, +488902, +489480, +490056, +490634, +491210, +491787, +492364, +492941, +493518, +494096, +494672, +495250, +495827, +496405, +496982, +497559, +498137, +498714, +499292, +499869, +500447, +501024, +501602, +502179, +502757, +503334, +503912, +504489, +505067, +505645, +506222, +506800, +507378, +507956, +508533, +509111, +509688, +510266, +510844, +511422, +512000, +512577, +513155, +513733, +514311, +514888, +515466, +516043, +516621, +517199, +517777, +518354, +518932, +519510, +520087, +520665, +521242, +521820, +522397, +522975, +523552, +524130, +524707, +525285, +525862, +526440, +527018, +527594, +528172, +528749, +529327, +529903, +530481, +531058, +531635, +532212, +532789, +533365, +533943, +534519, +535097, +535673, +536250, +536826, +537403, +537979, +538556, +539132, +539709, +540285, +540862, +541438, +542014, +542591, +543167, +543742, +544319, +544894, +545470, +546046, +546622, +547197, +547773, +548348, +548924, +549499, +550075, +550649, +551225, +551799, +552375, +552949, +553525, +554099, +554674, +555248, +555823, +556397, +556972, +557545, +558119, +558694, +559267, +559841, +560415, +560989, +561562, +562136, +562709, +563282, +563855, +564428, +565001, +565574, +566147, +566719, +567291, +567864, +568436, +569009, +569580, +570152, +570724, +571296, +571868, +572439, +573010, +573582, +574152, +574724, +575294, +575865, +576436, +577006, +577576, +578147, +578717, +579287, +579857, +580426, +580996, +581565, +582134, +582704, +583273, +583841, +584410, +584979, +585547, +586116, +586684, +587251, +587820, +588387, +588954, +589521, +590089, +590656, +591223, +591790, +592357, +592923, +593489, +594056, +594621, +595187, +595752, +596318, +596883, +597448, +598013, +598579, +599143, +599707, +600271, +600836, +601400, +601963, +602527, +603090, +603654, +604217, +604779, +605342, +605904, +606467, +607029, +607591, +608153, +608714, +609275, +609837, +610398, +610959, +611519, +612079, +612640, +613199, +613760, +614320, +614879, +615438, +615997, +616556, +617114, +617672, +618231, +618788, +619346, +619905, +620462, +621019, +621576, +622133, +622689, +623245, +623801, +624357, +624913, +625468, +626023, +626578, +627133, +627688, +628242, +628796, +629350, +629903, +630457, +631010, +631563, +632116, +632668, +633220, +633773, +634323, +634875, +635426, +635977, +636528, +637079, +637629, +638180, +638729, +639279, +639828, +640377, +640926, +641475, +642023, +642571, +643119, +643666, +644214, +644761, +645308, +645855, +646401, +646946, +647492, +648038, +648584, +649128, +649673, +650217, +650762, +651305, +651849, +652393, +652936, +653478, +654021, +654564, +655106, +655647, +656189, +656730, +657271, +657812, +658352, +658892, +659432, +659972, +660511, +661050, +661588, +662127, +662665, +663202, +663740, +664278, +664814, +665352, +665887, +666424, +666959, +667495, +668031, +668565, +669100, +669634, +670169, +670702, +671236, +671768, +672302, +672834, +673366, +673898, +674429, +674961, +675491, +676023, +676552, +677083, +677612, +678141, +678671, +679200, +679729, +680256, +680784, +681312, +681839, +682365, +682893, +683419, +683944, +684470, +684995, +685520, +686045, +686569, +687093, +687618, +688141, +688663, +689186, +689709, +690231, +690752, +691273, +691794, +692315, +692835, +693355, +693875, +694394, +694914, +695432, +695950, +696468, +696986, +697503, +698020, +698536, +699053, +699569, +700084, +700599, +701114, +701629, +702143, +702657, +703170, +703683, +704196, +704708, +705220, +705732, +706243, +706754, +707265, +707775, +708285, +708794, +709304, +709812, +710321, +710829, +711336, +711843, +712350, +712857, +713363, +713869, +714375, +714880, +715384, +715889, +716393, +716897, +717400, +717902, +718405, +718907, +719409, +719910, +720411, +720912, +721413, +721912, +722412, +722911, +723409, +723908, +724406, +724903, +725400, +725898, +726393, +726890, +727386, +727880, +728376, +728870, +729364, +729858, +730351, +730844, +731336, +731829, +732320, +732812, +733302, +733793, +734283, +734773, +735262, +735751, +736240, +736728, +737216, +737702, +738190, +738676, +739163, +739648, +740133, +740619, +741103, +741587, +742071, +742554, +743036, +743520, +744001, +744483, +744965, +745445, +745925, +746405, +746885, +747364, +747843, +748321, +748799, +749277, +749754, +750230, +750707, +751182, +751658, +752133, +752608, +753082, +753555, +754029, +754501, +754974, +755446, +755917, +756389, +756859, +757330, +757799, +758269, +758738, +759207, +759675, +760143, +760610, +761077, +761544, +762010, +762475, +762941, +763406, +763870, +764334, +764797, +765260, +765722, +766185, +766647, +767108, +767568, +768029, +768489, +768949, +769408, +769866, +770324, +770782, +771239, +771696, +772153, +772609, +773064, +773519, +773973, +774428, +774882, +775334, +775788, +776240, +776692, +777144, +777594, +778045, +778495, +778945, +779395, +779843, +780292, +780739, +781187, +781634, +782080, +782527, +782972, +783418, +783862, +784307, +784750, +785193, +785637, +786079, +786521, +786963, +787403, +787845, +788284, +788724, +789164, +789602, +790040, +790478, +790916, +791353, +791789, +792225, +792661, +793096, +793531, +793965, +794398, +794831, +795265, +795697, +796129, +796560, +796991, +797421, +797851, +798280, +798709, +799138, +799566, +799994, +800421, +800847, +801274, +801699, +802125, +802550, +802974, +803398, +803821, +804244, +804667, +805089, +805511, +805932, +806351, +806772, +807191, +807611, +808030, +808447, +808865, +809282, +809699, +810116, +810531, +810947, +811362, +811776, +812189, +812603, +813016, +813428, +813841, +814252, +814663, +815074, +815483, +815893, +816303, +816711, +817119, +817526, +817934, +818340, +818747, +819152, +819558, +819962, +820367, +820770, +821174, +821576, +821979, +822381, +822782, +823183, +823583, +823984, +824383, +824781, +825181, +825578, +825975, +826373, +826769, +827165, +827560, +827956, +828351, +828744, +829138, +829532, +829924, +830316, +830707, +831098, +831490, +831880, +832270, +832659, +833047, +833435, +833823, +834210, +834597, +834983, +835369, +835755, +836140, +836524, +836908, +837291, +837674, +838055, +838437, +838819, +839200, +839580, +839960, +840340, +840719, +841097, +841475, +841852, +842229, +842606, +842982, +843357, +843731, +844106, +844480, +844854, +845226, +845599, +845971, +846343, +846713, +847084, +847455, +847823, +848193, +848562, +848929, +849297, +849665, +850031, +850397, +850762, +851128, +851492, +851856, +852219, +852583, +852945, +853307, +853669, +854030, +854390, +854751, +855110, +855470, +855828, +856186, +856544, +856901, +857257, +857614, +857970, +858325, +858680, +859034, +859387, +859741, +860093, +860445, +860797, +861149, +861499, +861849, +862199, +862549, +862897, +863245, +863593, +863940, +864287, +864633, +864979, +865325, +865669, +866014, +866357, +866701, +867043, +867386, +867727, +868069, +868409, +868750, +869090, +869429, +869768, +870106, +870444, +870781, +871118, +871454, +871790, +872125, +872461, +872795, +873128, +873462, +873795, +874127, +874459, +874790, +875121, +875452, +875782, +876111, +876440, +876769, +877096, +877424, +877751, +878077, +878403, +878729, +879053, +879378, +879703, +880026, +880349, +880671, +880994, +881315, +881636, +881956, +882277, +882596, +882915, +883234, +883552, +883869, +884187, +884503, +884819, +885135, +885450, +885765, +886079, +886392, +886706, +887019, +887330, +887643, +887954, +888264, +888574, +888885, +889194, +889502, +889810, +890119, +890426, +890733, +891039, +891345, +891651, +891955, +892260, +892564, +892867, +893170, +893472, +893774, +894075, +894376, +894678, +894978, +895277, +895576, +895875, +896173, +896470, +896768, +897063, +897359, +897655, +897950, +898245, +898539, +898833, +899127, +899420, +899711, +900003, +900294, +900585, +900876, +901166, +901455, +901744, +902032, +902320, +902607, +902894, +903181, +903468, +903752, +904038, +904323, +904606, +904890, +905174, +905456, +905738, +906019, +906301, +906582, +906862, +907142, +907421, +907700, +907978, +908256, +908533, +908811, +909087, +909363, +909638, +909914, +910188, +910462, +910736, +911009, +911282, +911554, +911825, +912097, +912367, +912637, +912908, +913177, +913446, +913715, +913982, +914250, +914516, +914784, +915050, +915315, +915580, +915845, +916109, +916373, +916636, +916899, +917161, +917424, +917685, +917946, +918206, +918466, +918726, +918985, +919243, +919501, +919759, +920016, +920273, +920529, +920785, +921040, +921295, +921550, +921804, +922058, +922311, +922563, +922816, +923067, +923319, +923570, +923820, +924069, +924319, +924568, +924817, +925065, +925313, +925559, +925806, +926052, +926298, +926543, +926788, +927033, +927277, +927520, +927763, +928006, +928248, +928490, +928731, +928971, +929212, +929452, +929691, +929931, +930168, +930407, +930645, +930882, +931119, +931355, +931591, +931826, +932061, +932295, +932530, +932763, +932997, +933229, +933462, +933693, +933924, +934156, +934386, +934617, +934846, +935075, +935304, +935532, +935760, +935988, +936215, +936441, +936668, +936893, +937118, +937343, +937568, +937791, +938015, +938238, +938461, +938683, +938905, +939126, +939346, +939568, +939788, +940007, +940226, +940445, +940663, +940881, +941098, +941316, +941533, +941749, +941964, +942180, +942394, +942609, +942823, +943036, +943250, +943462, +943675, +943887, +944098, +944309, +944520, +944730, +944940, +945149, +945358, +945566, +945774, +945982, +946190, +946397, +946603, +946808, +947014, +947220, +947424, +947629, +947832, +948036, +948239, +948442, +948644, +948846, +949047, +949249, +949449, +949649, +949849, +950048, +950247, +950446, +950644, +950842, +951039, +951236, +951432, +951628, +951824, +952019, +952214, +952409, +952602, +952797, +952989, +953183, +953375, +953567, +953758, +953950, +954140, +954331, +954521, +954711, +954900, +955088, +955277, +955465, +955653, +955840, +956026, +956213, +956399, +956584, +956770, +956955, +957139, +957324, +957507, +957690, +957874, +958056, +958238, +958419, +958601, +958782, +958962, +959142, +959323, +959502, +959681, +959859, +960037, +960216, +960393, +960570, +960746, +960923, +961098, +961274, +961450, +961624, +961799, +961973, +962146, +962319, +962492, +962665, +962837, +963008, +963180, +963351, +963521, +963691, +963861, +964031, +964200, +964369, +964537, +964705, +964873, +965040, +965207, +965372, +965539, +965704, +965870, +966035, +966200, +966364, +966528, +966691, +966854, +967017, +967180, +967342, +967503, +967664, +967826, +967986, +968146, +968306, +968466, +968625, +968783, +968942, +969100, +969257, +969415, +969572, +969729, +969885, +970041, +970197, +970351, +970507, +970660, +970815, +970969, +971122, +971275, +971428, +971580, +971732, +971884, +972036, +972186, +972337, +972487, +972637, +972786, +972936, +973084, +973233, +973381, +973529, +973677, +973823, +973971, +974117, +974263, +974409, +974555, +974699, +974844, +974989, +975132, +975277, +975420, +975562, +975706, +975848, +975990, +976132, +976273, +976414, +976554, +976695, +976835, +976974, +977114, +977253, +977392, +977530, +977669, +977806, +977943, +978080, +978217, +978354, +978490, +978625, +978760, +978895, +979031, +979165, +979299, +979433, +979566, +979699, +979832, +979964, +980097, +980229, +980360, +980492, +980622, +980753, +980883, +981013, +981143, +981272, +981401, +981530, +981658, +981786, +981914, +982041, +982168, +982295, +982422, +982548, +982674, +982799, +982925, +983050, +983174, +983299, +983422, +983545, +983669, +983792, +983915, +984038, +984160, +984282, +984403, +984524, +984645, +984766, +984887, +985007, +985126, +985245, +985365, +985484, +985602, +985720, +985838, +985956, +986074, +986190, +986307, +986424, +986540, +986655, +986771, +986887, +987001, +987116, +987231, +987344, +987458, +987572, +987685, +987798, +987911, +988023, +988136, +988248, +988359, +988470, +988581, +988692, +988803, +988912, +989022, +989131, +989241, +989349, +989459, +989566, +989675, +989783, +989890, +989998, +990105, +990212, +990318, +990425, +990530, +990636, +990741, +990846, +990951, +991055, +991160, +991264, +991368, +991471, +991575, +991677, +991779, +991882, +991984, +992085, +992188, +992289, +992390, +992491, +992591, +992692, +992791, +992891, +992991, +993090, +993188, +993288, +993386, +993483, +993582, +993679, +993776, +993873, +993971, +994067, +994163, +994259, +994355, +994451, +994546, +994641, +994736, +994830, +994924, +995018, +995112, +995206, +995299, +995392, +995485, +995577, +995670, +995762, +995853, +995945, +996036, +996127, +996217, +996309, +996399, +996489, +996578, +996668, +996757, +996846, +996935, +997023, +997111, +997199, +997287, +997375, +997463, +997550, +997637, +997724, +997810, +997896, +997982, +998068, +998153, +998238, +998323, +998408, +998492, +998577, +998661, +998745, +998828, +998911, +998994, +999077, +999159, +999242, +999324, +999406, +999488, +999570, +999651, +999732, +999813, +999894, +999973, +1000053, +1000133, +1000213, +1000293, +1000372, +1000451, +1000529, +1000608, +1000687, +1000765, +1000843, +1000921, +1000997, +1001075, +1001152, +1001229, +1001306, +1001381, +1001458, +1001534, +1001610, +1001686, +1001760, +1001836, +1001911, +1001986, +1002059, +1002134, +1002208, +1002281, +1002355, +1002429, +1002502, +1002574, +1002647, +1002720, +1002792, +1002864, +1002936, +1003007, +1003079, +1003151, +1003222, +1003292, +1003364, +1003433, +1003504, +1003574, +1003644, +1003714, +1003783, +1003852, +1003921, +1003991, +1004059, +1004128, +1004195, +1004264, +1004332, +1004399, +1004467, +1004534, +1004601, +1004667, +1004734, +1004801, +1004867, +1004934, +1004999, +1005065, +1005130, +1005196, +1005260, +1005326, +1005390, +1005455, +1005519, +1005584, +1005647, +1005711, +1005774, +1005838, +1005901, +1005965, +1006027, +1006090, +1006152, +1006215, +1006277, +1006339, +1006400, +1006461, +1006523, +1006584, +1006646, +1006706, +1006767, +1006827, +1006887, +1006948, +1007007, +1007067, +1007127, +1007186, +1007245, +1007304, +1007363, +1007422, +1007480, +1007539, +1007596, +1007654, +1007712, +1007770, +1007827, +1007885, +1007941, +1007998, +1008055, +1008112, +1008168, +1008224, +1008280, +1008336, +1008392, +1008447, +1008502, +1008558, +1008613, +1008668, +1008722, +1008777, +1008831, +1008885, +1008940, +1008993, +1009047, +1009100, +1009154, +1009207, +1009260, +1009312, +1009366, +1009418, +1009470, +1009522, +1009574, +1009627, +1009678, +1009730, +1009781, +1009832, +1009884, +1009934, +1009985, +1010035, +1010086, +1010137, +1010187, +1010237, +1010286, +1010336, +1010385, +1010435, +1010484, +1010533, +1010582, +1010631, +1010679, +1010727, +1010776, +1010824, +1010872, +1010920, +1010968, +1011015, +1011062, +1011109, +1011156, +1011204, +1011251, +1011297, +1011344, +1011390, +1011436, +1011482, +1011528, +1011573, +1011619, +1011664, +1011710, +1011756, +1011801, +1011846, +1011890, +1011935, +1011979, +1012023, +1012068, +1012112, +1012155, +1012199, +1012243, +1012286, +1012329, +1012373, +1012416, +1012459, +1012501, +1012544, +1012586, +1012629, +1012671, +1012713, +1012755, +1012797, +1012839, +1012880, +1012922, +1012963, +1013004, +1013045, +1013086, +1013127, +1013167, +1013208, +1013247, +1013288, +1013328, +1013368, +1013408, +1013447, +1013487, +1013527, +1013566, +1013605, +1013644, +1013683, +1013722, +1013761, +1013799, +1013837, +1013875, +1013914, +1013952, +1013990, +1014028, +1014065, +1014103, +1014140, +1014177, +1014214, +1014251, +1014289, +1014325, +1014362, +1014398, +1014435, +1014471, +1014507, +1014544, +1014580, +1014616, +1014650, +1014686, +1014722, +1014757, +1014793, +1014828, +1014862, +1014897, +1014932, +1014967, +1015002, +1015035, +1015070, +1015104, +1015139, +1015173, +1015206, +1015240, +1015273, +1015307, +1015341, +1015373, +1015407, +1015440, +1015473, +1015505, +1015538, +1015571, +1015604, +1015635, +1015668, +1015700, +1015733, +1015765, +1015796, +1015828, +1015860, +1015890, +1015922, +1015954, +1015985, +1016016, +1016047, +1016078, +1016109, +1016139, +1016170, +1016200, +1016230, +1016261, +1016291, +1016321, +1016351, +1016381, +1016411, +1016440, +1016470, +1016499, +1016528, +1016557, +1016587, +1016615, +1016644, +1016674, +1016703, +1016731, +1016759, +1016787, +1016816, +1016844, +1016872, +1016900, +1016929, +1016956, +1016984, +1017012, +1017039, +1017067, +1017094, +1017121, +1017148, +1017176, +1017202, +1017229, +1017256, +1017283, +1017310, +1017336, +1017362, +1017389, +1017415, +1017441, +1017467, +1017493, +1017519, +1017544, +1017570, +1017595, +1017621, +1017647, +1017672, +1017697, +1017722, +1017747, +1017773, +1017797, +1017822, +1017846, +1017872, +1017895, +1017920, +1017945, +1017969, +1017993, +1018017, +1018041, +1018065, +1018089, +1018113, +1018136, +1018160, +1018183, +1018207, +1018230, +1018254, +1018276, +1018300, +1018322, +1018346, +1018369, +1018391, +1018414, +1018436, +1018459, +1018481, +1018504, +1018526, +1018548, +1018570, +1018592, +1018614, +1018636, +1018658, +1018680, +1018701, +1018723, +1018744, +1018766, +1018787, +1018808, +1018829, +1018851, +1018871, +1018893, +1018913, +1018934, +1018954, +1018976, +1018996, +1019017, +1019037, +1019057, +1019077, +1019098, +1019118, +1019138, +1019158, +1019177, +1019197, +1019217, +1019237, +1019256, +1019276, +1019295, +1019315, +1019334, +1019354, +1019372, +1019392, +1019411, +1019429, +1019449, +1019467, +1019486, +1019504, +1019524, +1019542, +1019560, +1019579, +1019597, +1019615, +1019633, +1019652, +1019670, +1019687, +1019706, +1019723, +1019742, +1019759, +1019777, +1019794, +1019811, +1019829, +1019846, +1019864, +1019881, +1019898, +1019916, +1019932, +1019950, +1019967, +1019983, +1020001, +1020017, +1020034, +1020050, +1020067, +1020084, +1020100, +1020117, +1020133, +1020149, +1020165, +1020181, +1020197, +1020214, +1020229, +1020246, +1020261, +1020277, +1020293, +1020308, +1020323, +1020340, +1020355, +1020370, +1020386, +1020401, +1020417, +1020431, +1020446, +1020462, +1020477, +1020491, +1020507, +1020521, +1020536, +1020551, +1020565, +1020580, +1020595, +1020609, +1020623, +1020638, +1020652, +1020666, +1020681, +1020695, +1020709, +1020724, +1020737, +1020751, +1020765, +1020779, +1020792, +1020807, +1020820, +1020834, +1020848, +1020861, +1020874, +1020888, +1020901, +1020914, +1020927, +1020941, +1020954, +1020967, +1020981, +1020993, +1021006, +1021020, +1021032, +1021045, +1021058, +1021071, +1021083, +1021095, +1021109, +1021121, +1021133, +1021146, +1021158, +1021170, +1021182, +1021195, +1021207, +1021219, +1021232, +1021243, +1021255, +1021267, +1021279, +1021291, +1021303, +1021315, +1021326, +1021338, +1021349, +1021362, +1021373, +1021384, +1021395, +1021407, +1021418, +1021429, +1021441, +1021452, +1021463, +1021474, +1021486, +1021497, +1021507, +1021518, +1021530, +1021540, +1021551, +1021561, +1021573, +1021583, +1021594, +1021604, +1021615, +1021626, +1021636, +1021646, +1021657, +1021667, +1021677, +1021687, +1021698, +1021708, +1021718, +1021728, +1021739, +1021749, +1021759, +1021768, +1021778, +1021789, +1021798, +1021808, +1021817, +1021828, +1021837, +1021847, +1021856, +1021865, +1021876, +1021885, +1021894, +1021903, +1021913, +1021922, +1021931, +1021941, +1021949, +1021959, +1021968, +1021977, +1021986, +1021996, +1022005, +1022013, +1022022, +1022031, +1022040, +1022049, +1022058, +1022066, +1022075, +1022084, +1022092, +1022101, +1022109, +1022118, +1022127, +1022135, +1022143, +1022151, +1022160, +1022169, +1022177, +1022185, +1022193, +1022201, +1022210, +1022218, +1022226, +1022233, +1022241, +1022250, +1022258, +1022266, +1022273, +1022281, +1022289, +1022297, +1022305, +1022312, +1022320, +1022327, +1022335, +1022343, +1022350, +1022358, +1022365, +1022372, +1022381, +1022388, +1022395, +1022402, +1022409, +1022416, +1022425, +1022432, +1022439, +1022446, +1022453, +1022459, +1022467, +1022474, +1022481, +1022488, +1022495, +1022501, +1022509, +1022516, +1022523, +1022529, +1022536, +1022542, +1022549, +1022557, +1022563, +1022570, +1022576, +1022582, +1022589, +1022596, +1022602, +1022609, +1022615, +1022621, +1022628, +1022635, +1022641, +1022647, +1022653, +1022659, +1022665, +1022672, +1022679, +1022685, +1022691, +1022696, +1022702, +1022708, +1022714, +1022721, +1022727, +1022733, +1022738, +1022744, +1022750, +1022756, +1022761, +1022768, +1022774, +1022779, +1022785, +1022790, +1022796, +1022801, +1022808, +1022813, +1022819, +1022824, +1022830, +1022835, +1022840, +1022846, +1022852, +1022857, +1022862, +1022868, +1022873, +1022878, +1022883, +1022888, +1022894, +1022900, +1022905, +1022910, +1022915, +1022920, +1022925, +1022930, +1022936, +1022941, +1022945, +1022950, +1022955, +1022960, +1022965, +1022970, +1022974, +1022980, +1022985, +1022990, +1022994, +1022999, +1023004, +1023008, +1023013, +1023018, +1023023, +1023028, +1023032, +1023037, +1023041, +1023046, +1023050, +1023054, +1023059, +1023064, +1023069, +1023073, +1023077, +1023082, +1023086, +1023090, +1023094, +1023099, +1023104, +1023108, +1023112, +1023116, +1023121, +1023125, +1023129, +1023133, +1023137, +1023141, +1023145, +1023150, +1023154, +1023158, +1023162, +1023166, +1023170, +1023174, +1023178, +1023182, +1023186, +1023190, +1023194, +1023198, +1023202, +1023206, +1023209, +1023213, +1023217, +1023221, +1023224, +1023228, +1023233, +1023236, +1023240, +1023243, +1023247, +1023251, +1023254, +1023258, +1023261, +1023265, +1023268, +1023272, +1023276, +1023280, +1023283, +1023287, +1023290, +1023293, +1023297, +1023300, +1023303, +1023307, +1023310, +1023313, +1023317, +1023321, +1023324, +1023327, +1023331, +1023334, +1023337, +1023340, +1023343, +1023347, +1023350, +1023353, +1023356, +1023359, +1023363, +1023366, +1023369, +1023372, +1023375, +1023378, +1023381, +1023384, +1023387, +1023390, +1023393, +1023396, +1023399, +1023403, +1023406, +1023409, +1023412, +1023414, +1023417, +1023420, +1023423, +1023426, +1023428, +1023431, +1023434, +1023437, +1023439, +1023442, +1023446, +1023449, +1023451, +1023454, +1023457, +1023459, +1023462, +1023465, +1023467, +1023470, +1023472, +1023475, +1023477, +1023480, +1023483, +1023485, +1023489, +1023491, +1023494, +1023496, +1023499, +1023501, +1023503, +1023506, +1023508, +1023511, +1023513, +1023516, +1023518, +1023520, +1023523, +1023525, +1023527, +1023531, +1023533, +1023535, +1023538, +1023540, +1023542, +1023544, +1023547, +1023549, +1023551, +1023553, +1023556, +1023558, +1023560, +1023562, +1023564, +1023566, +1023569, +1023571, +1023574, +1023576, +1023578, +1023580, +1023582, +1023584, +1023586, +1023588, +1023590, +1023592, +1023595, +1023597, +1023599, +1023601, +1023603, +1023604, +1023606, +1023608, +1023610, +1023612, +1023614, +1023617, +1023619, +1023621, +1023623, +1023625, +1023627, +1023629, +1023630, +1023632, +1023634, +1023636, +1023638, +1023640, +1023641, +1023643, +1023645, +1023647, +1023649, +1023650, +1023652, +1023654, +1023656, +1023657, +1023660, +1023662, +1023663, +1023665, +1023667, +1023668, +1023670, +1023672, +1023673, +1023675, +1023677, +1023678, +1023680, +1023682, +1023683, +1023685, +1023686, +1023688, +1023690, +1023691, +1023693, +1023694, +1023696, +1023697, +1023699, +1023700, +1023703, +1023704, +1023706, +1023707, +1023709, +1023710, +1023712, +1023713, +1023715, +1023716, +1023718, +1023719, +1023721, +1023722, +1023723, +1023725, +1023726, +1023728, +1023729, +1023730, +1023732, +1023733, +1023735, +1023736, +1023737, +1023739, +1023740, +1023741, +1023744, +1023744, +1023746, +1023748, +1023749, +1023750, +1023751, +1023753, +1023754, +1023755, +1023757, +1023758, +1023759, +1023760, +1023762, +1023763, +1023764, +1023765, +1023766, +1023768, +1023769, +1023770, +1023771, +1023772, +1023774, +1023775, +1023776, +1023777, +1023778, +1023779, +1023780, +1023782, +1023783, +1023784, +1023786, +1023786, +1023788, +1023789, +1023790, +1023792, +1023793, +1023794, +1023795, +1023796, +1023797, +1023798, +1023799, +1023800, +1023801, +1023802, +1023803, +1023804, +1023805, +1023806, +1023807, +1023808, +1023809, +1023810, +1023811, +1023812, +1023813, +1023814, +1023815, +1023816, +1023817, +1023818, +1023819, +1023820, +1023821, +1023822, +1023823, +1023824, +1023825, +1023826, +1023826, +1023827, +1023828, +1023830, +1023831, +1023832, +1023833, +1023834, +1023835, +1023836, +1023836, +1023837, +1023838, +1023839, +1023840, +1023841, +1023842, +1023842, +1023843, +1023844, +1023845, +1023846, +1023846, +1023847, +1023848, +1023849, +1023850, +1023851, +1023851, +1023852, +1023853, +1023854, +1023854, +1023855, +1023856, +1023857, +1023858, +1023858, +1023859, +1023860, +1023861, +1023861, +1023862, +1023863, +1023863, +1023864, +1023865, +1023866, +1023866, +1023867, +1023868, +1023868, +1023869, +1023870, +1023872, +1023872, +1023873, +1023874, +1023874, +1023875, +1023876, +1023876, +1023877, +1023878, +1023878, +1023879, +1023880, +1023880, +1023881, +1023882, +1023882, +1023883, +1023883, +1023884, +1023885, +1023885, +1023886, +1023887, +1023887, +1023888, +1023888, +1023889, +1023890, +1023890, +1023891, +1023891, +1023892, +1023893, +1023893, +1023894, +1023894, +1023895, +1023895, +1023896, +1023897, +1023897, +1023898, +1023898, +1023899, +1023899, +1023900, +1023900, +1023901, +1023902, +1023902, +1023903, +1023903, +1023904, +1023904, +1023905, +1023905, +1023906, +1023906, +1023907, +1023907, +1023908, +1023908, +1023909, +1023909, +1023910, +1023910, +1023911, +1023911, +1023912, +1023912, +1023914, +1023914, +1023914, +1023914, +1023916, +1023916, +1023916, +1023917, +1023917, +1023918, +1023918, +1023919, +1023919, +1023920, +1023920, +1023921, +1023921, +1023921, +1023922, +1023922, +1023923, +1023923, +1023924, +1023924, +1023924, +1023925, +1023925, +1023926, +1023926, +1023926, +1023927, +1023927, +1023928, +1023928, +1023928, +1023929, +1023929, +1023930, +1023930, +1023930, +1023931, +1023931, +1023932, +1023932, +1023932, +1023933, +1023933, +1023933, +1023934, +1023934, +1023935, +1023935, +1023935, +1023936, +1023936, +1023936, +1023937, +1023937, +1023937, +1023938, +1023938, +1023938, +1023939, +1023939, +1023939, +1023940, +1023940, +1023941, +1023941, +1023941, +1023941, +1023942, +1023942, +1023942, +1023943, +1023943, +1023943, +1023944, +1023944, +1023944, +1023945, +1023945, +1023945, +1023946, +1023946, +1023946, +1023947, +1023947, +1023947, +1023947, +1023948, +1023948, +1023948, +1023949, +1023949, +1023949, +1023949, +1023950, +1023950, +1023950, +1023951, +1023951, +1023951, +1023951, +1023952, +1023952, +1023952, +1023952, +1023953, +1023953, +1023953, +1023954, +1023954, +1023954, +1023954, +1023955, +1023955, +1023955, +1023955, +1023956, +1023956, +1023956, +1023956, +1023958, +1023958, +1023958, +1023958, +1023958, +1023959, +1023959, +1023959, +1023959, +1023960, +1023960, +1023960, +1023960, +1023961, +1023961, +1023961, +1023961, +1023961, +1023962, +1023962, +1023962, +1023962, +1023963, +1023963, +1023963, +1023963, +1023963, +1023964, +1023964, +1023964, +1023964, +1023964, +1023965, +1023965, +1023965, +1023965, +1023965, +1023966, +1023966, +1023966, +1023966, +1023966, +1023967, +1023967, +1023967, +1023967, +1023967, +1023968, +1023968, +1023968, +1023968, +1023968, +1023969, +1023969, +1023969, +1023969, +1023969, +1023969, +1023970, +1023970, +1023970, +1023970, +1023970, +1023970, +1023971, +1023971, +1023971, +1023971, +1023971, +1023972, +1023972, +1023972, +1023972, +1023972, +1023972, +1023972, +1023973, +1023973, +1023973, +1023973, +1023973, +1023973, +1023974, +1023974, +1023974, +1023974, +1023974, +1023974, +1023974, +1023975, +1023975, +1023975, +1023975, +1023975, +1023975, +1023976, +1023976, +1023976, +1023976, +1023976, +1023976, +1023976, +1023976, +1023977, +1023977, +1023977, +1023977, +1023977, +1023977, +1023977, +1023978, +1023978, +1023978, +1023978, +1023978, +1023978, +1023978, +1023978, +1023979, +1023979, +1023979, +1023979, +1023979, +1023979, +1023979, +1023979, +1023980, +1023980, +1023980, +1023980, +1023980, +1023980, +1023980, +1023980, +1023980, +1023981, +1023981, +1023981, +1023981, +1023981, +1023981, +1023981, +1023981, +1023981, +1023982, +1023982, +1023982, +1023982, +1023982, +1023982, +1023982, +1023982, +1023982, +1023983, +1023983, +1023983, +1023983, +1023983, +1023983, +1023983, +1023983, +1023983, +1023983, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023984, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023985, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023986, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023987, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023988, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023989, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023990, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023991, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023992, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023993, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023994, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023995, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023996, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023997, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1023998, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, +1024000, diff --git a/rce/rcecalib/dataproc/fit/errf_ext_int.dat b/rce/rcecalib/dataproc/fit/errf_ext_int.dat new file mode 100644 index 0000000000000000000000000000000000000000..adc1f0bf6e8ad0d896747585d68b2872efebc580 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/errf_ext_int.dat @@ -0,0 +1,7001 @@ +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +9, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +11, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +12, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +13, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +14, +15, +15, +15, +15, +15, +15, +15, +15, +15, +15, +15, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +17, +17, +17, +17, +17, +17, +17, +17, +17, +18, +18, +18, +18, +18, +18, +18, +18, +18, +19, +19, +19, +19, +19, +19, +19, +19, +19, +20, +20, +20, +20, +20, +20, +20, +20, +21, +21, +21, +21, +21, +21, +21, +21, +22, +22, +22, +22, +22, +22, +22, +23, +23, +23, +23, +23, +23, +23, +23, +24, +24, +24, +24, +24, +24, +25, +25, +25, +25, +25, +25, +25, +26, +26, +26, +26, +26, +26, +27, +27, +27, +27, +27, +27, +28, +28, +28, +28, +28, +28, +28, +29, +29, +29, +29, +29, +30, +30, +30, +30, +30, +30, +31, +31, +31, +31, +31, +32, +32, +32, +32, +32, +33, +33, +33, +33, +33, +33, +34, +34, +34, +34, +35, +35, +35, +35, +35, +36, +36, +36, +36, +36, +37, +37, +37, +37, +38, +38, +38, +38, +38, +39, +39, +39, +39, +40, +40, +40, +40, +41, +41, +41, +41, +41, +42, +42, +42, +42, +43, +43, +43, +43, +44, +44, +44, +44, +45, +45, +45, +46, +46, +46, +46, +47, +47, +47, +47, +48, +48, +48, +49, +49, +49, +49, +50, +50, +50, +51, +51, +51, +51, +52, +52, +52, +53, +53, +53, +54, +54, +54, +55, +55, +55, +56, +56, +56, +57, +57, +57, +57, +58, +58, +59, +59, +59, +60, +60, +60, +61, +61, +61, +62, +62, +62, +63, +63, +63, +64, +64, +65, +65, +65, +66, +66, +66, +67, +67, +68, +68, +68, +69, +69, +70, +70, +70, +71, +71, +72, +72, +72, +73, +73, +74, +74, +74, +75, +75, +76, +76, +77, +77, +77, +78, +78, +79, +79, +80, +80, +81, +81, +82, +82, +82, +83, +83, +84, +84, +85, +85, +86, +86, +87, +87, +88, +88, +89, +89, +90, +90, +91, +91, +92, +92, +93, +93, +94, +94, +95, +95, +96, +97, +97, +98, +98, +99, +99, +100, +100, +101, +102, +102, +103, +103, +104, +104, +105, +106, +106, +107, +107, +108, +109, +109, +110, +110, +111, +112, +112, +113, +114, +114, +115, +115, +116, +117, +117, +118, +119, +119, +120, +121, +121, +122, +123, +123, +124, +125, +125, +126, +127, +128, +128, +129, +130, +130, +131, +132, +133, +133, +134, +135, +135, +136, +137, +138, +138, +139, +140, +141, +142, +142, +143, +144, +145, +145, +146, +147, +148, +149, +150, +150, +151, +152, +153, +154, +154, +155, +156, +157, +158, +159, +160, +160, +161, +162, +163, +164, +165, +166, +167, +168, +169, +169, +170, +171, +172, +173, +174, +175, +176, +177, +178, +179, +180, +181, +182, +183, +184, +185, +186, +187, +188, +189, +190, +191, +192, +193, +194, +195, +196, +197, +198, +199, +200, +201, +202, +203, +205, +206, +207, +208, +209, +210, +211, +212, +214, +215, +216, +217, +218, +219, +220, +222, +223, +224, +225, +226, +228, +229, +230, +231, +232, +234, +235, +236, +237, +239, +240, +241, +243, +244, +245, +246, +248, +248, +250, +252, +253, +254, +256, +257, +258, +260, +261, +262, +264, +265, +267, +268, +270, +271, +272, +274, +275, +277, +278, +280, +281, +283, +284, +286, +287, +289, +290, +292, +293, +295, +296, +298, +299, +301, +302, +304, +306, +307, +309, +310, +312, +314, +315, +317, +319, +320, +322, +324, +325, +327, +329, +330, +332, +334, +335, +337, +339, +341, +342, +344, +346, +348, +350, +351, +353, +355, +357, +359, +361, +362, +364, +366, +368, +370, +372, +374, +376, +378, +380, +382, +384, +385, +387, +389, +391, +393, +396, +398, +400, +402, +404, +406, +408, +410, +412, +414, +416, +418, +420, +423, +425, +427, +429, +431, +434, +436, +438, +440, +442, +445, +447, +449, +451, +454, +456, +458, +461, +463, +465, +468, +470, +472, +475, +477, +480, +482, +485, +487, +488, +492, +494, +497, +499, +501, +504, +506, +510, +512, +515, +517, +520, +522, +525, +528, +530, +533, +536, +538, +541, +544, +547, +549, +552, +555, +558, +560, +563, +566, +569, +572, +574, +577, +580, +583, +586, +589, +592, +595, +598, +601, +604, +607, +610, +613, +616, +619, +622, +625, +628, +631, +634, +637, +641, +644, +647, +650, +653, +657, +660, +663, +666, +670, +673, +676, +680, +683, +686, +690, +693, +696, +700, +703, +707, +710, +714, +717, +721, +724, +728, +731, +735, +739, +742, +746, +749, +753, +757, +760, +764, +768, +772, +775, +779, +783, +787, +791, +794, +798, +802, +806, +810, +814, +818, +822, +826, +830, +834, +838, +842, +846, +850, +854, +858, +863, +867, +871, +875, +879, +884, +888, +892, +896, +901, +905, +909, +914, +918, +923, +927, +931, +936, +940, +945, +949, +954, +959, +963, +968, +972, +977, +982, +985, +990, +995, +1000, +1005, +1010, +1015, +1020, +1025, +1030, +1034, +1039, +1044, +1049, +1054, +1059, +1064, +1069, +1074, +1080, +1085, +1090, +1095, +1100, +1105, +1111, +1116, +1121, +1126, +1132, +1137, +1142, +1148, +1153, +1159, +1164, +1170, +1175, +1181, +1186, +1192, +1197, +1203, +1209, +1214, +1220, +1226, +1232, +1237, +1243, +1249, +1255, +1261, +1267, +1273, +1278, +1284, +1290, +1296, +1303, +1309, +1315, +1321, +1327, +1333, +1339, +1346, +1352, +1358, +1364, +1371, +1377, +1384, +1390, +1397, +1403, +1409, +1416, +1423, +1429, +1436, +1442, +1449, +1456, +1463, +1469, +1476, +1483, +1490, +1497, +1503, +1510, +1517, +1524, +1531, +1538, +1546, +1553, +1560, +1567, +1574, +1581, +1589, +1596, +1603, +1611, +1618, +1625, +1633, +1640, +1648, +1655, +1663, +1670, +1678, +1686, +1693, +1701, +1709, +1717, +1725, +1732, +1740, +1748, +1756, +1764, +1772, +1780, +1788, +1796, +1805, +1813, +1821, +1829, +1837, +1846, +1854, +1863, +1871, +1879, +1888, +1896, +1905, +1914, +1922, +1931, +1940, +1948, +1957, +1965, +1975, +1984, +1993, +2001, +2010, +2020, +2029, +2037, +2047, +2056, +2065, +2074, +2084, +2093, +2102, +2112, +2121, +2131, +2140, +2150, +2159, +2169, +2179, +2188, +2198, +2208, +2218, +2228, +2238, +2248, +2257, +2268, +2278, +2288, +2298, +2308, +2318, +2329, +2339, +2349, +2360, +2370, +2381, +2391, +2402, +2412, +2423, +2434, +2444, +2455, +2466, +2477, +2488, +2499, +2510, +2521, +2532, +2543, +2554, +2565, +2576, +2588, +2599, +2611, +2622, +2633, +2645, +2657, +2668, +2680, +2692, +2703, +2715, +2727, +2739, +2751, +2763, +2775, +2787, +2799, +2811, +2823, +2836, +2848, +2860, +2873, +2885, +2898, +2910, +2923, +2936, +2948, +2961, +2974, +2987, +3000, +3013, +3026, +3039, +3052, +3065, +3078, +3091, +3105, +3118, +3132, +3145, +3159, +3172, +3186, +3199, +3213, +3227, +3241, +3255, +3269, +3283, +3297, +3311, +3325, +3339, +3354, +3368, +3382, +3397, +3411, +3426, +3440, +3455, +3470, +3485, +3499, +3514, +3529, +3544, +3559, +3574, +3590, +3605, +3620, +3635, +3651, +3666, +3682, +3697, +3713, +3729, +3745, +3760, +3776, +3792, +3808, +3824, +3840, +3857, +3873, +3889, +3905, +3922, +3937, +3955, +3972, +3988, +4005, +4022, +4039, +4055, +4073, +4090, +4107, +4124, +4141, +4158, +4176, +4193, +4211, +4228, +4246, +4264, +4282, +4299, +4317, +4335, +4353, +4371, +4390, +4408, +4426, +4444, +4463, +4481, +4500, +4519, +4537, +4556, +4575, +4594, +4613, +4632, +4651, +4670, +4690, +4709, +4728, +4748, +4767, +4787, +4807, +4827, +4846, +4866, +4886, +4906, +4927, +4947, +4967, +4987, +5008, +5028, +5049, +5070, +5090, +5111, +5132, +5153, +5174, +5195, +5216, +5238, +5259, +5280, +5302, +5324, +5345, +5367, +5389, +5411, +5433, +5455, +5477, +5499, +5521, +5544, +5566, +5589, +5611, +5634, +5657, +5680, +5703, +5726, +5749, +5772, +5795, +5819, +5842, +5866, +5889, +5913, +5937, +5961, +5984, +6009, +6033, +6057, +6081, +6106, +6130, +6155, +6179, +6204, +6229, +6254, +6279, +6304, +6329, +6354, +6379, +6405, +6430, +6456, +6482, +6507, +6533, +6559, +6585, +6612, +6638, +6664, +6691, +6717, +6744, +6770, +6797, +6824, +6851, +6878, +6905, +6933, +6960, +6988, +7015, +7043, +7071, +7098, +7126, +7154, +7183, +7211, +7239, +7268, +7296, +7325, +7353, +7382, +7411, +7440, +7469, +7499, +7528, +7557, +7587, +7617, +7646, +7676, +7706, +7736, +7766, +7796, +7827, +7856, +7887, +7919, +7948, +7979, +8011, +8042, +8073, +8104, +8135, +8168, +8199, +8231, +8263, +8295, +8327, +8359, +8391, +8424, +8456, +8489, +8521, +8554, +8587, +8620, +8653, +8687, +8720, +8754, +8787, +8821, +8855, +8889, +8923, +8957, +8991, +9026, +9060, +9095, +9130, +9164, +9199, +9234, +9270, +9305, +9340, +9376, +9412, +9448, +9483, +9520, +9556, +9592, +9628, +9665, +9702, +9738, +9775, +9812, +9849, +9887, +9924, +9961, +9999, +10037, +10075, +10113, +10151, +10189, +10227, +10266, +10305, +10343, +10382, +10421, +10460, +10500, +10539, +10579, +10618, +10658, +10698, +10738, +10778, +10818, +10859, +10899, +10940, +10981, +11022, +11063, +11104, +11146, +11187, +11229, +11270, +11312, +11354, +11397, +11439, +11481, +11524, +11567, +11609, +11652, +11696, +11739, +11782, +11826, +11869, +11913, +11957, +12001, +12046, +12090, +12135, +12179, +12224, +12269, +12314, +12359, +12405, +12450, +12496, +12542, +12588, +12634, +12680, +12726, +12773, +12820, +12867, +12914, +12961, +13008, +13055, +13103, +13151, +13199, +13247, +13295, +13343, +13392, +13440, +13489, +13538, +13587, +13637, +13686, +13736, +13785, +13835, +13885, +13935, +13986, +14036, +14087, +14138, +14189, +14240, +14291, +14343, +14394, +14446, +14498, +14550, +14602, +14655, +14707, +14760, +14813, +14866, +14919, +14972, +15026, +15080, +15134, +15188, +15242, +15296, +15351, +15406, +15460, +15515, +15571, +15626, +15682, +15737, +15793, +15848, +15906, +15962, +16018, +16074, +16132, +16188, +16247, +16303, +16362, +16419, +16477, +16536, +16594, +16652, +16711, +16770, +16829, +16888, +16947, +17007, +17067, +17127, +17187, +17247, +17307, +17368, +17429, +17490, +17551, +17612, +17674, +17736, +17798, +17860, +17922, +17984, +18047, +18110, +18173, +18236, +18300, +18363, +18427, +18491, +18555, +18619, +18684, +18749, +18814, +18879, +18944, +19009, +19075, +19141, +19207, +19273, +19340, +19406, +19473, +19540, +19608, +19675, +19743, +19810, +19878, +19947, +20015, +20084, +20152, +20222, +20291, +20360, +20430, +20500, +20570, +20640, +20710, +20781, +20852, +20923, +20994, +21065, +21137, +21209, +21281, +21353, +21426, +21498, +21571, +21644, +21718, +21791, +21865, +21939, +22013, +22088, +22162, +22237, +22312, +22387, +22463, +22538, +22614, +22690, +22766, +22843, +22920, +22997, +23074, +23151, +23229, +23307, +23385, +23463, +23541, +23620, +23699, +23778, +23857, +23937, +24017, +24097, +24177, +24258, +24338, +24419, +24500, +24582, +24663, +24745, +24827, +24910, +24992, +25075, +25158, +25241, +25324, +25408, +25492, +25576, +25660, +25745, +25830, +25915, +26000, +26086, +26172, +26258, +26344, +26430, +26517, +26604, +26691, +26779, +26866, +26954, +27042, +27131, +27219, +27308, +27397, +27487, +27576, +27666, +27756, +27846, +27937, +28028, +28119, +28210, +28302, +28394, +28486, +28578, +28670, +28763, +28856, +28950, +29043, +29137, +29231, +29325, +29420, +29515, +29610, +29705, +29801, +29896, +29992, +30089, +30185, +30282, +30379, +30477, +30574, +30672, +30770, +30869, +30967, +31066, +31166, +31265, +31364, +31465, +31565, +31665, +31766, +31867, +31968, +32070, +32172, +32273, +32376, +32479, +32582, +32685, +32788, +32892, +32996, +33100, +33205, +33310, +33415, +33520, +33626, +33731, +33838, +33944, +34051, +34158, +34265, +34372, +34480, +34588, +34697, +34805, +34914, +35023, +35133, +35243, +35353, +35463, +35574, +35684, +35796, +35907, +36019, +36131, +36243, +36356, +36469, +36582, +36695, +36809, +36923, +37037, +37152, +37267, +37382, +37497, +37613, +37729, +37846, +37962, +38079, +38196, +38314, +38432, +38550, +38668, +38787, +38906, +39025, +39145, +39265, +39385, +39506, +39626, +39747, +39869, +39990, +40112, +40235, +40357, +40480, +40603, +40727, +40851, +40975, +41099, +41224, +41349, +41474, +41600, +41726, +41852, +41979, +42106, +42233, +42361, +42488, +42617, +42745, +42874, +43003, +43132, +43262, +43392, +43522, +43653, +43784, +43915, +44047, +44179, +44311, +44443, +44576, +44710, +44843, +44977, +45111, +45245, +45380, +45515, +45651, +45787, +45923, +46059, +46196, +46333, +46470, +46608, +46746, +46884, +47023, +47162, +47302, +47441, +47581, +47722, +47862, +48003, +48145, +48286, +48428, +48571, +48713, +48856, +49000, +49143, +49288, +49432, +49577, +49722, +49867, +50013, +50159, +50305, +50452, +50599, +50746, +50894, +51042, +51191, +51339, +51489, +51638, +51788, +51938, +52089, +52239, +52391, +52542, +52694, +52846, +52999, +53152, +53305, +53459, +53613, +53767, +53922, +54077, +54232, +54388, +54544, +54701, +54857, +55015, +55172, +55330, +55488, +55647, +55806, +55965, +56125, +56285, +56445, +56606, +56767, +56929, +57090, +57253, +57415, +57578, +57741, +57905, +58069, +58233, +58398, +58563, +58729, +58895, +59061, +59227, +59394, +59562, +59729, +59897, +60066, +60235, +60404, +60573, +60743, +60914, +61084, +61255, +61427, +61598, +61771, +61943, +62116, +62289, +62463, +62637, +62811, +62986, +63160, +63337, +63513, +63688, +63866, +64043, +64220, +64398, +64575, +64754, +64934, +65113, +65293, +65473, +65654, +65835, +66016, +66198, +66380, +66562, +66745, +66928, +67112, +67296, +67480, +67665, +67850, +68036, +68222, +68408, +68595, +68782, +68969, +69157, +69346, +69534, +69724, +69913, +70103, +70293, +70484, +70675, +70867, +71058, +71251, +71443, +71636, +71830, +72024, +72218, +72413, +72608, +72803, +72999, +73196, +73392, +73589, +73787, +73985, +74183, +74382, +74581, +74781, +74980, +75181, +75382, +75583, +75784, +75986, +76189, +76392, +76595, +76798, +77002, +77207, +77412, +77617, +77823, +78029, +78235, +78442, +78650, +78857, +79066, +79274, +79483, +79693, +79902, +80113, +80323, +80534, +80746, +80958, +81170, +81383, +81596, +81810, +82024, +82238, +82453, +82669, +82884, +83100, +83317, +83534, +83751, +83969, +84188, +84406, +84625, +84845, +85065, +85285, +85506, +85727, +85949, +86171, +86394, +86617, +86840, +87064, +87288, +87513, +87738, +87964, +88190, +88416, +88643, +88870, +89098, +89326, +89555, +89784, +90013, +90243, +90473, +90704, +90935, +91167, +91399, +91632, +91864, +92098, +92332, +92566, +92801, +93036, +93271, +93507, +93744, +93981, +94218, +94456, +94694, +94933, +95172, +95412, +95652, +95892, +96133, +96374, +96616, +96858, +97101, +97344, +97588, +97832, +98076, +98321, +98567, +98812, +99059, +99305, +99552, +99800, +100048, +100297, +100546, +100795, +101045, +101295, +101546, +101797, +102049, +102301, +102553, +102806, +103060, +103314, +103568, +103823, +104078, +104334, +104590, +104847, +105104, +105362, +105620, +105878, +106137, +106396, +106656, +106917, +107177, +107439, +107700, +107962, +108225, +108488, +108752, +109016, +109280, +109545, +109810, +110076, +110342, +110609, +110876, +111144, +111412, +111681, +111950, +112219, +112489, +112760, +113031, +113302, +113574, +113846, +114119, +114392, +114666, +114940, +115215, +115490, +115765, +116041, +116318, +116595, +116872, +117150, +117429, +117707, +117987, +118267, +118547, +118828, +119109, +119390, +119672, +119955, +120238, +120522, +120806, +121090, +121375, +121660, +121946, +122233, +122520, +122807, +123095, +123383, +123672, +123961, +124250, +124541, +124831, +125122, +125414, +125706, +125998, +126290, +126585, +126878, +127173, +127468, +127762, +128059, +128355, +128651, +128950, +129247, +129545, +129843, +130143, +130443, +130743, +131044, +131345, +131646, +131948, +132251, +132554, +132857, +133161, +133466, +133770, +134076, +134382, +134688, +134995, +135302, +135610, +135918, +136227, +136536, +136846, +137156, +137466, +137778, +138089, +138401, +138714, +139027, +139340, +139654, +139969, +140284, +140599, +140915, +141232, +141549, +141866, +142184, +142502, +142821, +143140, +143460, +143780, +144101, +144422, +144744, +145066, +145389, +145712, +146036, +146360, +146684, +147009, +147335, +147661, +147987, +148315, +148642, +148970, +149298, +149627, +149957, +150287, +150617, +150948, +151279, +151611, +151944, +152276, +152610, +152943, +153278, +153612, +153948, +154283, +154620, +154956, +155293, +155631, +155969, +156308, +156647, +156987, +157327, +157667, +158008, +158350, +158692, +159034, +159377, +159721, +160065, +160409, +160754, +161099, +161445, +161792, +162138, +162486, +162834, +163182, +163531, +163880, +164230, +164580, +164931, +165282, +165634, +165986, +166338, +166692, +167045, +167399, +167754, +168109, +168464, +168820, +169177, +169534, +169891, +170249, +170608, +170967, +171326, +171686, +172047, +172407, +172769, +173131, +173493, +173856, +174219, +174583, +174947, +175312, +175677, +176043, +176409, +176775, +177142, +177510, +177878, +178247, +178616, +178985, +179355, +179726, +180097, +180468, +180840, +181213, +181586, +181959, +182333, +182707, +183082, +183457, +183833, +184209, +184586, +184963, +185341, +185719, +186098, +186477, +186856, +187236, +187617, +187998, +188380, +188762, +189144, +189527, +189910, +190294, +190679, +191063, +191449, +191835, +192221, +192608, +192995, +193383, +193771, +194159, +194549, +194938, +195328, +195719, +196110, +196501, +196893, +197286, +197679, +198072, +198466, +198860, +199255, +199650, +200046, +200442, +200839, +201236, +201634, +202032, +202430, +202829, +203229, +203629, +204029, +204430, +204832, +205233, +205636, +206039, +206442, +206846, +207250, +207654, +208059, +208465, +208871, +209278, +209685, +210092, +210500, +210908, +211317, +211727, +212136, +212547, +212957, +213368, +213780, +214192, +214605, +215018, +215431, +215845, +216259, +216674, +217090, +217505, +217922, +218338, +218755, +219173, +219591, +220010, +220429, +220848, +221268, +221688, +222109, +222530, +222952, +223374, +223797, +224220, +224643, +225067, +225492, +225917, +226342, +226768, +227194, +227621, +228048, +228476, +228904, +229332, +229761, +230191, +230620, +231051, +231481, +231913, +232344, +232776, +233209, +233642, +234075, +234509, +234943, +235378, +235813, +236249, +236685, +237122, +237559, +237996, +238434, +238872, +239311, +239750, +240190, +240630, +241070, +241511, +241953, +242394, +242837, +243279, +243722, +244166, +244610, +245054, +245499, +245944, +246390, +246836, +247283, +247730, +248177, +248625, +249073, +249522, +249971, +250421, +250871, +251321, +251772, +252224, +252674, +253127, +253580, +254033, +254486, +254940, +255394, +255849, +256303, +256760, +257216, +257672, +258129, +258585, +259044, +259502, +259961, +260419, +260879, +261338, +261799, +262259, +262720, +263182, +263643, +264106, +264568, +265031, +265495, +265958, +266423, +266887, +267353, +267818, +268284, +268750, +269217, +269684, +270152, +270620, +271088, +271557, +272026, +272495, +272965, +273436, +273906, +274378, +274849, +275321, +275793, +276266, +276739, +277213, +277687, +278161, +278636, +279111, +279587, +280062, +280539, +281015, +281493, +281970, +282448, +282926, +283405, +283884, +284363, +284843, +285323, +285804, +286285, +286766, +287248, +287730, +288212, +288695, +289179, +289662, +290146, +290631, +291115, +291601, +292086, +292572, +293058, +293545, +294032, +294519, +295007, +295495, +295984, +296473, +296962, +297452, +297942, +298432, +298923, +299414, +299905, +300397, +300889, +301382, +301875, +302368, +302862, +303356, +303850, +304345, +304840, +305335, +305831, +306327, +306824, +307320, +307818, +308315, +308813, +309311, +309810, +310309, +310808, +311308, +311808, +312308, +312809, +313310, +313811, +314313, +314815, +315318, +315821, +316324, +316827, +317331, +317835, +318339, +318844, +319349, +319855, +320361, +320867, +321373, +321880, +322387, +322895, +323403, +323911, +324419, +324928, +325437, +325946, +326456, +326966, +327477, +327987, +328498, +329010, +329522, +330034, +330546, +331059, +331572, +332085, +332598, +333112, +333627, +334141, +334656, +335171, +335687, +336202, +336718, +337235, +337752, +338269, +338786, +339304, +339821, +340340, +340858, +341377, +341896, +342416, +342935, +343455, +343976, +344496, +345017, +345538, +346060, +346582, +347104, +347626, +348149, +348672, +349195, +349719, +350242, +350767, +351291, +351816, +352341, +352866, +353391, +353917, +354443, +354969, +355496, +356023, +356550, +357078, +357605, +358133, +358662, +359190, +359719, +360248, +360777, +361307, +361837, +362367, +362897, +363428, +363959, +364490, +365022, +365553, +366085, +366617, +367150, +367683, +368216, +368749, +369282, +369816, +370350, +370884, +371419, +371954, +372489, +373024, +373559, +374095, +374631, +375167, +375704, +376241, +376777, +377315, +377852, +378390, +378928, +379466, +380004, +380543, +381081, +381621, +382160, +382699, +383239, +383779, +384319, +384860, +385400, +385941, +386482, +387023, +387565, +388107, +388649, +389191, +389733, +390276, +390819, +391362, +391905, +392448, +392992, +393536, +394080, +394624, +395169, +395714, +396258, +396804, +397349, +397894, +398440, +398986, +399532, +400078, +400625, +401172, +401718, +402266, +402813, +403360, +403908, +404456, +405004, +405552, +406100, +406649, +407198, +407747, +408296, +408845, +409395, +409944, +410494, +411044, +411594, +412145, +412695, +413246, +413797, +414348, +414899, +415450, +416002, +416554, +417106, +417658, +418210, +418762, +419315, +419867, +420420, +420973, +421526, +422080, +422633, +423187, +423741, +424295, +424849, +425403, +425957, +426512, +427066, +427621, +428176, +428731, +429287, +429842, +430397, +430953, +431509, +432065, +432621, +433177, +433733, +434290, +434846, +435403, +435960, +436517, +437074, +437631, +438189, +438746, +439304, +439861, +440419, +440977, +441535, +442093, +442652, +443210, +443769, +444327, +444886, +445445, +446004, +446563, +447122, +447681, +448241, +448800, +449360, +449919, +450479, +451039, +451599, +452159, +452719, +453280, +453840, +454400, +454961, +455522, +456082, +456643, +457204, +457765, +458326, +458887, +459448, +460010, +460571, +461133, +461694, +462256, +462817, +463379, +463941, +464503, +465065, +465627, +466189, +466751, +467314, +467876, +468438, +469001, +469563, +470126, +470689, +471251, +471814, +472377, +472940, +473503, +474066, +474629, +475192, +475755, +476318, +476881, +477444, +478008, +478571, +479135, +479698, +480261, +480825, +481388, +481952, +482516, +483079, +483643, +484207, +484771, +485334, +485898, +486462, +487026, +487590, +488154, +488718, +489282, +489846, +490410, +490974, +491538, +492102, +492666, +493230, +493794, +494358, +494922, +495487, +496051, +496615, +497179, +497743, +498307, +498872, +499436, +500000, +500000, +500000, +500564, +501128, +501692, +502256, +502820, +503385, +503949, +504513, +505078, +505642, +506206, +506770, +507333, +507897, +508461, +509026, +509590, +510154, +510718, +511282, +511846, +512410, +512974, +513538, +514101, +514665, +515229, +515792, +516356, +516920, +517484, +518047, +518611, +519175, +519738, +520302, +520865, +521429, +521992, +522556, +523119, +523682, +524244, +524808, +525371, +525934, +526497, +527060, +527623, +528186, +528749, +529311, +529874, +530437, +530999, +531562, +532124, +532686, +533249, +533811, +534373, +534935, +535497, +536059, +536621, +537183, +537744, +538306, +538867, +539429, +539990, +540552, +541113, +541674, +542235, +542796, +543357, +543918, +544478, +545039, +545600, +546160, +546720, +547281, +547841, +548401, +548961, +549521, +550081, +550640, +551200, +551759, +552319, +552878, +553437, +553996, +554555, +555114, +555673, +556231, +556790, +557348, +557907, +558465, +559023, +559581, +560139, +560696, +561254, +561811, +562369, +562926, +563483, +564040, +564597, +565154, +565710, +566267, +566823, +567379, +567935, +568491, +569047, +569603, +570158, +570713, +571269, +571824, +572379, +572934, +573488, +574043, +574597, +575151, +575705, +576259, +576813, +577367, +577920, +578474, +579027, +579580, +580133, +580685, +581238, +581790, +582342, +582894, +583446, +583998, +584550, +585101, +585652, +586203, +586754, +587305, +587855, +588406, +588956, +589506, +590056, +590605, +591155, +591704, +592253, +592802, +593351, +593900, +594448, +594996, +595544, +596092, +596640, +597187, +597734, +598282, +598828, +599375, +599922, +600468, +601014, +601560, +602106, +602651, +603196, +603742, +604286, +604831, +605376, +605920, +606464, +607008, +607552, +608095, +608638, +609181, +609724, +610267, +610809, +611351, +611893, +612435, +612977, +613518, +614059, +614600, +615140, +615681, +616221, +616761, +617301, +617840, +618379, +618919, +619457, +619996, +620534, +621072, +621610, +622148, +622685, +623223, +623759, +624296, +624833, +625369, +625905, +626441, +626976, +627511, +628046, +628581, +629116, +629650, +630184, +630718, +631251, +631784, +632317, +632850, +633383, +633915, +634447, +634978, +635510, +636041, +636572, +637103, +637633, +638163, +638693, +639223, +639752, +640281, +640810, +641338, +641867, +642395, +642922, +643450, +643977, +644504, +645031, +645557, +646083, +646609, +647134, +647659, +648184, +648709, +649233, +649758, +650281, +650805, +651328, +651851, +652374, +652896, +653418, +653940, +654462, +654983, +655504, +656024, +656545, +657065, +657584, +658104, +658623, +659142, +659660, +660179, +660696, +661214, +661731, +662248, +662765, +663282, +663798, +664313, +664829, +665344, +665859, +666373, +666888, +667402, +667915, +668428, +668941, +669454, +669966, +670478, +670990, +671502, +672013, +672523, +673034, +673544, +674054, +674563, +675072, +675581, +676089, +676597, +677105, +677613, +678120, +678627, +679133, +679639, +680145, +680651, +681156, +681661, +682165, +682669, +683173, +683676, +684179, +684682, +685185, +685687, +686189, +686690, +687191, +687692, +688192, +688692, +689192, +689691, +690190, +690689, +691187, +691685, +692182, +692680, +693176, +693673, +694169, +694665, +695160, +695655, +696150, +696644, +697138, +697632, +698125, +698618, +699111, +699603, +700095, +700586, +701077, +701568, +702058, +702548, +703038, +703527, +704016, +704505, +704993, +705481, +705968, +706455, +706942, +707428, +707914, +708399, +708885, +709369, +709854, +710338, +710821, +711305, +711788, +712270, +712752, +713234, +713715, +714196, +714677, +715157, +715637, +716116, +716595, +717074, +717552, +718030, +718507, +718985, +719461, +719938, +720413, +720889, +721364, +721839, +722313, +722787, +723261, +723734, +724207, +724679, +725151, +725622, +726094, +726564, +727035, +727505, +727974, +728443, +728912, +729380, +729848, +730316, +730783, +731250, +731716, +732182, +732647, +733113, +733577, +734042, +734505, +734969, +735432, +735894, +736357, +736818, +737280, +737741, +738201, +738662, +739121, +739581, +740039, +740498, +740956, +741414, +741871, +742328, +742784, +743240, +743696, +744151, +744605, +745060, +745514, +745967, +746420, +746873, +747325, +747776, +748228, +748679, +749129, +749579, +750029, +750478, +750927, +751375, +751823, +752270, +752717, +753164, +753610, +754056, +754501, +754946, +755390, +755834, +756278, +756721, +757163, +757606, +758047, +758489, +758930, +759370, +759810, +760250, +760689, +761128, +761566, +762004, +762441, +762878, +763315, +763751, +764187, +764622, +765057, +765491, +765925, +766358, +766791, +767224, +767656, +768087, +768519, +768949, +769380, +769809, +770239, +770668, +771096, +771524, +771952, +772379, +772806, +773232, +773658, +774083, +774508, +774933, +775357, +775780, +776203, +776626, +777048, +777470, +777891, +778312, +778732, +779152, +779571, +779990, +780409, +780827, +781245, +781662, +782078, +782495, +782910, +783326, +783741, +784155, +784569, +784982, +785395, +785808, +786220, +786632, +787043, +787453, +787864, +788273, +788683, +789092, +789500, +789908, +790315, +790722, +791129, +791535, +791941, +792346, +792750, +793154, +793558, +793961, +794364, +794767, +795168, +795570, +795971, +796371, +796771, +797171, +797570, +797968, +798366, +798764, +799161, +799558, +799954, +800350, +800745, +801140, +801534, +801928, +802321, +802714, +803107, +803499, +803890, +804281, +804672, +805062, +805451, +805841, +806229, +806617, +807005, +807392, +807779, +808165, +808551, +808937, +809321, +809706, +810090, +810473, +810856, +811238, +811620, +812002, +812383, +812764, +813144, +813523, +813902, +814281, +814659, +815037, +815414, +815791, +816167, +816543, +816918, +817293, +817667, +818041, +818414, +818787, +819160, +819532, +819903, +820274, +820645, +821015, +821384, +821753, +822122, +822490, +822858, +823225, +823591, +823957, +824323, +824688, +825053, +825417, +825781, +826144, +826507, +826869, +827231, +827593, +827953, +828314, +828674, +829033, +829392, +829751, +830109, +830466, +830823, +831180, +831536, +831891, +832246, +832601, +832955, +833308, +833662, +834014, +834366, +834718, +835069, +835420, +835770, +836120, +836469, +836818, +837166, +837514, +837862, +838208, +838555, +838901, +839246, +839591, +839935, +840279, +840623, +840966, +841308, +841650, +841992, +842333, +842673, +843013, +843353, +843692, +844031, +844369, +844707, +845044, +845380, +845717, +846052, +846388, +846722, +847057, +847390, +847724, +848056, +848389, +848721, +849052, +849383, +849713, +850043, +850373, +850702, +851030, +851358, +851685, +852013, +852339, +852665, +852991, +853316, +853640, +853964, +854288, +854611, +854934, +855256, +855578, +855899, +856220, +856540, +856860, +857179, +857498, +857816, +858134, +858451, +858768, +859085, +859401, +859716, +860031, +860346, +860660, +860973, +861286, +861599, +861911, +862222, +862534, +862844, +863154, +863464, +863773, +864082, +864390, +864698, +865005, +865312, +865618, +865924, +866230, +866534, +866839, +867143, +867446, +867749, +868052, +868354, +868655, +868956, +869257, +869557, +869857, +870156, +870455, +870753, +871050, +871348, +871645, +871941, +872237, +872532, +872827, +873121, +873415, +873709, +874002, +874294, +874586, +874878, +875169, +875459, +875750, +876039, +876328, +876617, +876905, +877193, +877480, +877767, +878054, +878340, +878625, +878910, +879194, +879478, +879762, +880045, +880328, +880610, +880891, +881172, +881453, +881733, +882013, +882293, +882571, +882850, +883128, +883405, +883682, +883959, +884235, +884510, +884785, +885060, +885334, +885608, +885881, +886154, +886426, +886698, +886969, +887240, +887511, +887781, +888050, +888319, +888588, +888856, +889124, +889391, +889658, +889924, +890190, +890455, +890720, +890984, +891248, +891512, +891775, +892038, +892300, +892561, +892823, +893083, +893344, +893604, +893863, +894122, +894380, +894638, +894896, +895153, +895410, +895666, +895922, +896177, +896432, +896686, +896940, +897194, +897447, +897699, +897951, +898203, +898454, +898705, +898955, +899205, +899454, +899703, +899952, +900200, +900448, +900695, +900941, +901188, +901433, +901679, +901924, +902168, +902412, +902656, +902899, +903142, +903384, +903626, +903867, +904108, +904348, +904588, +904828, +905067, +905306, +905544, +905782, +906019, +906256, +906493, +906729, +906964, +907199, +907434, +907668, +907902, +908136, +908368, +908601, +908833, +909065, +909296, +909527, +909757, +909987, +910216, +910445, +910674, +910902, +911130, +911357, +911584, +911810, +912036, +912262, +912487, +912712, +912936, +913160, +913383, +913606, +913829, +914051, +914273, +914494, +914715, +914935, +915155, +915375, +915594, +915812, +916031, +916249, +916466, +916683, +916900, +917116, +917331, +917547, +917762, +917976, +918190, +918404, +918617, +918830, +919042, +919254, +919466, +919677, +919887, +920098, +920307, +920517, +920726, +920934, +921143, +921350, +921558, +921765, +921971, +922177, +922383, +922588, +922793, +922998, +923202, +923405, +923608, +923811, +924014, +924216, +924417, +924618, +924819, +925020, +925219, +925419, +925618, +925817, +926015, +926213, +926411, +926608, +926804, +927001, +927197, +927392, +927587, +927782, +927976, +928170, +928364, +928557, +928749, +928942, +929133, +929325, +929516, +929707, +929897, +930087, +930276, +930466, +930654, +930843, +931031, +931218, +931405, +931592, +931778, +931964, +932150, +932335, +932520, +932704, +932888, +933072, +933255, +933438, +933620, +933802, +933984, +934165, +934346, +934527, +934707, +934887, +935066, +935245, +935424, +935602, +935780, +935957, +936134, +936311, +936487, +936663, +936839, +937014, +937189, +937363, +937537, +937711, +937884, +938057, +938229, +938402, +938573, +938745, +938916, +939086, +939257, +939427, +939596, +939765, +939934, +940103, +940271, +940438, +940606, +940773, +940939, +941105, +941271, +941437, +941602, +941767, +941931, +942095, +942259, +942422, +942585, +942747, +942910, +943071, +943233, +943394, +943555, +943715, +943875, +944035, +944194, +944353, +944512, +944670, +944828, +944985, +945143, +945299, +945456, +945612, +945768, +945923, +946078, +946233, +946387, +946541, +946695, +946848, +947001, +947154, +947306, +947458, +947609, +947761, +947911, +948062, +948212, +948362, +948511, +948661, +948809, +948958, +949106, +949254, +949401, +949548, +949695, +949841, +949987, +950133, +950278, +950423, +950568, +950712, +950857, +951000, +951144, +951287, +951429, +951572, +951714, +951855, +951997, +952138, +952278, +952419, +952559, +952698, +952838, +952977, +953116, +953254, +953392, +953530, +953667, +953804, +953941, +954077, +954213, +954349, +954485, +954620, +954755, +954889, +955023, +955157, +955290, +955424, +955557, +955689, +955821, +955953, +956085, +956216, +956347, +956478, +956608, +956738, +956868, +956997, +957126, +957255, +957383, +957512, +957639, +957767, +957894, +958021, +958148, +958274, +958400, +958526, +958651, +958776, +958901, +959025, +959149, +959273, +959397, +959520, +959643, +959765, +959888, +960010, +960131, +960253, +960374, +960494, +960615, +960735, +960855, +960975, +961094, +961213, +961332, +961450, +961568, +961686, +961804, +961921, +962038, +962154, +962271, +962387, +962503, +962618, +962733, +962848, +962963, +963077, +963191, +963305, +963418, +963531, +963644, +963757, +963869, +963981, +964093, +964204, +964316, +964426, +964537, +964647, +964757, +964867, +964977, +965086, +965195, +965303, +965412, +965520, +965628, +965735, +965842, +965949, +966056, +966162, +966269, +966374, +966480, +966585, +966690, +966795, +966900, +967004, +967108, +967212, +967315, +967418, +967521, +967624, +967726, +967828, +967930, +968032, +968133, +968234, +968335, +968435, +968535, +968635, +968735, +968834, +968934, +969033, +969131, +969230, +969328, +969426, +969523, +969621, +969718, +969815, +969911, +970008, +970104, +970199, +970295, +970390, +970485, +970580, +970675, +970769, +970863, +970957, +971050, +971144, +971237, +971330, +971422, +971514, +971606, +971698, +971790, +971881, +971972, +972063, +972154, +972244, +972334, +972424, +972513, +972603, +972692, +972781, +972869, +972958, +973046, +973134, +973221, +973309, +973396, +973483, +973570, +973656, +973742, +973828, +973914, +974000, +974085, +974170, +974255, +974340, +974424, +974508, +974592, +974676, +974759, +974842, +974925, +975008, +975090, +975173, +975255, +975337, +975418, +975500, +975581, +975662, +975742, +975823, +975903, +975983, +976063, +976143, +976222, +976301, +976380, +976459, +976537, +976615, +976693, +976771, +976849, +976926, +977003, +977080, +977157, +977234, +977310, +977386, +977462, +977537, +977613, +977688, +977763, +977838, +977912, +977987, +978061, +978135, +978209, +978282, +978356, +978429, +978502, +978574, +978647, +978719, +978791, +978863, +978935, +979006, +979077, +979148, +979219, +979290, +979360, +979430, +979500, +979570, +979640, +979709, +979778, +979848, +979916, +979985, +980053, +980122, +980190, +980257, +980325, +980392, +980460, +980527, +980594, +980660, +980727, +980793, +980859, +980925, +980991, +981056, +981121, +981186, +981251, +981316, +981381, +981445, +981509, +981573, +981637, +981700, +981764, +981827, +981890, +981953, +982016, +982078, +982140, +982202, +982264, +982326, +982388, +982449, +982510, +982571, +982632, +982693, +982753, +982813, +982873, +982933, +982993, +983053, +983112, +983171, +983230, +983289, +983348, +983406, +983464, +983523, +983581, +983638, +983696, +983753, +983811, +983868, +983925, +983981, +984038, +984094, +984151, +984207, +984263, +984318, +984374, +984429, +984485, +984540, +984594, +984649, +984704, +984758, +984812, +984866, +984920, +984974, +985028, +985081, +985134, +985187, +985240, +985293, +985345, +985398, +985450, +985502, +985554, +985606, +985657, +985709, +985760, +985811, +985862, +985913, +985964, +986014, +986065, +986115, +986165, +986215, +986264, +986314, +986363, +986413, +986462, +986511, +986560, +986608, +986657, +986705, +986753, +986801, +986849, +986897, +986945, +986992, +987039, +987086, +987133, +987180, +987227, +987274, +987320, +987366, +987412, +987458, +987504, +987550, +987595, +987641, +987686, +987731, +987776, +987821, +987865, +987910, +987954, +987999, +988043, +988087, +988131, +988174, +988218, +988261, +988304, +988348, +988391, +988433, +988476, +988519, +988561, +988603, +988646, +988688, +988730, +988771, +988813, +988854, +988896, +988937, +988978, +989019, +989060, +989101, +989141, +989182, +989222, +989262, +989302, +989342, +989382, +989421, +989461, +989500, +989540, +989579, +989618, +989657, +989695, +989734, +989773, +989811, +989849, +989887, +989925, +989963, +990001, +990039, +990076, +990113, +990151, +990188, +990225, +990262, +990298, +990335, +990372, +990408, +990444, +990480, +990517, +990552, +990588, +990624, +990660, +990695, +990730, +990766, +990801, +990836, +990870, +990905, +990940, +990974, +991009, +991043, +991077, +991111, +991145, +991179, +991213, +991246, +991280, +991313, +991347, +991380, +991413, +991446, +991479, +991511, +991544, +991576, +991609, +991641, +991673, +991705, +991737, +991769, +991801, +991832, +991864, +991895, +991927, +991958, +991989, +992020, +992051, +992081, +992112, +992143, +992173, +992204, +992234, +992264, +992294, +992324, +992354, +992383, +992413, +992443, +992472, +992501, +992531, +992560, +992589, +992618, +992647, +992675, +992704, +992732, +992761, +992789, +992817, +992846, +992874, +992902, +992929, +992957, +992985, +993012, +993040, +993067, +993095, +993122, +993149, +993176, +993203, +993230, +993256, +993283, +993309, +993336, +993362, +993388, +993415, +993441, +993467, +993493, +993518, +993544, +993570, +993595, +993621, +993646, +993671, +993696, +993721, +993746, +993771, +993796, +993821, +993845, +993870, +993894, +993919, +993943, +993967, +993991, +994016, +994039, +994063, +994087, +994111, +994134, +994158, +994181, +994205, +994228, +994251, +994274, +994297, +994320, +994343, +994366, +994389, +994411, +994434, +994456, +994479, +994501, +994523, +994545, +994567, +994589, +994611, +994633, +994655, +994676, +994698, +994720, +994741, +994762, +994784, +994805, +994826, +994847, +994868, +994889, +994910, +994930, +994951, +994972, +994992, +995013, +995033, +995053, +995073, +995094, +995114, +995134, +995154, +995173, +995193, +995213, +995233, +995252, +995272, +995291, +995310, +995330, +995349, +995368, +995387, +995406, +995425, +995444, +995463, +995481, +995500, +995519, +995537, +995556, +995574, +995592, +995610, +995629, +995647, +995665, +995683, +995701, +995718, +995736, +995754, +995772, +995789, +995807, +995824, +995842, +995859, +995876, +995893, +995910, +995927, +995944, +995961, +995978, +995995, +996012, +996028, +996045, +996062, +996078, +996095, +996111, +996127, +996143, +996160, +996176, +996192, +996208, +996224, +996240, +996255, +996271, +996287, +996303, +996318, +996334, +996349, +996365, +996380, +996395, +996410, +996426, +996441, +996456, +996471, +996486, +996501, +996515, +996530, +996545, +996560, +996574, +996589, +996603, +996618, +996632, +996646, +996661, +996675, +996689, +996703, +996717, +996731, +996745, +996759, +996773, +996787, +996801, +996814, +996828, +996841, +996855, +996868, +996882, +996895, +996909, +996922, +996935, +996948, +996961, +996974, +996987, +997000, +997013, +997026, +997039, +997052, +997064, +997077, +997090, +997102, +997115, +997127, +997140, +997152, +997164, +997177, +997189, +997201, +997213, +997225, +997237, +997249, +997261, +997273, +997285, +997297, +997308, +997320, +997332, +997343, +997355, +997367, +997378, +997389, +997401, +997412, +997424, +997435, +997446, +997457, +997468, +997479, +997490, +997501, +997512, +997523, +997534, +997545, +997556, +997566, +997577, +997588, +997598, +997609, +997619, +997630, +997640, +997651, +997661, +997671, +997682, +997692, +997702, +997712, +997722, +997732, +997743, +997752, +997762, +997772, +997782, +997792, +997802, +997812, +997821, +997831, +997841, +997850, +997860, +997869, +997879, +997888, +997898, +997907, +997916, +997926, +997935, +997944, +997953, +997962, +997971, +997980, +997990, +997999, +998007, +998016, +998025, +998034, +998043, +998052, +998060, +998069, +998078, +998086, +998095, +998104, +998112, +998121, +998129, +998137, +998146, +998154, +998163, +998171, +998179, +998187, +998195, +998204, +998212, +998220, +998228, +998236, +998244, +998252, +998260, +998268, +998275, +998283, +998291, +998299, +998307, +998314, +998322, +998330, +998337, +998345, +998352, +998360, +998367, +998375, +998382, +998389, +998397, +998404, +998411, +998419, +998426, +998433, +998440, +998447, +998454, +998462, +998469, +998476, +998483, +998490, +998497, +998503, +998510, +998517, +998524, +998531, +998537, +998544, +998551, +998558, +998564, +998571, +998577, +998584, +998591, +998597, +998603, +998610, +998616, +998623, +998629, +998636, +998642, +998648, +998654, +998661, +998667, +998673, +998679, +998685, +998691, +998697, +998704, +998710, +998716, +998722, +998727, +998733, +998739, +998745, +998751, +998757, +998763, +998768, +998774, +998780, +998786, +998791, +998797, +998803, +998808, +998814, +998819, +998825, +998830, +998836, +998841, +998847, +998852, +998858, +998863, +998868, +998874, +998879, +998884, +998889, +998895, +998900, +998905, +998910, +998915, +998920, +998926, +998931, +998936, +998941, +998946, +998951, +998956, +998961, +998966, +998970, +998975, +998980, +998985, +998990, +998995, +998999, +999004, +999009, +999014, +999018, +999023, +999028, +999032, +999037, +999041, +999046, +999051, +999055, +999060, +999064, +999069, +999073, +999077, +999082, +999086, +999091, +999095, +999099, +999104, +999108, +999112, +999116, +999121, +999125, +999129, +999133, +999137, +999142, +999146, +999150, +999154, +999158, +999162, +999166, +999170, +999174, +999178, +999182, +999186, +999190, +999194, +999198, +999202, +999206, +999209, +999213, +999217, +999221, +999225, +999228, +999232, +999236, +999240, +999243, +999247, +999251, +999254, +999258, +999261, +999265, +999269, +999272, +999276, +999279, +999283, +999286, +999290, +999293, +999297, +999300, +999304, +999307, +999310, +999314, +999317, +999320, +999324, +999327, +999330, +999334, +999337, +999340, +999343, +999347, +999350, +999353, +999356, +999359, +999363, +999366, +999369, +999372, +999375, +999378, +999381, +999384, +999387, +999390, +999393, +999396, +999399, +999402, +999405, +999408, +999411, +999414, +999417, +999420, +999423, +999426, +999428, +999431, +999434, +999437, +999440, +999442, +999445, +999448, +999451, +999453, +999456, +999459, +999462, +999464, +999467, +999470, +999472, +999475, +999478, +999480, +999483, +999485, +999488, +999490, +999493, +999496, +999498, +999501, +999503, +999506, +999508, +999511, +999513, +999515, +999518, +999520, +999523, +999525, +999528, +999530, +999532, +999535, +999537, +999539, +999542, +999544, +999546, +999549, +999551, +999553, +999555, +999558, +999560, +999562, +999564, +999566, +999569, +999571, +999573, +999575, +999577, +999580, +999582, +999584, +999586, +999588, +999590, +999592, +999594, +999596, +999598, +999600, +999602, +999604, +999607, +999609, +999611, +999613, +999615, +999616, +999618, +999620, +999622, +999624, +999626, +999628, +999630, +999632, +999634, +999636, +999638, +999639, +999641, +999643, +999645, +999647, +999649, +999650, +999652, +999654, +999656, +999658, +999659, +999661, +999663, +999665, +999666, +999668, +999670, +999671, +999673, +999675, +999676, +999678, +999680, +999681, +999683, +999685, +999686, +999688, +999690, +999691, +999693, +999694, +999696, +999698, +999699, +999701, +999702, +999704, +999705, +999707, +999708, +999710, +999711, +999713, +999714, +999716, +999717, +999719, +999720, +999722, +999723, +999725, +999726, +999728, +999729, +999730, +999732, +999733, +999735, +999736, +999738, +999739, +999740, +999742, +999743, +999744, +999746, +999747, +999748, +999750, +999751, +999752, +999754, +999755, +999756, +999757, +999759, +999760, +999761, +999763, +999764, +999765, +999766, +999768, +999769, +999770, +999771, +999772, +999774, +999775, +999776, +999777, +999778, +999780, +999781, +999782, +999783, +999784, +999785, +999786, +999788, +999789, +999790, +999791, +999792, +999793, +999794, +999795, +999797, +999798, +999799, +999800, +999801, +999802, +999803, +999804, +999805, +999806, +999807, +999808, +999809, +999810, +999811, +999812, +999813, +999814, +999815, +999816, +999817, +999818, +999819, +999820, +999821, +999822, +999823, +999824, +999825, +999826, +999827, +999828, +999829, +999830, +999831, +999831, +999832, +999833, +999834, +999835, +999836, +999837, +999838, +999839, +999840, +999840, +999841, +999842, +999843, +999844, +999845, +999846, +999846, +999847, +999848, +999849, +999850, +999850, +999851, +999852, +999853, +999854, +999855, +999855, +999856, +999857, +999858, +999858, +999859, +999860, +999861, +999862, +999862, +999863, +999864, +999865, +999865, +999866, +999867, +999867, +999868, +999869, +999870, +999870, +999871, +999872, +999872, +999873, +999874, +999875, +999875, +999876, +999877, +999877, +999878, +999879, +999879, +999880, +999881, +999881, +999882, +999883, +999883, +999884, +999885, +999885, +999886, +999886, +999887, +999888, +999888, +999889, +999890, +999890, +999891, +999891, +999892, +999893, +999893, +999894, +999894, +999895, +999896, +999896, +999897, +999897, +999898, +999898, +999899, +999900, +999900, +999901, +999901, +999902, +999902, +999903, +999903, +999904, +999905, +999905, +999906, +999906, +999907, +999907, +999908, +999908, +999909, +999909, +999910, +999910, +999911, +999911, +999912, +999912, +999913, +999913, +999914, +999914, +999915, +999915, +999916, +999916, +999917, +999917, +999918, +999918, +999918, +999919, +999919, +999920, +999920, +999921, +999921, +999922, +999922, +999923, +999923, +999923, +999924, +999924, +999925, +999925, +999926, +999926, +999926, +999927, +999927, +999928, +999928, +999928, +999929, +999929, +999930, +999930, +999930, +999931, +999931, +999932, +999932, +999932, +999933, +999933, +999934, +999934, +999934, +999935, +999935, +999935, +999936, +999936, +999937, +999937, +999937, +999938, +999938, +999938, +999939, +999939, +999939, +999940, +999940, +999940, +999941, +999941, +999941, +999942, +999942, +999943, +999943, +999943, +999943, +999944, +999944, +999944, +999945, +999945, +999945, +999946, +999946, +999946, +999947, +999947, +999947, +999948, +999948, +999948, +999949, +999949, +999949, +999949, +999950, +999950, +999950, +999951, +999951, +999951, +999951, +999952, +999952, +999952, +999953, +999953, +999953, +999953, +999954, +999954, +999954, +999954, +999955, +999955, +999955, +999956, +999956, +999956, +999956, +999957, +999957, +999957, +999957, +999958, +999958, +999958, +999958, +999959, +999959, +999959, +999959, +999959, +999960, +999960, +999960, +999960, +999961, +999961, +999961, +999961, +999962, +999962, +999962, +999962, +999962, +999963, +999963, +999963, +999963, +999964, +999964, +999964, +999964, +999964, +999965, +999965, +999965, +999965, +999965, +999966, +999966, +999966, +999966, +999967, +999967, +999967, +999967, +999967, +999967, +999968, +999968, +999968, +999968, +999968, +999969, +999969, +999969, +999969, +999969, +999970, +999970, +999970, +999970, +999970, +999970, +999971, +999971, +999971, +999971, +999971, +999972, +999972, +999972, +999972, +999972, +999972, +999972, +999973, +999973, +999973, +999973, +999973, +999973, +999974, +999974, +999974, +999974, +999974, +999974, +999975, +999975, +999975, +999975, +999975, +999975, +999975, +999976, +999976, +999976, +999976, +999976, +999976, +999977, +999977, +999977, +999977, +999977, +999977, +999977, +999977, +999978, +999978, +999978, +999978, +999978, +999978, +999978, +999979, +999979, +999979, +999979, +999979, +999979, +999979, +999979, +999980, +999980, +999980, +999980, +999980, +999980, +999980, +999980, +999981, +999981, +999981, +999981, +999981, +999981, +999981, +999981, +999981, +999982, +999982, +999982, +999982, +999982, +999982, +999982, +999982, +999982, +999983, +999983, +999983, +999983, +999983, +999983, +999983, +999983, +999983, +999984, +999984, +999984, +999984, +999984, +999984, +999984, +999984, +999984, +999984, +999985, +999985, +999985, +999985, +999985, +999985, +999985, +999985, +999985, +999985, +999985, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999986, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999987, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999988, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999989, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999990, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999991, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999992, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999993, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999994, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999995, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999996, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999997, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999998, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +999999, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000, +1000000 diff --git a/rce/rcecalib/dataproc/fit/logx.dat b/rce/rcecalib/dataproc/fit/logx.dat new file mode 100644 index 0000000000000000000000000000000000000000..7541fb46cb7060d8e4e6a9c04e17877db08e09bd --- /dev/null +++ b/rce/rcecalib/dataproc/fit/logx.dat @@ -0,0 +1,7001 @@ +-20.366591f, +-6.551079f, +-5.857933f, +-5.452468f, +-5.164786f, +-4.941642f, +-4.759321f, +-4.605170f, +-4.471639f, +-4.353856f, +-4.248495f, +-4.153185f, +-4.066174f, +-3.986131f, +-3.912023f, +-3.843030f, +-3.778492f, +-3.717867f, +-3.660709f, +-3.606641f, +-3.555348f, +-3.506558f, +-3.460038f, +-3.415586f, +-3.373026f, +-3.332204f, +-3.292984f, +-3.255243f, +-3.218876f, +-3.183784f, +-3.149883f, +-3.117093f, +-3.085344f, +-3.054573f, +-3.024720f, +-2.995732f, +-2.967561f, +-2.940162f, +-2.913494f, +-2.887519f, +-2.862201f, +-2.837508f, +-2.813411f, +-2.789880f, +-2.766891f, +-2.744418f, +-2.722439f, +-2.700933f, +-2.679879f, +-2.659260f, +-2.639057f, +-2.619255f, +-2.599837f, +-2.580788f, +-2.562096f, +-2.543747f, +-2.525729f, +-2.508029f, +-2.490637f, +-2.473543f, +-2.456736f, +-2.440206f, +-2.423946f, +-2.407946f, +-2.392197f, +-2.376693f, +-2.361426f, +-2.346388f, +-2.331573f, +-2.316974f, +-2.302585f, +-2.288400f, +-2.274414f, +-2.260621f, +-2.247015f, +-2.233592f, +-2.220347f, +-2.207275f, +-2.194371f, +-2.181632f, +-2.169054f, +-2.156631f, +-2.144361f, +-2.132240f, +-2.120264f, +-2.108429f, +-2.096733f, +-2.085172f, +-2.073744f, +-2.062444f, +-2.051271f, +-2.040221f, +-2.029292f, +-2.018481f, +-2.007786f, +-1.997203f, +-1.986732f, +-1.976369f, +-1.966113f, +-1.955960f, +-1.945910f, +-1.935960f, +-1.926108f, +-1.916351f, +-1.906689f, +-1.897120f, +-1.887641f, +-1.878251f, +-1.868949f, +-1.859732f, +-1.850600f, +-1.841550f, +-1.832581f, +-1.823693f, +-1.814882f, +-1.806148f, +-1.797490f, +-1.788906f, +-1.780396f, +-1.771957f, +-1.763589f, +-1.755290f, +-1.747059f, +-1.738896f, +-1.730799f, +-1.722767f, +-1.714798f, +-1.706893f, +-1.699050f, +-1.691268f, +-1.683546f, +-1.675883f, +-1.668278f, +-1.660731f, +-1.653241f, +-1.645806f, +-1.638425f, +-1.631099f, +-1.623827f, +-1.616606f, +-1.609438f, +-1.602320f, +-1.595253f, +-1.588236f, +-1.581267f, +-1.574347f, +-1.567474f, +-1.560648f, +-1.553868f, +-1.547134f, +-1.540445f, +-1.533800f, +-1.527200f, +-1.520642f, +-1.514128f, +-1.507655f, +-1.501224f, +-1.494835f, +-1.488485f, +-1.482176f, +-1.475907f, +-1.469676f, +-1.463484f, +-1.457330f, +-1.451214f, +-1.445135f, +-1.439093f, +-1.433087f, +-1.427116f, +-1.421182f, +-1.415282f, +-1.409417f, +-1.403586f, +-1.397789f, +-1.392025f, +-1.386294f, +-1.380596f, +-1.374931f, +-1.369297f, +-1.363695f, +-1.358123f, +-1.352583f, +-1.347074f, +-1.341594f, +-1.336145f, +-1.330725f, +-1.325334f, +-1.319972f, +-1.314638f, +-1.309333f, +-1.304056f, +-1.298807f, +-1.293585f, +-1.288390f, +-1.283222f, +-1.278081f, +-1.272966f, +-1.267877f, +-1.262813f, +-1.257776f, +-1.252763f, +-1.247775f, +-1.242813f, +-1.237874f, +-1.232960f, +-1.228070f, +-1.223204f, +-1.218362f, +-1.213542f, +-1.208746f, +-1.203973f, +-1.199222f, +-1.194494f, +-1.189788f, +-1.185104f, +-1.180442f, +-1.175802f, +-1.171183f, +-1.166585f, +-1.162009f, +-1.157453f, +-1.152918f, +-1.148403f, +-1.143909f, +-1.139434f, +-1.134980f, +-1.130545f, +-1.126130f, +-1.121735f, +-1.117358f, +-1.113001f, +-1.108663f, +-1.104343f, +-1.100042f, +-1.095759f, +-1.091495f, +-1.087249f, +-1.083020f, +-1.078810f, +-1.074617f, +-1.070441f, +-1.066283f, +-1.062143f, +-1.058019f, +-1.053912f, +-1.049822f, +-1.045749f, +-1.041692f, +-1.037652f, +-1.033627f, +-1.029619f, +-1.025627f, +-1.021651f, +-1.017691f, +-1.013746f, +-1.009817f, +-1.005903f, +-1.002004f, +-0.998121f, +-0.994252f, +-0.990399f, +-0.986560f, +-0.982736f, +-0.978926f, +-0.975131f, +-0.971351f, +-0.967584f, +-0.963832f, +-0.960093f, +-0.956369f, +-0.952658f, +-0.948962f, +-0.945278f, +-0.941609f, +-0.937952f, +-0.934309f, +-0.930679f, +-0.927063f, +-0.923459f, +-0.919869f, +-0.916291f, +-0.912726f, +-0.909173f, +-0.905633f, +-0.902106f, +-0.898591f, +-0.895089f, +-0.891598f, +-0.888120f, +-0.884654f, +-0.881199f, +-0.877757f, +-0.874327f, +-0.870908f, +-0.867501f, +-0.864105f, +-0.860721f, +-0.857348f, +-0.853987f, +-0.850637f, +-0.847298f, +-0.843970f, +-0.840653f, +-0.837348f, +-0.834053f, +-0.830769f, +-0.827495f, +-0.824233f, +-0.820981f, +-0.817739f, +-0.814508f, +-0.811287f, +-0.808077f, +-0.804877f, +-0.801687f, +-0.798508f, +-0.795338f, +-0.792179f, +-0.789029f, +-0.785889f, +-0.782759f, +-0.779639f, +-0.776529f, +-0.773428f, +-0.770337f, +-0.767255f, +-0.764183f, +-0.761120f, +-0.758067f, +-0.755023f, +-0.751988f, +-0.748962f, +-0.745945f, +-0.742938f, +-0.739939f, +-0.736950f, +-0.733969f, +-0.730997f, +-0.728034f, +-0.725080f, +-0.722135f, +-0.719198f, +-0.716270f, +-0.713350f, +-0.710439f, +-0.707536f, +-0.704642f, +-0.701756f, +-0.698878f, +-0.696008f, +-0.693147f, +-0.690294f, +-0.687449f, +-0.684612f, +-0.681783f, +-0.678963f, +-0.676150f, +-0.673345f, +-0.670547f, +-0.667758f, +-0.664976f, +-0.662202f, +-0.659436f, +-0.656677f, +-0.653926f, +-0.651183f, +-0.648447f, +-0.645718f, +-0.642997f, +-0.640284f, +-0.637577f, +-0.634878f, +-0.632186f, +-0.629502f, +-0.626825f, +-0.624154f, +-0.621491f, +-0.618835f, +-0.616186f, +-0.613544f, +-0.610909f, +-0.608281f, +-0.605660f, +-0.603045f, +-0.600438f, +-0.597837f, +-0.595243f, +-0.592656f, +-0.590075f, +-0.587501f, +-0.584934f, +-0.582373f, +-0.579818f, +-0.577271f, +-0.574729f, +-0.572195f, +-0.569666f, +-0.567144f, +-0.564628f, +-0.562119f, +-0.559616f, +-0.557119f, +-0.554628f, +-0.552144f, +-0.549665f, +-0.547193f, +-0.544727f, +-0.542267f, +-0.539813f, +-0.537365f, +-0.534923f, +-0.532487f, +-0.530057f, +-0.527633f, +-0.525214f, +-0.522802f, +-0.520395f, +-0.517994f, +-0.515599f, +-0.513209f, +-0.510826f, +-0.508447f, +-0.506075f, +-0.503708f, +-0.501347f, +-0.498991f, +-0.496641f, +-0.494296f, +-0.491957f, +-0.489623f, +-0.487295f, +-0.484972f, +-0.482655f, +-0.480343f, +-0.478036f, +-0.475734f, +-0.473438f, +-0.471147f, +-0.468861f, +-0.466581f, +-0.464306f, +-0.462035f, +-0.459770f, +-0.457511f, +-0.455256f, +-0.453006f, +-0.450761f, +-0.448522f, +-0.446287f, +-0.444057f, +-0.441833f, +-0.439613f, +-0.437398f, +-0.435188f, +-0.432983f, +-0.430783f, +-0.428588f, +-0.426397f, +-0.424211f, +-0.422030f, +-0.419854f, +-0.417682f, +-0.415515f, +-0.413353f, +-0.411196f, +-0.409043f, +-0.406895f, +-0.404751f, +-0.402612f, +-0.400478f, +-0.398348f, +-0.396222f, +-0.394101f, +-0.391985f, +-0.389873f, +-0.387766f, +-0.385662f, +-0.383564f, +-0.381470f, +-0.379380f, +-0.377294f, +-0.375213f, +-0.373136f, +-0.371064f, +-0.368995f, +-0.366931f, +-0.364872f, +-0.362816f, +-0.360765f, +-0.358718f, +-0.356675f, +-0.354636f, +-0.352602f, +-0.350571f, +-0.348545f, +-0.346523f, +-0.344504f, +-0.342490f, +-0.340480f, +-0.338474f, +-0.336472f, +-0.334474f, +-0.332480f, +-0.330490f, +-0.328504f, +-0.326522f, +-0.324544f, +-0.322569f, +-0.320599f, +-0.318632f, +-0.316670f, +-0.314711f, +-0.312756f, +-0.310804f, +-0.308857f, +-0.306913f, +-0.304974f, +-0.303037f, +-0.301105f, +-0.299176f, +-0.297252f, +-0.295330f, +-0.293413f, +-0.291499f, +-0.289589f, +-0.287682f, +-0.285779f, +-0.283880f, +-0.281984f, +-0.280092f, +-0.278203f, +-0.276318f, +-0.274437f, +-0.272559f, +-0.270684f, +-0.268814f, +-0.266946f, +-0.265082f, +-0.263222f, +-0.261365f, +-0.259511f, +-0.257661f, +-0.255814f, +-0.253971f, +-0.252131f, +-0.250295f, +-0.248461f, +-0.246632f, +-0.244805f, +-0.242982f, +-0.241162f, +-0.239346f, +-0.237532f, +-0.235722f, +-0.233916f, +-0.232112f, +-0.230312f, +-0.228515f, +-0.226721f, +-0.224931f, +-0.223144f, +-0.221359f, +-0.219578f, +-0.217801f, +-0.216026f, +-0.214255f, +-0.212486f, +-0.210721f, +-0.208959f, +-0.207200f, +-0.205444f, +-0.203691f, +-0.201941f, +-0.200195f, +-0.198451f, +-0.196710f, +-0.194973f, +-0.193238f, +-0.191506f, +-0.189778f, +-0.188052f, +-0.186330f, +-0.184610f, +-0.182893f, +-0.181179f, +-0.179468f, +-0.177761f, +-0.176056f, +-0.174353f, +-0.172654f, +-0.170958f, +-0.169264f, +-0.167574f, +-0.165886f, +-0.164201f, +-0.162519f, +-0.160840f, +-0.159163f, +-0.157490f, +-0.155819f, +-0.154151f, +-0.152485f, +-0.150823f, +-0.149163f, +-0.147506f, +-0.145852f, +-0.144200f, +-0.142552f, +-0.140905f, +-0.139262f, +-0.137621f, +-0.135983f, +-0.134348f, +-0.132715f, +-0.131085f, +-0.129458f, +-0.127833f, +-0.126211f, +-0.124592f, +-0.122975f, +-0.121361f, +-0.119749f, +-0.118140f, +-0.116534f, +-0.114930f, +-0.113329f, +-0.111730f, +-0.110134f, +-0.108540f, +-0.106949f, +-0.105361f, +-0.103774f, +-0.102191f, +-0.100610f, +-0.099031f, +-0.097455f, +-0.095882f, +-0.094311f, +-0.092742f, +-0.091176f, +-0.089612f, +-0.088051f, +-0.086492f, +-0.084936f, +-0.083382f, +-0.081830f, +-0.080281f, +-0.078734f, +-0.077190f, +-0.075648f, +-0.074108f, +-0.072571f, +-0.071036f, +-0.069503f, +-0.067973f, +-0.066445f, +-0.064920f, +-0.063396f, +-0.061875f, +-0.060357f, +-0.058840f, +-0.057326f, +-0.055815f, +-0.054305f, +-0.052798f, +-0.051293f, +-0.049791f, +-0.048290f, +-0.046792f, +-0.045296f, +-0.043803f, +-0.042311f, +-0.040822f, +-0.039335f, +-0.037850f, +-0.036368f, +-0.034887f, +-0.033409f, +-0.031933f, +-0.030459f, +-0.028988f, +-0.027518f, +-0.026051f, +-0.024585f, +-0.023122f, +-0.021661f, +-0.020203f, +-0.018746f, +-0.017291f, +-0.015839f, +-0.014389f, +-0.012941f, +-0.011494f, +-0.010050f, +-0.008608f, +-0.007168f, +-0.005731f, +-0.004295f, +-0.002861f, +-0.001430f, +0.000000f, +0.001428f, +0.002853f, +0.004277f, +0.005698f, +0.007117f, +0.008535f, +0.009950f, +0.011364f, +0.012775f, +0.014185f, +0.015592f, +0.016998f, +0.018401f, +0.019803f, +0.021202f, +0.022600f, +0.023996f, +0.025389f, +0.026781f, +0.028171f, +0.029559f, +0.030945f, +0.032329f, +0.033711f, +0.035091f, +0.036470f, +0.037846f, +0.039221f, +0.040593f, +0.041964f, +0.043333f, +0.044700f, +0.046065f, +0.047429f, +0.048790f, +0.050150f, +0.051508f, +0.052863f, +0.054218f, +0.055570f, +0.056920f, +0.058269f, +0.059616f, +0.060961f, +0.062304f, +0.063645f, +0.064985f, +0.066323f, +0.067659f, +0.068993f, +0.070325f, +0.071656f, +0.072985f, +0.074312f, +0.075637f, +0.076961f, +0.078283f, +0.079603f, +0.080921f, +0.082238f, +0.083553f, +0.084866f, +0.086178f, +0.087487f, +0.088796f, +0.090102f, +0.091406f, +0.092709f, +0.094011f, +0.095310f, +0.096608f, +0.097904f, +0.099199f, +0.100492f, +0.101783f, +0.103072f, +0.104360f, +0.105646f, +0.106931f, +0.108214f, +0.109495f, +0.110774f, +0.112052f, +0.113329f, +0.114603f, +0.115876f, +0.117148f, +0.118418f, +0.119686f, +0.120953f, +0.122218f, +0.123481f, +0.124743f, +0.126003f, +0.127262f, +0.128519f, +0.129774f, +0.131028f, +0.132281f, +0.133531f, +0.134781f, +0.136028f, +0.137274f, +0.138519f, +0.139762f, +0.141003f, +0.142243f, +0.143482f, +0.144719f, +0.145954f, +0.147188f, +0.148420f, +0.149651f, +0.150880f, +0.152108f, +0.153334f, +0.154559f, +0.155782f, +0.157004f, +0.158224f, +0.159443f, +0.160660f, +0.161876f, +0.163090f, +0.164303f, +0.165514f, +0.166724f, +0.167933f, +0.169140f, +0.170345f, +0.171549f, +0.172752f, +0.173953f, +0.175153f, +0.176351f, +0.177548f, +0.178744f, +0.179938f, +0.181130f, +0.182322f, +0.183511f, +0.184700f, +0.185887f, +0.187072f, +0.188256f, +0.189439f, +0.190620f, +0.191800f, +0.192979f, +0.194156f, +0.195332f, +0.196506f, +0.197679f, +0.198851f, +0.200021f, +0.201190f, +0.202358f, +0.203524f, +0.204689f, +0.205852f, +0.207014f, +0.208175f, +0.209334f, +0.210492f, +0.211649f, +0.212805f, +0.213959f, +0.215111f, +0.216263f, +0.217413f, +0.218562f, +0.219709f, +0.220855f, +0.222000f, +0.223144f, +0.224286f, +0.225427f, +0.226566f, +0.227705f, +0.228842f, +0.229977f, +0.231112f, +0.232245f, +0.233377f, +0.234507f, +0.235637f, +0.236765f, +0.237891f, +0.239017f, +0.240141f, +0.241264f, +0.242386f, +0.243506f, +0.244625f, +0.245743f, +0.246860f, +0.247976f, +0.249090f, +0.250203f, +0.251314f, +0.252425f, +0.253534f, +0.254642f, +0.255749f, +0.256855f, +0.257959f, +0.259062f, +0.260164f, +0.261265f, +0.262364f, +0.263463f, +0.264560f, +0.265656f, +0.266750f, +0.267844f, +0.268936f, +0.270027f, +0.271117f, +0.272206f, +0.273293f, +0.274380f, +0.275465f, +0.276549f, +0.277632f, +0.278713f, +0.279794f, +0.280873f, +0.281951f, +0.283028f, +0.284104f, +0.285179f, +0.286252f, +0.287325f, +0.288396f, +0.289466f, +0.290535f, +0.291603f, +0.292670f, +0.293735f, +0.294800f, +0.295863f, +0.296925f, +0.297986f, +0.299046f, +0.300105f, +0.301162f, +0.302219f, +0.303274f, +0.304328f, +0.305382f, +0.306434f, +0.307485f, +0.308535f, +0.309583f, +0.310631f, +0.311678f, +0.312723f, +0.313767f, +0.314811f, +0.315853f, +0.316894f, +0.317934f, +0.318973f, +0.320011f, +0.321048f, +0.322084f, +0.323118f, +0.324152f, +0.325184f, +0.326216f, +0.327246f, +0.328275f, +0.329304f, +0.330331f, +0.331357f, +0.332382f, +0.333406f, +0.334429f, +0.335451f, +0.336472f, +0.337492f, +0.338511f, +0.339529f, +0.340546f, +0.341561f, +0.342576f, +0.343590f, +0.344602f, +0.345614f, +0.346625f, +0.347634f, +0.348643f, +0.349650f, +0.350657f, +0.351662f, +0.352667f, +0.353670f, +0.354673f, +0.355674f, +0.356675f, +0.357674f, +0.358673f, +0.359670f, +0.360667f, +0.361662f, +0.362657f, +0.363651f, +0.364643f, +0.365635f, +0.366625f, +0.367615f, +0.368604f, +0.369591f, +0.370578f, +0.371564f, +0.372548f, +0.373532f, +0.374515f, +0.375497f, +0.376478f, +0.377457f, +0.378436f, +0.379414f, +0.380391f, +0.381368f, +0.382343f, +0.383317f, +0.384290f, +0.385262f, +0.386234f, +0.387204f, +0.388174f, +0.389142f, +0.390110f, +0.391076f, +0.392042f, +0.393007f, +0.393971f, +0.394934f, +0.395896f, +0.396857f, +0.397817f, +0.398776f, +0.399734f, +0.400692f, +0.401648f, +0.402604f, +0.403559f, +0.404512f, +0.405465f, +0.406417f, +0.407368f, +0.408318f, +0.409267f, +0.410216f, +0.411163f, +0.412110f, +0.413055f, +0.414000f, +0.414944f, +0.415887f, +0.416829f, +0.417770f, +0.418710f, +0.419650f, +0.420588f, +0.421526f, +0.422463f, +0.423399f, +0.424334f, +0.425268f, +0.426201f, +0.427133f, +0.428065f, +0.428996f, +0.429925f, +0.430854f, +0.431782f, +0.432710f, +0.433636f, +0.434561f, +0.435486f, +0.436410f, +0.437333f, +0.438255f, +0.439176f, +0.440097f, +0.441016f, +0.441935f, +0.442853f, +0.443770f, +0.444686f, +0.445601f, +0.446516f, +0.447429f, +0.448342f, +0.449254f, +0.450165f, +0.451076f, +0.451985f, +0.452894f, +0.453802f, +0.454709f, +0.455615f, +0.456520f, +0.457425f, +0.458329f, +0.459232f, +0.460134f, +0.461035f, +0.461935f, +0.462835f, +0.463734f, +0.464632f, +0.465529f, +0.466426f, +0.467321f, +0.468216f, +0.469110f, +0.470004f, +0.470896f, +0.471788f, +0.472679f, +0.473569f, +0.474458f, +0.475346f, +0.476234f, +0.477121f, +0.478007f, +0.478893f, +0.479777f, +0.480661f, +0.481544f, +0.482426f, +0.483308f, +0.484188f, +0.485068f, +0.485947f, +0.486826f, +0.487703f, +0.488580f, +0.489456f, +0.490331f, +0.491206f, +0.492080f, +0.492953f, +0.493825f, +0.494696f, +0.495567f, +0.496437f, +0.497306f, +0.498175f, +0.499042f, +0.499909f, +0.500775f, +0.501641f, +0.502505f, +0.503369f, +0.504233f, +0.505095f, +0.505957f, +0.506818f, +0.507678f, +0.508537f, +0.509396f, +0.510254f, +0.511111f, +0.511968f, +0.512824f, +0.513679f, +0.514533f, +0.515387f, +0.516240f, +0.517092f, +0.517943f, +0.518794f, +0.519644f, +0.520493f, +0.521342f, +0.522189f, +0.523036f, +0.523883f, +0.524729f, +0.525573f, +0.526418f, +0.527261f, +0.528104f, +0.528946f, +0.529788f, +0.530628f, +0.531468f, +0.532308f, +0.533146f, +0.533984f, +0.534821f, +0.535658f, +0.536493f, +0.537328f, +0.538163f, +0.538997f, +0.539829f, +0.540662f, +0.541493f, +0.542324f, +0.543155f, +0.543984f, +0.544813f, +0.545641f, +0.546469f, +0.547295f, +0.548121f, +0.548947f, +0.549772f, +0.550596f, +0.551419f, +0.552242f, +0.553064f, +0.553885f, +0.554706f, +0.555526f, +0.556345f, +0.557164f, +0.557982f, +0.558799f, +0.559616f, +0.560432f, +0.561247f, +0.562062f, +0.562876f, +0.563689f, +0.564502f, +0.565314f, +0.566125f, +0.566936f, +0.567746f, +0.568555f, +0.569364f, +0.570172f, +0.570980f, +0.571786f, +0.572592f, +0.573398f, +0.574203f, +0.575007f, +0.575810f, +0.576613f, +0.577416f, +0.578217f, +0.579018f, +0.579818f, +0.580618f, +0.581417f, +0.582216f, +0.583013f, +0.583811f, +0.584607f, +0.585403f, +0.586198f, +0.586993f, +0.587787f, +0.588580f, +0.589373f, +0.590165f, +0.590956f, +0.591747f, +0.592537f, +0.593327f, +0.594116f, +0.594904f, +0.595692f, +0.596479f, +0.597265f, +0.598051f, +0.598837f, +0.599621f, +0.600405f, +0.601189f, +0.601971f, +0.602753f, +0.603535f, +0.604316f, +0.605096f, +0.605876f, +0.606655f, +0.607434f, +0.608212f, +0.608989f, +0.609766f, +0.610542f, +0.611317f, +0.612092f, +0.612866f, +0.613640f, +0.614413f, +0.615186f, +0.615958f, +0.616729f, +0.617500f, +0.618270f, +0.619039f, +0.619808f, +0.620576f, +0.621344f, +0.622111f, +0.622878f, +0.623644f, +0.624409f, +0.625174f, +0.625938f, +0.626702f, +0.627465f, +0.628228f, +0.628990f, +0.629751f, +0.630512f, +0.631272f, +0.632031f, +0.632790f, +0.633549f, +0.634307f, +0.635064f, +0.635821f, +0.636577f, +0.637332f, +0.638087f, +0.638842f, +0.639596f, +0.640349f, +0.641102f, +0.641854f, +0.642605f, +0.643357f, +0.644107f, +0.644857f, +0.645606f, +0.646355f, +0.647103f, +0.647851f, +0.648598f, +0.649345f, +0.650091f, +0.650836f, +0.651581f, +0.652325f, +0.653069f, +0.653812f, +0.654555f, +0.655297f, +0.656039f, +0.656780f, +0.657520f, +0.658260f, +0.658999f, +0.659738f, +0.660476f, +0.661214f, +0.661951f, +0.662688f, +0.663424f, +0.664160f, +0.664895f, +0.665629f, +0.666363f, +0.667097f, +0.667829f, +0.668562f, +0.669294f, +0.670025f, +0.670755f, +0.671486f, +0.672215f, +0.672944f, +0.673673f, +0.674401f, +0.675129f, +0.675856f, +0.676582f, +0.677308f, +0.678034f, +0.678758f, +0.679483f, +0.680207f, +0.680930f, +0.681653f, +0.682375f, +0.683097f, +0.683818f, +0.684539f, +0.685259f, +0.685979f, +0.686698f, +0.687417f, +0.688135f, +0.688852f, +0.689569f, +0.690286f, +0.691002f, +0.691718f, +0.692433f, +0.693147f, +0.693861f, +0.694575f, +0.695288f, +0.696000f, +0.696712f, +0.697424f, +0.698135f, +0.698845f, +0.699555f, +0.700265f, +0.700974f, +0.701682f, +0.702390f, +0.703098f, +0.703804f, +0.704511f, +0.705217f, +0.705922f, +0.706627f, +0.707332f, +0.708036f, +0.708739f, +0.709442f, +0.710145f, +0.710847f, +0.711548f, +0.712249f, +0.712950f, +0.713650f, +0.714349f, +0.715048f, +0.715747f, +0.716445f, +0.717143f, +0.717840f, +0.718536f, +0.719233f, +0.719928f, +0.720623f, +0.721318f, +0.722012f, +0.722706f, +0.723399f, +0.724092f, +0.724784f, +0.725476f, +0.726167f, +0.726858f, +0.727549f, +0.728239f, +0.728928f, +0.729617f, +0.730305f, +0.730993f, +0.731681f, +0.732368f, +0.733054f, +0.733741f, +0.734426f, +0.735111f, +0.735796f, +0.736480f, +0.737164f, +0.737847f, +0.738530f, +0.739213f, +0.739894f, +0.740576f, +0.741257f, +0.741937f, +0.742617f, +0.743297f, +0.743976f, +0.744655f, +0.745333f, +0.746011f, +0.746688f, +0.747365f, +0.748041f, +0.748717f, +0.749392f, +0.750067f, +0.750742f, +0.751416f, +0.752090f, +0.752763f, +0.753436f, +0.754108f, +0.754780f, +0.755451f, +0.756122f, +0.756792f, +0.757462f, +0.758132f, +0.758801f, +0.759470f, +0.760138f, +0.760806f, +0.761473f, +0.762140f, +0.762806f, +0.763472f, +0.764138f, +0.764803f, +0.765468f, +0.766132f, +0.766796f, +0.767459f, +0.768122f, +0.768785f, +0.769447f, +0.770108f, +0.770769f, +0.771430f, +0.772090f, +0.772750f, +0.773410f, +0.774069f, +0.774727f, +0.775385f, +0.776043f, +0.776700f, +0.777357f, +0.778013f, +0.778669f, +0.779325f, +0.779980f, +0.780635f, +0.781289f, +0.781943f, +0.782596f, +0.783249f, +0.783902f, +0.784554f, +0.785205f, +0.785857f, +0.786507f, +0.787158f, +0.787808f, +0.788457f, +0.789107f, +0.789755f, +0.790404f, +0.791051f, +0.791699f, +0.792346f, +0.792993f, +0.793639f, +0.794285f, +0.794930f, +0.795575f, +0.796219f, +0.796863f, +0.797507f, +0.798150f, +0.798793f, +0.799436f, +0.800078f, +0.800720f, +0.801361f, +0.802002f, +0.802642f, +0.803282f, +0.803922f, +0.804561f, +0.805200f, +0.805838f, +0.806476f, +0.807113f, +0.807751f, +0.808387f, +0.809024f, +0.809660f, +0.810295f, +0.810930f, +0.811565f, +0.812199f, +0.812833f, +0.813467f, +0.814100f, +0.814733f, +0.815365f, +0.815997f, +0.816628f, +0.817259f, +0.817890f, +0.818520f, +0.819150f, +0.819780f, +0.820409f, +0.821038f, +0.821666f, +0.822294f, +0.822922f, +0.823549f, +0.824175f, +0.824802f, +0.825428f, +0.826053f, +0.826679f, +0.827303f, +0.827928f, +0.828552f, +0.829175f, +0.829799f, +0.830422f, +0.831044f, +0.831666f, +0.832288f, +0.832909f, +0.833530f, +0.834151f, +0.834771f, +0.835391f, +0.836010f, +0.836629f, +0.837248f, +0.837866f, +0.838484f, +0.839101f, +0.839718f, +0.840335f, +0.840951f, +0.841567f, +0.842183f, +0.842798f, +0.843413f, +0.844027f, +0.844641f, +0.845255f, +0.845868f, +0.846481f, +0.847094f, +0.847706f, +0.848318f, +0.848929f, +0.849540f, +0.850151f, +0.850761f, +0.851371f, +0.851981f, +0.852590f, +0.853199f, +0.853807f, +0.854415f, +0.855023f, +0.855630f, +0.856237f, +0.856844f, +0.857450f, +0.858056f, +0.858662f, +0.859267f, +0.859872f, +0.860476f, +0.861080f, +0.861684f, +0.862287f, +0.862890f, +0.863493f, +0.864095f, +0.864697f, +0.865298f, +0.865899f, +0.866500f, +0.867100f, +0.867701f, +0.868300f, +0.868900f, +0.869499f, +0.870097f, +0.870695f, +0.871293f, +0.871891f, +0.872488f, +0.873085f, +0.873681f, +0.874278f, +0.874873f, +0.875469f, +0.876064f, +0.876659f, +0.877253f, +0.877847f, +0.878441f, +0.879034f, +0.879627f, +0.880219f, +0.880812f, +0.881403f, +0.881995f, +0.882586f, +0.883177f, +0.883768f, +0.884358f, +0.884947f, +0.885537f, +0.886126f, +0.886715f, +0.887303f, +0.887891f, +0.888479f, +0.889066f, +0.889653f, +0.890240f, +0.890826f, +0.891412f, +0.891998f, +0.892583f, +0.893168f, +0.893753f, +0.894337f, +0.894921f, +0.895505f, +0.896088f, +0.896671f, +0.897254f, +0.897836f, +0.898418f, +0.898999f, +0.899580f, +0.900161f, +0.900742f, +0.901322f, +0.901902f, +0.902482f, +0.903061f, +0.903640f, +0.904218f, +0.904796f, +0.905374f, +0.905952f, +0.906529f, +0.907106f, +0.907682f, +0.908259f, +0.908834f, +0.909410f, +0.909985f, +0.910560f, +0.911135f, +0.911709f, +0.912283f, +0.912856f, +0.913430f, +0.914002f, +0.914575f, +0.915147f, +0.915719f, +0.916291f, +0.916862f, +0.917433f, +0.918004f, +0.918574f, +0.919144f, +0.919713f, +0.920283f, +0.920852f, +0.921420f, +0.921989f, +0.922557f, +0.923124f, +0.923692f, +0.924259f, +0.924826f, +0.925392f, +0.925958f, +0.926524f, +0.927089f, +0.927654f, +0.928219f, +0.928784f, +0.929348f, +0.929912f, +0.930475f, +0.931039f, +0.931601f, +0.932164f, +0.932726f, +0.933288f, +0.933850f, +0.934411f, +0.934972f, +0.935533f, +0.936093f, +0.936653f, +0.937213f, +0.937773f, +0.938332f, +0.938891f, +0.939449f, +0.940007f, +0.940565f, +0.941123f, +0.941680f, +0.942237f, +0.942794f, +0.943350f, +0.943906f, +0.944462f, +0.945017f, +0.945572f, +0.946127f, +0.946681f, +0.947236f, +0.947789f, +0.948343f, +0.948896f, +0.949449f, +0.950002f, +0.950554f, +0.951106f, +0.951658f, +0.952209f, +0.952760f, +0.953311f, +0.953862f, +0.954412f, +0.954962f, +0.955511f, +0.956061f, +0.956610f, +0.957158f, +0.957707f, +0.958255f, +0.958803f, +0.959350f, +0.959897f, +0.960444f, +0.960991f, +0.961537f, +0.962083f, +0.962629f, +0.963174f, +0.963719f, +0.964264f, +0.964809f, +0.965353f, +0.965897f, +0.966441f, +0.966984f, +0.967527f, +0.968070f, +0.968612f, +0.969154f, +0.969696f, +0.970238f, +0.970779f, +0.971320f, +0.971861f, +0.972401f, +0.972941f, +0.973481f, +0.974020f, +0.974560f, +0.975099f, +0.975637f, +0.976176f, +0.976714f, +0.977251f, +0.977789f, +0.978326f, +0.978863f, +0.979400f, +0.979936f, +0.980472f, +0.981008f, +0.981543f, +0.982078f, +0.982613f, +0.983148f, +0.983682f, +0.984216f, +0.984750f, +0.985284f, +0.985817f, +0.986350f, +0.986882f, +0.987415f, +0.987947f, +0.988478f, +0.989010f, +0.989541f, +0.990072f, +0.990603f, +0.991133f, +0.991663f, +0.992193f, +0.992723f, +0.993252f, +0.993781f, +0.994309f, +0.994838f, +0.995366f, +0.995894f, +0.996421f, +0.996949f, +0.997476f, +0.998002f, +0.998529f, +0.999055f, +0.999581f, +1.000107f, +1.000632f, +1.001157f, +1.001682f, +1.002206f, +1.002731f, +1.003254f, +1.003778f, +1.004302f, +1.004825f, +1.005348f, +1.005870f, +1.006393f, +1.006915f, +1.007436f, +1.007958f, +1.008479f, +1.009000f, +1.009521f, +1.010041f, +1.010561f, +1.011081f, +1.011601f, +1.012120f, +1.012639f, +1.013158f, +1.013677f, +1.014195f, +1.014713f, +1.015231f, +1.015748f, +1.016265f, +1.016782f, +1.017299f, +1.017815f, +1.018331f, +1.018847f, +1.019363f, +1.019878f, +1.020393f, +1.020908f, +1.021423f, +1.021937f, +1.022451f, +1.022965f, +1.023478f, +1.023991f, +1.024504f, +1.025017f, +1.025529f, +1.026042f, +1.026553f, +1.027065f, +1.027577f, +1.028088f, +1.028598f, +1.029109f, +1.029619f, +1.030129f, +1.030639f, +1.031149f, +1.031658f, +1.032167f, +1.032676f, +1.033184f, +1.033693f, +1.034201f, +1.034708f, +1.035216f, +1.035723f, +1.036230f, +1.036737f, +1.037243f, +1.037750f, +1.038255f, +1.038761f, +1.039267f, +1.039772f, +1.040277f, +1.040781f, +1.041286f, +1.041790f, +1.042294f, +1.042798f, +1.043301f, +1.043804f, +1.044307f, +1.044810f, +1.045312f, +1.045814f, +1.046316f, +1.046818f, +1.047319f, +1.047820f, +1.048321f, +1.048822f, +1.049322f, +1.049822f, +1.050322f, +1.050822f, +1.051321f, +1.051820f, +1.052319f, +1.052818f, +1.053316f, +1.053814f, +1.054312f, +1.054810f, +1.055307f, +1.055804f, +1.056301f, +1.056798f, +1.057294f, +1.057790f, +1.058286f, +1.058782f, +1.059277f, +1.059772f, +1.060267f, +1.060762f, +1.061257f, +1.061751f, +1.062245f, +1.062738f, +1.063232f, +1.063725f, +1.064218f, +1.064711f, +1.065203f, +1.065695f, +1.066187f, +1.066679f, +1.067171f, +1.067662f, +1.068153f, +1.068644f, +1.069134f, +1.069625f, +1.070115f, +1.070605f, +1.071094f, +1.071584f, +1.072073f, +1.072562f, +1.073050f, +1.073539f, +1.074027f, +1.074515f, +1.075002f, +1.075490f, +1.075977f, +1.076464f, +1.076951f, +1.077437f, +1.077924f, +1.078410f, +1.078895f, +1.079381f, +1.079866f, +1.080351f, +1.080836f, +1.081321f, +1.081805f, +1.082289f, +1.082773f, +1.083257f, +1.083740f, +1.084224f, +1.084707f, +1.085189f, +1.085672f, +1.086154f, +1.086636f, +1.087118f, +1.087599f, +1.088081f, +1.088562f, +1.089043f, +1.089523f, +1.090004f, +1.090484f, +1.090964f, +1.091444f, +1.091923f, +1.092403f, +1.092882f, +1.093360f, +1.093839f, +1.094317f, +1.094795f, +1.095273f, +1.095751f, +1.096228f, +1.096706f, +1.097183f, +1.097659f, +1.098136f, +1.098612f, +1.099088f, +1.099564f, +1.100040f, +1.100515f, +1.100990f, +1.101465f, +1.101940f, +1.102415f, +1.102889f, +1.103363f, +1.103837f, +1.104310f, +1.104784f, +1.105257f, +1.105730f, +1.106202f, +1.106675f, +1.107147f, +1.107619f, +1.108091f, +1.108563f, +1.109034f, +1.109505f, +1.109976f, +1.110447f, +1.110917f, +1.111387f, +1.111858f, +1.112327f, +1.112797f, +1.113266f, +1.113735f, +1.114204f, +1.114673f, +1.115142f, +1.115610f, +1.116078f, +1.116546f, +1.117013f, +1.117481f, +1.117948f, +1.118415f, +1.118882f, +1.119348f, +1.119814f, +1.120281f, +1.120746f, +1.121212f, +1.121678f, +1.122143f, +1.122608f, +1.123073f, +1.123537f, +1.124002f, +1.124466f, +1.124930f, +1.125393f, +1.125857f, +1.126320f, +1.126783f, +1.127246f, +1.127709f, +1.128171f, +1.128633f, +1.129095f, +1.129557f, +1.130019f, +1.130480f, +1.130941f, +1.131402f, +1.131863f, +1.132323f, +1.132784f, +1.133244f, +1.133704f, +1.134163f, +1.134623f, +1.135082f, +1.135541f, +1.136000f, +1.136458f, +1.136917f, +1.137375f, +1.137833f, +1.138291f, +1.138748f, +1.139206f, +1.139663f, +1.140120f, +1.140576f, +1.141033f, +1.141489f, +1.141945f, +1.142401f, +1.142857f, +1.143312f, +1.143768f, +1.144223f, +1.144678f, +1.145132f, +1.145587f, +1.146041f, +1.146495f, +1.146949f, +1.147402f, +1.147856f, +1.148309f, +1.148762f, +1.149215f, +1.149667f, +1.150120f, +1.150572f, +1.151024f, +1.151476f, +1.151927f, +1.152379f, +1.152830f, +1.153281f, +1.153732f, +1.154182f, +1.154632f, +1.155083f, +1.155533f, +1.155982f, +1.156432f, +1.156881f, +1.157330f, +1.157779f, +1.158228f, +1.158677f, +1.159125f, +1.159573f, +1.160021f, +1.160469f, +1.160916f, +1.161363f, +1.161811f, +1.162258f, +1.162704f, +1.163151f, +1.163597f, +1.164043f, +1.164489f, +1.164935f, +1.165380f, +1.165826f, +1.166271f, +1.166716f, +1.167161f, +1.167605f, +1.168050f, +1.168494f, +1.168938f, +1.169381f, +1.169825f, +1.170268f, +1.170711f, +1.171154f, +1.171597f, +1.172040f, +1.172482f, +1.172924f, +1.173366f, +1.173808f, +1.174250f, +1.174691f, +1.175132f, +1.175573f, +1.176014f, +1.176455f, +1.176895f, +1.177335f, +1.177775f, +1.178215f, +1.178655f, +1.179094f, +1.179534f, +1.179973f, +1.180412f, +1.180850f, +1.181289f, +1.181727f, +1.182165f, +1.182603f, +1.183041f, +1.183479f, +1.183916f, +1.184353f, +1.184790f, +1.185227f, +1.185663f, +1.186100f, +1.186536f, +1.186972f, +1.187408f, +1.187843f, +1.188279f, +1.188714f, +1.189149f, +1.189584f, +1.190019f, +1.190453f, +1.190888f, +1.191322f, +1.191756f, +1.192189f, +1.192623f, +1.193056f, +1.193489f, +1.193922f, +1.194355f, +1.194788f, +1.195220f, +1.195653f, +1.196085f, +1.196517f, +1.196948f, +1.197380f, +1.197811f, +1.198242f, +1.198673f, +1.199104f, +1.199534f, +1.199965f, +1.200395f, +1.200825f, +1.201255f, +1.201684f, +1.202114f, +1.202543f, +1.202972f, +1.203401f, +1.203830f, +1.204258f, +1.204687f, +1.205115f, +1.205543f, +1.205971f, +1.206398f, +1.206826f, +1.207253f, +1.207680f, +1.208107f, +1.208534f, +1.208960f, +1.209387f, +1.209813f, +1.210239f, +1.210665f, +1.211090f, +1.211516f, +1.211941f, +1.212366f, +1.212791f, +1.213216f, +1.213640f, +1.214065f, +1.214489f, +1.214913f, +1.215337f, +1.215760f, +1.216184f, +1.216607f, +1.217030f, +1.217453f, +1.217876f, +1.218298f, +1.218721f, +1.219143f, +1.219565f, +1.219987f, +1.220408f, +1.220830f, +1.221251f, +1.221672f, +1.222093f, +1.222514f, +1.222935f, +1.223355f, +1.223775f, +1.224196f, +1.224615f, +1.225035f, +1.225455f, +1.225874f, +1.226293f, +1.226712f, +1.227131f, +1.227550f, +1.227968f, +1.228387f, +1.228805f, +1.229223f, +1.229641f, +1.230058f, +1.230476f, +1.230893f, +1.231310f, +1.231727f, +1.232144f, +1.232560f, +1.232977f, +1.233393f, +1.233809f, +1.234225f, +1.234641f, +1.235056f, +1.235471f, +1.235887f, +1.236302f, +1.236717f, +1.237131f, +1.237546f, +1.237960f, +1.238374f, +1.238788f, +1.239202f, +1.239616f, +1.240029f, +1.240442f, +1.240856f, +1.241269f, +1.241681f, +1.242094f, +1.242506f, +1.242919f, +1.243331f, +1.243743f, +1.244155f, +1.244566f, +1.244978f, +1.245389f, +1.245800f, +1.246211f, +1.246622f, +1.247032f, +1.247443f, +1.247853f, +1.248263f, +1.248673f, +1.249083f, +1.249492f, +1.249902f, +1.250311f, +1.250720f, +1.251129f, +1.251538f, +1.251946f, +1.252355f, +1.252763f, +1.253171f, +1.253579f, +1.253987f, +1.254394f, +1.254802f, +1.255209f, +1.255616f, +1.256023f, +1.256430f, +1.256836f, +1.257243f, +1.257649f, +1.258055f, +1.258461f, +1.258867f, +1.259272f, +1.259678f, +1.260083f, +1.260488f, +1.260893f, +1.261298f, +1.261702f, +1.262107f, +1.262511f, +1.262915f, +1.263319f, +1.263723f, +1.264127f, +1.264530f, +1.264934f, +1.265337f, +1.265740f, +1.266142f, +1.266545f, +1.266948f, +1.267350f, +1.267752f, +1.268154f, +1.268556f, +1.268958f, +1.269359f, +1.269761f, +1.270162f, +1.270563f, +1.270964f, +1.271364f, +1.271765f, +1.272165f, +1.272566f, +1.272966f, +1.273366f, +1.273765f, +1.274165f, +1.274564f, +1.274964f, +1.275363f, +1.275762f, +1.276161f, +1.276559f, +1.276958f, +1.277356f, +1.277754f, +1.278152f, +1.278550f, +1.278948f, +1.279345f, +1.279743f, +1.280140f, +1.280537f, +1.280934f, +1.281331f, +1.281727f, +1.282124f, +1.282520f, +1.282916f, +1.283312f, +1.283708f, +1.284103f, +1.284499f, +1.284894f, +1.285289f, +1.285684f, +1.286079f, +1.286474f, +1.286869f, +1.287263f, +1.287657f, +1.288051f, +1.288445f, +1.288839f, +1.289233f, +1.289626f, +1.290019f, +1.290413f, +1.290806f, +1.291198f, +1.291591f, +1.291984f, +1.292376f, +1.292768f, +1.293160f, +1.293552f, +1.293944f, +1.294336f, +1.294727f, +1.295118f, +1.295510f, +1.295901f, +1.296292f, +1.296682f, +1.297073f, +1.297463f, +1.297853f, +1.298243f, +1.298633f, +1.299023f, +1.299413f, +1.299802f, +1.300192f, +1.300581f, +1.300970f, +1.301359f, +1.301747f, +1.302136f, +1.302524f, +1.302913f, +1.303301f, +1.303689f, +1.304077f, +1.304464f, +1.304852f, +1.305239f, +1.305626f, +1.306014f, +1.306400f, +1.306787f, +1.307174f, +1.307560f, +1.307947f, +1.308333f, +1.308719f, +1.309105f, +1.309490f, +1.309876f, +1.310261f, +1.310647f, +1.311032f, +1.311417f, +1.311802f, +1.312186f, +1.312571f, +1.312955f, +1.313340f, +1.313724f, +1.314108f, +1.314491f, +1.314875f, +1.315259f, +1.315642f, +1.316025f, +1.316408f, +1.316791f, +1.317174f, +1.317557f, +1.317939f, +1.318321f, +1.318704f, +1.319086f, +1.319468f, +1.319849f, +1.320231f, +1.320612f, +1.320994f, +1.321375f, +1.321756f, +1.322137f, +1.322517f, +1.322898f, +1.323278f, +1.323659f, +1.324039f, +1.324419f, +1.324799f, +1.325179f, +1.325558f, +1.325938f, +1.326317f, +1.326696f, +1.327075f, +1.327454f, +1.327833f, +1.328211f, +1.328590f, +1.328968f, +1.329346f, +1.329724f, +1.330102f, +1.330480f, +1.330857f, +1.331235f, +1.331612f, +1.331989f, +1.332366f, +1.332743f, +1.333120f, +1.333496f, +1.333873f, +1.334249f, +1.334625f, +1.335001f, +1.335377f, +1.335753f, +1.336128f, +1.336504f, +1.336879f, +1.337254f, +1.337629f, +1.338004f, +1.338379f, +1.338753f, +1.339128f, +1.339502f, +1.339876f, +1.340250f, +1.340624f, +1.340998f, +1.341372f, +1.341745f, +1.342119f, +1.342492f, +1.342865f, +1.343238f, +1.343611f, +1.343983f, +1.344356f, +1.344728f, +1.345100f, +1.345472f, +1.345844f, +1.346216f, +1.346588f, +1.346959f, +1.347331f, +1.347702f, +1.348073f, +1.348444f, +1.348815f, +1.349186f, +1.349556f, +1.349927f, +1.350297f, +1.350667f, +1.351037f, +1.351407f, +1.351777f, +1.352146f, +1.352516f, +1.352885f, +1.353255f, +1.353624f, +1.353993f, +1.354361f, +1.354730f, +1.355099f, +1.355467f, +1.355835f, +1.356203f, +1.356571f, +1.356939f, +1.357307f, +1.357674f, +1.358042f, +1.358409f, +1.358776f, +1.359143f, +1.359510f, +1.359877f, +1.360244f, +1.360610f, +1.360977f, +1.361343f, +1.361709f, +1.362075f, +1.362441f, +1.362806f, +1.363172f, +1.363537f, +1.363903f, +1.364268f, +1.364633f, +1.364998f, +1.365363f, +1.365727f, +1.366092f, +1.366456f, +1.366820f, +1.367184f, +1.367548f, +1.367912f, +1.368276f, +1.368639f, +1.369003f, +1.369366f, +1.369729f, +1.370092f, +1.370455f, +1.370818f, +1.371181f, +1.371543f, +1.371906f, +1.372268f, +1.372630f, +1.372992f, +1.373354f, +1.373716f, +1.374077f, +1.374439f, +1.374800f, +1.375161f, +1.375522f, +1.375883f, +1.376244f, +1.376605f, +1.376965f, +1.377326f, +1.377686f, +1.378046f, +1.378406f, +1.378766f, +1.379126f, +1.379486f, +1.379845f, +1.380204f, +1.380564f, +1.380923f, +1.381282f, +1.381641f, +1.381999f, +1.382358f, +1.382717f, +1.383075f, +1.383433f, +1.383791f, +1.384149f, +1.384507f, +1.384865f, +1.385222f, +1.385580f, +1.385937f, +1.386294f, +1.386651f, +1.387008f, +1.387365f, +1.387722f, +1.388078f, +1.388435f, +1.388791f, +1.389147f, +1.389503f, +1.389859f, +1.390215f, +1.390571f, +1.390926f, +1.391282f, +1.391637f, +1.391992f, +1.392347f, +1.392702f, +1.393057f, +1.393412f, +1.393766f, +1.394121f, +1.394475f, +1.394829f, +1.395183f, +1.395537f, +1.395891f, +1.396245f, +1.396598f, +1.396952f, +1.397305f, +1.397658f, +1.398011f, +1.398364f, +1.398717f, +1.399070f, +1.399422f, +1.399775f, +1.400127f, +1.400479f, +1.400831f, +1.401183f, +1.401535f, +1.401886f, +1.402238f, +1.402589f, +1.402941f, +1.403292f, +1.403643f, +1.403994f, +1.404345f, +1.404695f, +1.405046f, +1.405396f, +1.405747f, +1.406097f, +1.406447f, +1.406797f, +1.407147f, +1.407497f, +1.407846f, +1.408196f, +1.408545f, +1.408894f, +1.409243f, +1.409592f, +1.409941f, +1.410290f, +1.410638f, +1.410987f, +1.411335f, +1.411684f, +1.412032f, +1.412380f, +1.412728f, +1.413075f, +1.413423f, +1.413771f, +1.414118f, +1.414465f, +1.414812f, +1.415159f, +1.415506f, +1.415853f, +1.416200f, +1.416546f, +1.416893f, +1.417239f, +1.417585f, +1.417931f, +1.418277f, +1.418623f, +1.418969f, +1.419315f, +1.419660f, +1.420005f, +1.420351f, +1.420696f, +1.421041f, +1.421386f, +1.421730f, +1.422075f, +1.422420f, +1.422764f, +1.423108f, +1.423453f, +1.423797f, +1.424141f, +1.424484f, +1.424828f, +1.425172f, +1.425515f, +1.425858f, +1.426202f, +1.426545f, +1.426888f, +1.427231f, +1.427573f, +1.427916f, +1.428259f, +1.428601f, +1.428943f, +1.429285f, +1.429627f, +1.429969f, +1.430311f, +1.430653f, +1.430995f, +1.431336f, +1.431677f, +1.432019f, +1.432360f, +1.432701f, +1.433042f, +1.433382f, +1.433723f, +1.434064f, +1.434404f, +1.434744f, +1.435085f, +1.435425f, +1.435765f, +1.436104f, +1.436444f, +1.436784f, +1.437123f, +1.437463f, +1.437802f, +1.438141f, +1.438480f, +1.438819f, +1.439158f, +1.439497f, +1.439835f, +1.440174f, +1.440512f, +1.440850f, +1.441188f, +1.441526f, +1.441864f, +1.442202f, +1.442540f, +1.442877f, +1.443215f, +1.443552f, +1.443889f, +1.444226f, +1.444563f, +1.444900f, +1.445237f, +1.445574f, +1.445910f, +1.446246f, +1.446583f, +1.446919f, +1.447255f, +1.447591f, +1.447927f, +1.448263f, +1.448598f, +1.448934f, +1.449269f, +1.449604f, +1.449940f, +1.450275f, +1.450610f, +1.450944f, +1.451279f, +1.451614f, +1.451948f, +1.452283f, +1.452617f, +1.452951f, +1.453285f, +1.453619f, +1.453953f, +1.454287f, +1.454620f, +1.454954f, +1.455287f, +1.455621f, +1.455954f, +1.456287f, +1.456620f, +1.456953f, +1.457285f, +1.457618f, +1.457950f, +1.458283f, +1.458615f, +1.458947f, +1.459279f, +1.459611f, +1.459943f, +1.460275f, +1.460606f, +1.460938f, +1.461269f, +1.461601f, +1.461932f, +1.462263f, +1.462594f, +1.462925f, +1.463255f, +1.463586f, +1.463917f, +1.464247f, +1.464577f, +1.464907f, +1.465238f, +1.465568f, +1.465897f, +1.466227f, +1.466557f, +1.466886f, +1.467216f, +1.467545f, +1.467874f, +1.468203f, +1.468532f, +1.468861f, +1.469190f, +1.469519f, +1.469847f, +1.470176f, +1.470504f, +1.470832f, +1.471161f, +1.471489f, +1.471817f, +1.472144f, +1.472472f, +1.472800f, +1.473127f, +1.473455f, +1.473782f, +1.474109f, +1.474436f, +1.474763f, +1.475090f, +1.475417f, +1.475743f, +1.476070f, +1.476396f, +1.476723f, +1.477049f, +1.477375f, +1.477701f, +1.478027f, +1.478353f, +1.478678f, +1.479004f, +1.479329f, +1.479655f, +1.479980f, +1.480305f, +1.480630f, +1.480955f, +1.481280f, +1.481605f, +1.481929f, +1.482254f, +1.482578f, +1.482902f, +1.483227f, +1.483551f, +1.483875f, +1.484199f, +1.484522f, +1.484846f, +1.485170f, +1.485493f, +1.485816f, +1.486140f, +1.486463f, +1.486786f, +1.487109f, +1.487432f, +1.487754f, +1.488077f, +1.488400f, +1.488722f, +1.489044f, +1.489367f, +1.489689f, +1.490011f, +1.490333f, +1.490654f, +1.490976f, +1.491298f, +1.491619f, +1.491941f, +1.492262f, +1.492583f, +1.492904f, +1.493225f, +1.493546f, +1.493867f, +1.494187f, +1.494508f, +1.494828f, +1.495149f, +1.495469f, +1.495789f, +1.496109f, +1.496429f, +1.496749f, +1.497069f, +1.497388f, +1.497708f, +1.498027f, +1.498347f, +1.498666f, +1.498985f, +1.499304f, +1.499623f, +1.499942f, +1.500261f, +1.500579f, +1.500898f, +1.501216f, +1.501534f, +1.501853f, +1.502171f, +1.502489f, +1.502807f, +1.503125f, +1.503442f, +1.503760f, +1.504077f, +1.504395f, +1.504712f, +1.505029f, +1.505346f, +1.505663f, +1.505980f, +1.506297f, +1.506614f, +1.506930f, +1.507247f, +1.507563f, +1.507880f, +1.508196f, +1.508512f, +1.508828f, +1.509144f, +1.509460f, +1.509775f, +1.510091f, +1.510407f, +1.510722f, +1.511037f, +1.511352f, +1.511668f, +1.511983f, +1.512297f, +1.512612f, +1.512927f, +1.513242f, +1.513556f, +1.513871f, +1.514185f, +1.514499f, +1.514813f, +1.515127f, +1.515441f, +1.515755f, +1.516069f, +1.516382f, +1.516696f, +1.517009f, +1.517323f, +1.517636f, +1.517949f, +1.518262f, +1.518575f, +1.518888f, +1.519201f, +1.519513f, +1.519826f, +1.520138f, +1.520451f, +1.520763f, +1.521075f, +1.521387f, +1.521699f, +1.522011f, +1.522323f, +1.522634f, +1.522946f, +1.523257f, +1.523569f, +1.523880f, +1.524191f, +1.524502f, +1.524813f, +1.525124f, +1.525435f, +1.525746f, +1.526056f, +1.526367f, +1.526677f, +1.526988f, +1.527298f, +1.527608f, +1.527918f, +1.528228f, +1.528538f, +1.528847f, +1.529157f, +1.529467f, +1.529776f, +1.530085f, +1.530395f, +1.530704f, +1.531013f, +1.531322f, +1.531631f, +1.531940f, +1.532248f, +1.532557f, +1.532865f, +1.533174f, +1.533482f, +1.533790f, +1.534098f, +1.534406f, +1.534714f, +1.535022f, +1.535330f, +1.535638f, +1.535945f, +1.536253f, +1.536560f, +1.536867f, +1.537174f, +1.537481f, +1.537788f, +1.538095f, +1.538402f, +1.538709f, +1.539015f, +1.539322f, +1.539628f, +1.539935f, +1.540241f, +1.540547f, +1.540853f, +1.541159f, +1.541465f, +1.541771f, +1.542076f, +1.542382f, +1.542687f, +1.542993f, +1.543298f, +1.543603f, +1.543908f, +1.544213f, +1.544518f, +1.544823f, +1.545128f, +1.545433f, +1.545737f, +1.546042f, +1.546346f, +1.546650f, +1.546954f, +1.547259f, +1.547563f, +1.547866f, +1.548170f, +1.548474f, +1.548778f, +1.549081f, +1.549385f, +1.549688f, +1.549991f, +1.550294f, +1.550597f, +1.550900f, +1.551203f, +1.551506f, +1.551809f, +1.552111f, +1.552414f, +1.552716f, +1.553019f, +1.553321f, +1.553623f, +1.553925f, +1.554227f, +1.554529f, +1.554831f, +1.555133f, +1.555434f, +1.555736f, +1.556037f, +1.556338f, +1.556640f, +1.556941f, +1.557242f, +1.557543f, +1.557844f, +1.558145f, +1.558445f, +1.558746f, +1.559046f, +1.559347f, +1.559647f, +1.559948f, +1.560248f, +1.560548f, +1.560848f, +1.561148f, +1.561447f, +1.561747f, +1.562047f, +1.562346f, +1.562646f, +1.562945f, +1.563244f, +1.563544f, +1.563843f, +1.564142f, +1.564441f, +1.564739f, +1.565038f, +1.565337f, +1.565635f, +1.565934f, +1.566232f, +1.566530f, +1.566829f, +1.567127f, +1.567425f, +1.567723f, +1.568021f, +1.568318f, +1.568616f, +1.568913f, +1.569211f, +1.569508f, +1.569806f, +1.570103f, +1.570400f, +1.570697f, +1.570994f, +1.571291f, +1.571588f, +1.571884f, +1.572181f, +1.572478f, +1.572774f, +1.573070f, +1.573367f, +1.573663f, +1.573959f, +1.574255f, +1.574551f, +1.574846f, +1.575142f, +1.575438f, +1.575733f, +1.576029f, +1.576324f, +1.576620f, +1.576915f, +1.577210f, +1.577505f, +1.577800f, +1.578095f, +1.578389f, +1.578684f, +1.578979f, +1.579273f, +1.579568f, +1.579862f, +1.580156f, +1.580450f, +1.580744f, +1.581038f, +1.581332f, +1.581626f, +1.581920f, +1.582214f, +1.582507f, +1.582801f, +1.583094f, +1.583387f, +1.583680f, +1.583974f, +1.584267f, +1.584560f, +1.584852f, +1.585145f, +1.585438f, +1.585731f, +1.586023f, +1.586315f, +1.586608f, +1.586900f, +1.587192f, +1.587484f, +1.587776f, +1.588068f, +1.588360f, +1.588652f, +1.588944f, +1.589235f, +1.589527f, +1.589818f, +1.590109f, +1.590401f, +1.590692f, +1.590983f, +1.591274f, +1.591565f, +1.591856f, +1.592146f, +1.592437f, +1.592728f, +1.593018f, +1.593309f, +1.593599f, +1.593889f, +1.594179f, +1.594469f, +1.594759f, +1.595049f, +1.595339f, +1.595629f, +1.595918f, +1.596208f, +1.596497f, +1.596787f, +1.597076f, +1.597365f, +1.597654f, +1.597944f, +1.598233f, +1.598521f, +1.598810f, +1.599099f, +1.599388f, +1.599676f, +1.599965f, +1.600253f, +1.600541f, +1.600830f, +1.601118f, +1.601406f, +1.601694f, +1.601982f, +1.602269f, +1.602557f, +1.602845f, +1.603132f, +1.603420f, +1.603707f, +1.603995f, +1.604282f, +1.604569f, +1.604856f, +1.605143f, +1.605430f, +1.605717f, +1.606003f, +1.606290f, +1.606577f, +1.606863f, +1.607150f, +1.607436f, +1.607722f, +1.608008f, +1.608294f, +1.608580f, +1.608866f, +1.609152f, +1.609438f, +1.609724f, +1.610009f, +1.610295f, +1.610580f, +1.610865f, +1.611151f, +1.611436f, +1.611721f, +1.612006f, +1.612291f, +1.612576f, +1.612861f, +1.613145f, +1.613430f, +1.613714f, +1.613999f, +1.614283f, +1.614568f, +1.614852f, +1.615136f, +1.615420f, +1.615704f, +1.615988f, +1.616272f, +1.616555f, +1.616839f, +1.617123f, +1.617406f, +1.617689f, +1.617973f, +1.618256f, +1.618539f, +1.618822f, +1.619105f, +1.619388f, +1.619671f, +1.619954f, +1.620237f, +1.620519f, +1.620802f, +1.621084f, +1.621366f, +1.621649f, +1.621931f, +1.622213f, +1.622495f, +1.622777f, +1.623059f, +1.623341f, +1.623623f, +1.623904f, +1.624186f, +1.624467f, +1.624749f, +1.625030f, +1.625311f, +1.625592f, +1.625874f, +1.626155f, +1.626435f, +1.626716f, +1.626997f, +1.627278f, +1.627558f, +1.627839f, +1.628119f, +1.628400f, +1.628680f, +1.628960f, +1.629241f, +1.629521f, +1.629801f, +1.630081f, +1.630360f, +1.630640f, +1.630920f, +1.631199f, +1.631479f, +1.631758f, +1.632038f, +1.632317f, +1.632596f, +1.632875f, +1.633154f, +1.633433f, +1.633712f, +1.633991f, +1.634270f, +1.634549f, +1.634827f, +1.635106f, +1.635384f, +1.635662f, +1.635941f, +1.636219f, +1.636497f, +1.636775f, +1.637053f, +1.637331f, +1.637609f, +1.637887f, +1.638164f, +1.638442f, +1.638719f, +1.638997f, +1.639274f, +1.639551f, +1.639829f, +1.640106f, +1.640383f, +1.640660f, +1.640937f, +1.641213f, +1.641490f, +1.641767f, +1.642043f, +1.642320f, +1.642596f, +1.642873f, +1.643149f, +1.643425f, +1.643701f, +1.643977f, +1.644253f, +1.644529f, +1.644805f, +1.645081f, +1.645356f, +1.645632f, +1.645908f, +1.646183f, +1.646458f, +1.646734f, +1.647009f, +1.647284f, +1.647559f, +1.647834f, +1.648109f, +1.648384f, +1.648659f, +1.648933f, +1.649208f, +1.649482f, +1.649757f, +1.650031f, +1.650306f, +1.650580f, +1.650854f, +1.651128f, +1.651402f, +1.651676f, +1.651950f, +1.652224f, +1.652497f, +1.652771f, +1.653045f, +1.653318f, +1.653591f, +1.653865f, +1.654138f, +1.654411f, +1.654684f, +1.654957f, +1.655230f, +1.655503f, +1.655776f, +1.656049f, +1.656321f, +1.656594f, +1.656867f, +1.657139f, +1.657411f, +1.657684f, +1.657956f, +1.658228f, +1.658500f, +1.658772f, +1.659044f, +1.659316f, +1.659588f, +1.659859f, +1.660131f, +1.660403f, +1.660674f, +1.660945f, +1.661217f, +1.661488f, +1.661759f, +1.662030f, +1.662301f, +1.662572f, +1.662843f, +1.663114f, +1.663385f, +1.663655f, +1.663926f, +1.664197f, +1.664467f, +1.664737f, +1.665008f, +1.665278f, +1.665548f, +1.665818f, +1.666088f, +1.666358f, +1.666628f, +1.666898f, +1.667168f, +1.667437f, +1.667707f, +1.667976f, +1.668246f, +1.668515f, +1.668784f, +1.669054f, +1.669323f, +1.669592f, +1.669861f, +1.670130f, +1.670399f, +1.670667f, +1.670936f, +1.671205f, +1.671473f, +1.671742f, +1.672010f, +1.672279f, +1.672547f, +1.672815f, +1.673083f, +1.673351f, +1.673619f, +1.673887f, +1.674155f, +1.674423f, +1.674690f, +1.674958f, +1.675226f, +1.675493f, +1.675761f, +1.676028f, +1.676295f, +1.676562f, +1.676830f, +1.677097f, +1.677364f, +1.677630f, +1.677897f, +1.678164f, +1.678431f, +1.678697f, +1.678964f, +1.679230f, +1.679497f, +1.679763f, +1.680030f, +1.680296f, +1.680562f, +1.680828f, +1.681094f, +1.681360f, +1.681626f, +1.681891f, +1.682157f, +1.682423f, +1.682688f, +1.682954f, +1.683219f, +1.683485f, +1.683750f, +1.684015f, +1.684280f, +1.684545f, +1.684810f, +1.685075f, +1.685340f, +1.685605f, +1.685870f, +1.686134f, +1.686399f, +1.686663f, +1.686928f, +1.687192f, +1.687457f, +1.687721f, +1.687985f, +1.688249f, +1.688513f, +1.688777f, +1.689041f, +1.689305f, +1.689569f, +1.689832f, +1.690096f, +1.690359f, +1.690623f, +1.690886f, +1.691150f, +1.691413f, +1.691676f, +1.691939f, +1.692202f, +1.692465f, +1.692728f, +1.692991f, +1.693254f, +1.693516f, +1.693779f, +1.694042f, +1.694304f, +1.694567f, +1.694829f, +1.695091f, +1.695353f, +1.695616f, +1.695878f, +1.696140f, +1.696402f, +1.696664f, +1.696925f, +1.697187f, +1.697449f, +1.697710f, +1.697972f, +1.698233f, +1.698495f, +1.698756f, +1.699017f, +1.699279f, +1.699540f, +1.699801f, +1.700062f, +1.700323f, +1.700584f, +1.700844f, +1.701105f, +1.701366f, +1.701626f, +1.701887f, +1.702147f, +1.702408f, +1.702668f, +1.702928f, +1.703188f, +1.703449f, +1.703709f, +1.703969f, +1.704228f, +1.704488f, +1.704748f, +1.705008f, +1.705267f, +1.705527f, +1.705787f, +1.706046f, +1.706305f, +1.706565f, +1.706824f, +1.707083f, +1.707342f, +1.707601f, +1.707860f, +1.708119f, +1.708378f, +1.708637f, +1.708895f, +1.709154f, +1.709413f, +1.709671f, +1.709929f, +1.710188f, +1.710446f, +1.710704f, +1.710963f, +1.711221f, +1.711479f, +1.711737f, +1.711995f, +1.712252f, +1.712510f, +1.712768f, +1.713025f, +1.713283f, +1.713540f, +1.713798f, +1.714055f, +1.714313f, +1.714570f, +1.714827f, +1.715084f, +1.715341f, +1.715598f, +1.715855f, +1.716112f, +1.716369f, +1.716625f, +1.716882f, +1.717139f, +1.717395f, +1.717651f, +1.717908f, +1.718164f, +1.718420f, +1.718677f, +1.718933f, +1.719189f, +1.719445f, +1.719701f, +1.719957f, +1.720212f, +1.720468f, +1.720724f, +1.720979f, +1.721235f, +1.721490f, +1.721746f, +1.722001f, +1.722256f, +1.722511f, +1.722767f, +1.723022f, +1.723277f, +1.723532f, +1.723786f, +1.724041f, +1.724296f, +1.724551f, +1.724805f, +1.725060f, +1.725314f, +1.725569f, +1.725823f, +1.726077f, +1.726332f, +1.726586f, +1.726840f, +1.727094f, +1.727348f, +1.727602f, +1.727856f, +1.728109f, +1.728363f, +1.728617f, +1.728870f, +1.729124f, +1.729377f, +1.729631f, +1.729884f, +1.730137f, +1.730391f, +1.730644f, +1.730897f, +1.731150f, +1.731403f, +1.731656f, +1.731908f, +1.732161f, +1.732414f, +1.732666f, +1.732919f, +1.733171f, +1.733424f, +1.733676f, +1.733929f, +1.734181f, +1.734433f, +1.734685f, +1.734937f, +1.735189f, +1.735441f, +1.735693f, +1.735945f, +1.736196f, +1.736448f, +1.736700f, +1.736951f, +1.737203f, +1.737454f, +1.737705f, +1.737957f, +1.738208f, +1.738459f, +1.738710f, +1.738961f, +1.739212f, +1.739463f, +1.739714f, +1.739965f, +1.740216f, +1.740466f, +1.740717f, +1.740967f, +1.741218f, +1.741468f, +1.741719f, +1.741969f, +1.742219f, +1.742469f, +1.742719f, +1.742969f, +1.743219f, +1.743469f, +1.743719f, +1.743969f, +1.744219f, +1.744468f, +1.744718f, +1.744967f, +1.745217f, +1.745466f, +1.745716f, +1.745965f, +1.746214f, +1.746463f, +1.746712f, +1.746961f, +1.747210f, +1.747459f, +1.747708f, +1.747957f, +1.748206f, +1.748454f, +1.748703f, +1.748951f, +1.749200f, +1.749448f, +1.749697f, +1.749945f, +1.750193f, +1.750441f, +1.750689f, +1.750937f, +1.751185f, +1.751433f, +1.751681f, +1.751929f, +1.752177f, +1.752424f, +1.752672f, +1.752920f, +1.753167f, +1.753415f, +1.753662f, +1.753909f, +1.754156f, +1.754404f, +1.754651f, +1.754898f, +1.755145f, +1.755392f, +1.755639f, +1.755886f, +1.756132f, +1.756379f, +1.756626f, +1.756872f, +1.757119f, +1.757365f, +1.757612f, +1.757858f, +1.758104f, +1.758350f, +1.758597f, +1.758843f, +1.759089f, +1.759335f, +1.759581f, +1.759826f, +1.760072f, +1.760318f, +1.760564f, +1.760809f, +1.761055f, +1.761300f, +1.761546f, +1.761791f, +1.762036f, +1.762282f, +1.762527f, +1.762772f, +1.763017f, +1.763262f, +1.763507f, +1.763752f, +1.763997f, +1.764241f, +1.764486f, +1.764731f, +1.764975f, +1.765220f, +1.765464f, +1.765709f, +1.765953f, +1.766197f, +1.766442f, +1.766686f, +1.766930f, +1.767174f, +1.767418f, +1.767662f, +1.767906f, +1.768150f, +1.768393f, +1.768637f, +1.768881f, +1.769124f, +1.769368f, +1.769611f, +1.769855f, +1.770098f, +1.770341f, +1.770584f, +1.770828f, +1.771071f, +1.771314f, +1.771557f, +1.771800f, +1.772043f, +1.772285f, +1.772528f, +1.772771f, +1.773013f, +1.773256f, +1.773499f, +1.773741f, +1.773983f, +1.774226f, +1.774468f, +1.774710f, +1.774952f, +1.775194f, +1.775436f, +1.775678f, +1.775920f, +1.776162f, +1.776404f, +1.776646f, +1.776888f, +1.777129f, +1.777371f, +1.777612f, +1.777854f, +1.778095f, +1.778336f, +1.778578f, +1.778819f, +1.779060f, +1.779301f, +1.779542f, +1.779783f, +1.780024f, +1.780265f, +1.780506f, +1.780747f, +1.780987f, +1.781228f, +1.781469f, +1.781709f, +1.781950f, +1.782190f, +1.782430f, +1.782671f, +1.782911f, +1.783151f, +1.783391f, +1.783631f, +1.783871f, +1.784111f, +1.784351f, +1.784591f, +1.784831f, +1.785070f, +1.785310f, +1.785550f, +1.785789f, +1.786029f, +1.786268f, +1.786508f, +1.786747f, +1.786986f, +1.787225f, +1.787465f, +1.787704f, +1.787943f, +1.788182f, +1.788421f, +1.788659f, +1.788898f, +1.789137f, +1.789376f, +1.789614f, +1.789853f, +1.790091f, +1.790330f, +1.790568f, +1.790807f, +1.791045f, +1.791283f, +1.791521f, +1.791759f, +1.791998f, +1.792236f, +1.792474f, +1.792711f, +1.792949f, +1.793187f, +1.793425f, +1.793662f, +1.793900f, +1.794138f, +1.794375f, +1.794613f, +1.794850f, +1.795087f, +1.795325f, +1.795562f, +1.795799f, +1.796036f, +1.796273f, +1.796510f, +1.796747f, +1.796984f, +1.797221f, +1.797457f, +1.797694f, +1.797931f, +1.798167f, +1.798404f, +1.798641f, +1.798877f, +1.799113f, +1.799350f, +1.799586f, +1.799822f, +1.800058f, +1.800294f, +1.800530f, +1.800766f, +1.801002f, +1.801238f, +1.801474f, +1.801710f, +1.801946f, +1.802181f, +1.802417f, +1.802652f, +1.802888f, +1.803123f, +1.803359f, +1.803594f, +1.803829f, +1.804064f, +1.804300f, +1.804535f, +1.804770f, +1.805005f, +1.805240f, +1.805475f, +1.805709f, +1.805944f, +1.806179f, +1.806413f, +1.806648f, +1.806883f, +1.807117f, +1.807352f, +1.807586f, +1.807820f, +1.808055f, +1.808289f, +1.808523f, +1.808757f, +1.808991f, +1.809225f, +1.809459f, +1.809693f, +1.809927f, +1.810161f, +1.810394f, +1.810628f, +1.810862f, +1.811095f, +1.811329f, +1.811562f, +1.811795f, +1.812029f, +1.812262f, +1.812495f, +1.812729f, +1.812962f, +1.813195f, +1.813428f, +1.813661f, +1.813894f, +1.814126f, +1.814359f, +1.814592f, +1.814825f, +1.815057f, +1.815290f, +1.815522f, +1.815755f, +1.815987f, +1.816220f, +1.816452f, +1.816684f, +1.816917f, +1.817149f, +1.817381f, +1.817613f, +1.817845f, +1.818077f, +1.818309f, +1.818540f, +1.818772f, +1.819004f, +1.819236f, +1.819467f, +1.819699f, +1.819930f, +1.820162f, +1.820393f, +1.820625f, +1.820856f, +1.821087f, +1.821318f, +1.821549f, +1.821780f, +1.822012f, +1.822242f, +1.822473f, +1.822704f, +1.822935f, +1.823166f, +1.823397f, +1.823627f, +1.823858f, +1.824088f, +1.824319f, +1.824549f, +1.824780f, +1.825010f, +1.825240f, +1.825471f, +1.825701f, +1.825931f, +1.826161f, +1.826391f, +1.826621f, +1.826851f, +1.827081f, +1.827310f, +1.827540f, +1.827770f, +1.828000f, +1.828229f, +1.828459f, +1.828688f, +1.828918f, +1.829147f, +1.829376f, +1.829606f, +1.829835f, +1.830064f, +1.830293f, +1.830522f, +1.830751f, +1.830980f, +1.831209f, +1.831438f, +1.831667f, +1.831896f, +1.832124f, +1.832353f, +1.832581f, +1.832810f, +1.833039f, +1.833267f, +1.833495f, +1.833724f, +1.833952f, +1.834180f, +1.834408f, +1.834636f, +1.834865f, +1.835093f, +1.835321f, +1.835548f, +1.835776f, +1.836004f, +1.836232f, +1.836460f, +1.836687f, +1.836915f, +1.837142f, +1.837370f, +1.837597f, +1.837825f, +1.838052f, +1.838279f, +1.838507f, +1.838734f, +1.838961f, +1.839188f, +1.839415f, +1.839642f, +1.839869f, +1.840096f, +1.840323f, +1.840550f, +1.840776f, +1.841003f, +1.841230f, +1.841456f, +1.841683f, +1.841909f, +1.842136f, +1.842362f, +1.842588f, +1.842815f, +1.843041f, +1.843267f, +1.843493f, +1.843719f, +1.843945f, +1.844171f, +1.844397f, +1.844623f, +1.844849f, +1.845075f, +1.845300f, +1.845526f, +1.845751f, +1.845977f, +1.846203f, +1.846428f, +1.846653f, +1.846879f, +1.847104f, +1.847329f, +1.847555f, +1.847780f, +1.848005f, +1.848230f, +1.848455f, +1.848680f, +1.848905f, +1.849130f, +1.849354f, +1.849579f, +1.849804f, +1.850028f, +1.850253f, +1.850478f, +1.850702f, +1.850926f, +1.851151f, +1.851375f, +1.851599f, +1.851824f, +1.852048f, +1.852272f, +1.852496f, +1.852720f, +1.852944f, +1.853168f, +1.853392f, +1.853616f, +1.853840f, +1.854063f, +1.854287f, +1.854511f, +1.854734f, +1.854958f, +1.855181f, +1.855405f, +1.855628f, +1.855851f, +1.856075f, +1.856298f, +1.856521f, +1.856744f, +1.856967f, +1.857190f, +1.857413f, +1.857636f, +1.857859f, +1.858082f, +1.858305f, +1.858528f, +1.858750f, +1.858973f, +1.859196f, +1.859418f, +1.859641f, +1.859863f, +1.860085f, +1.860308f, +1.860530f, +1.860752f, +1.860975f, +1.861197f, +1.861419f, +1.861641f, +1.861863f, +1.862085f, +1.862307f, +1.862529f, +1.862750f, +1.862972f, +1.863194f, +1.863415f, +1.863637f, +1.863859f, +1.864080f, +1.864302f, +1.864523f, +1.864744f, +1.864966f, +1.865187f, +1.865408f, +1.865629f, +1.865850f, +1.866072f, +1.866293f, +1.866513f, +1.866734f, +1.866955f, +1.867176f, +1.867397f, +1.867618f, +1.867838f, +1.868059f, +1.868279f, +1.868500f, +1.868721f, +1.868941f, +1.869161f, +1.869382f, +1.869602f, +1.869822f, +1.870042f, +1.870263f, +1.870483f, +1.870703f, +1.870923f, +1.871143f, +1.871363f, +1.871582f, +1.871802f, +1.872022f, +1.872242f, +1.872461f, +1.872681f, +1.872900f, +1.873120f, +1.873339f, +1.873559f, +1.873778f, +1.873998f, +1.874217f, +1.874436f, +1.874655f, +1.874874f, +1.875093f, +1.875312f, +1.875531f, +1.875750f, +1.875969f, +1.876188f, +1.876407f, +1.876626f, +1.876844f, +1.877063f, +1.877282f, +1.877500f, +1.877719f, +1.877937f, +1.878156f, +1.878374f, +1.878592f, +1.878811f, +1.879029f, +1.879247f, +1.879465f, +1.879683f, +1.879901f, +1.880119f, +1.880337f, +1.880555f, +1.880773f, +1.880991f, +1.881208f, +1.881426f, +1.881644f, +1.881861f, +1.882079f, +1.882296f, +1.882514f, +1.882731f, +1.882949f, +1.883166f, +1.883383f, +1.883600f, +1.883818f, +1.884035f, +1.884252f, +1.884469f, +1.884686f, +1.884903f, +1.885120f, +1.885337f, +1.885553f, +1.885770f, +1.885987f, +1.886203f, +1.886420f, +1.886637f, +1.886853f, +1.887070f, +1.887286f, +1.887502f, +1.887719f, +1.887935f, +1.888151f, +1.888368f, +1.888584f, +1.888800f, +1.889016f, +1.889232f, +1.889448f, +1.889664f, +1.889880f, +1.890095f, +1.890311f, +1.890527f, +1.890743f, +1.890958f, +1.891174f, +1.891389f, +1.891605f, +1.891820f, +1.892036f, +1.892251f, +1.892466f, +1.892682f, +1.892897f, +1.893112f, +1.893327f, +1.893542f, +1.893757f, +1.893972f, +1.894187f, +1.894402f, +1.894617f, +1.894832f, +1.895046f, +1.895261f, +1.895476f, +1.895690f, +1.895905f, +1.896119f, +1.896334f, +1.896548f, +1.896763f, +1.896977f, +1.897191f, +1.897406f, +1.897620f, +1.897834f, +1.898048f, +1.898262f, +1.898476f, +1.898690f, +1.898904f, +1.899118f, +1.899332f, +1.899546f, +1.899759f, +1.899973f, +1.900187f, +1.900400f, +1.900614f, +1.900827f, +1.901041f, +1.901254f, +1.901468f, +1.901681f, +1.901894f, +1.902108f, +1.902321f, +1.902534f, +1.902747f, +1.902960f, +1.903173f, +1.903386f, +1.903599f, +1.903812f, +1.904025f, +1.904237f, +1.904450f, +1.904663f, +1.904876f, +1.905088f, +1.905301f, +1.905513f, +1.905726f, +1.905938f, +1.906151f, +1.906363f, +1.906575f, +1.906787f, +1.907000f, +1.907212f, +1.907424f, +1.907636f, +1.907848f, +1.908060f, +1.908272f, +1.908484f, +1.908696f, +1.908907f, +1.909119f, +1.909331f, +1.909543f, +1.909754f, +1.909966f, +1.910177f, +1.910389f, +1.910600f, +1.910812f, +1.911023f, +1.911234f, +1.911445f, +1.911657f, +1.911868f, +1.912079f, +1.912290f, +1.912501f, +1.912712f, +1.912923f, +1.913134f, +1.913345f, +1.913556f, +1.913766f, +1.913977f, +1.914188f, +1.914398f, +1.914609f, +1.914820f, +1.915030f, +1.915241f, +1.915451f, +1.915661f, +1.915872f, +1.916082f, +1.916292f, +1.916502f, +1.916713f, +1.916923f, +1.917133f, +1.917343f, +1.917553f, +1.917763f, +1.917972f, +1.918182f, +1.918392f, +1.918602f, +1.918812f, +1.919021f, +1.919231f, +1.919440f, +1.919650f, +1.919859f, +1.920069f, +1.920278f, +1.920488f, +1.920697f, +1.920906f, +1.921115f, +1.921325f, +1.921534f, +1.921743f, +1.921952f, +1.922161f, +1.922370f, +1.922579f, +1.922788f, +1.922997f, +1.923205f, +1.923414f, +1.923623f, +1.923831f, +1.924040f, +1.924249f, +1.924457f, +1.924666f, +1.924874f, +1.925083f, +1.925291f, +1.925499f, +1.925707f, +1.925916f, +1.926124f, +1.926332f, +1.926540f, +1.926748f, +1.926956f, +1.927164f, +1.927372f, +1.927580f, +1.927788f, +1.927996f, +1.928203f, +1.928411f, +1.928619f, +1.928826f, +1.929034f, +1.929241f, +1.929449f, +1.929656f, +1.929864f, +1.930071f, +1.930278f, +1.930486f, +1.930693f, +1.930900f, +1.931107f, +1.931314f, +1.931521f, +1.931728f, +1.931935f, +1.932142f, +1.932349f, +1.932556f, +1.932763f, +1.932970f, +1.933176f, +1.933383f, +1.933590f, +1.933796f, +1.934003f, +1.934209f, +1.934416f, +1.934622f, +1.934829f, +1.935035f, +1.935241f, +1.935447f, +1.935654f, +1.935860f, +1.936066f, +1.936272f, +1.936478f, +1.936684f, +1.936890f, +1.937096f, +1.937302f, +1.937508f, +1.937713f, +1.937919f, +1.938125f, +1.938330f, +1.938536f, +1.938742f, +1.938947f, +1.939153f, +1.939358f, +1.939564f, +1.939769f, +1.939974f, +1.940179f, +1.940385f, +1.940590f, +1.940795f, +1.941000f, +1.941205f, +1.941410f, +1.941615f, +1.941820f, +1.942025f, +1.942230f, +1.942435f, +1.942640f, +1.942844f, +1.943049f, +1.943254f, +1.943458f, +1.943663f, +1.943867f, +1.944072f, +1.944276f, +1.944481f, +1.944685f, +1.944889f, +1.945093f, +1.945298f, +1.945502f, +1.945706f, +1.945910f, +1.946114f, +1.946318f, +1.946522f, +1.946726f, +1.946930f, +1.947134f, +1.947338f, +1.947541f, +1.947745f, +1.947949f, +1.948153f, +1.948356f, +1.948560f, +1.948763f, +1.948967f, +1.949170f, +1.949374f, +1.949577f, +1.949780f, +1.949983f, +1.950187f, +1.950390f, +1.950593f, +1.950796f, +1.950999f, +1.951202f, +1.951405f, +1.951608f, +1.951811f, +1.952014f, +1.952217f, +1.952420f, +1.952622f, +1.952825f, +1.953028f, +1.953230f, +1.953433f, +1.953635f, +1.953838f, +1.954040f, +1.954243f, +1.954445f, +1.954647f, +1.954850f, +1.955052f, +1.955254f, +1.955456f, +1.955658f, +1.955860f, +1.956063f, +1.956265f, +1.956466f, +1.956668f, +1.956870f, +1.957072f, +1.957274f, +1.957476f, +1.957677f, +1.957879f, +1.958081f, +1.958282f, +1.958484f, +1.958685f, +1.958887f, +1.959088f, +1.959290f, +1.959491f, +1.959692f, +1.959894f, +1.960095f, +1.960296f, +1.960497f, +1.960698f, +1.960899f, +1.961100f, +1.961301f, +1.961502f, +1.961703f, +1.961904f, +1.962105f, +1.962306f, +1.962506f, +1.962707f, +1.962908f, +1.963108f, +1.963309f, +1.963509f, +1.963710f, +1.963910f, +1.964111f, +1.964311f, +1.964512f, +1.964712f, +1.964912f, +1.965112f, +1.965313f, +1.965513f, +1.965713f, +1.965913f, +1.966113f, +1.966313f, +1.966513f, +1.966713f, +1.966913f, +1.967112f, +1.967312f, +1.967512f, +1.967712f, +1.967911f, +1.968111f, +1.968310f, +1.968510f, +1.968709f, +1.968909f, +1.969108f, +1.969308f, +1.969507f, +1.969706f, +1.969906f, +1.970105f, +1.970304f, +1.970503f, +1.970702f, +1.970901f, +1.971100f, +1.971299f, +1.971498f, +1.971697f, +1.971896f, +1.972095f, +1.972294f, +1.972492f, +1.972691f, +1.972890f, +1.973088f, +1.973287f, +1.973486f, +1.973684f, +1.973883f, +1.974081f, +1.974279f, +1.974478f, +1.974676f, +1.974874f, +1.975073f, +1.975271f, +1.975469f, +1.975667f, +1.975865f, +1.976063f, +1.976261f, +1.976459f, +1.976657f, +1.976855f, +1.977053f, +1.977251f, +1.977448f, +1.977646f, +1.977844f, +1.978041f, +1.978239f, +1.978437f, +1.978634f, +1.978832f, +1.979029f, +1.979226f, +1.979424f, +1.979621f, +1.979819f, +1.980016f, +1.980213f, +1.980410f, +1.980607f, +1.980804f, +1.981001f, +1.981198f, +1.981395f, +1.981592f, +1.981789f, +1.981986f, +1.982183f, +1.982380f, +1.982577f, +1.982773f, +1.982970f, +1.983167f, +1.983363f, +1.983560f, +1.983756f, +1.983953f, +1.984149f, +1.984346f, +1.984542f, +1.984738f, +1.984935f, +1.985131f, +1.985327f, +1.985523f, +1.985719f, +1.985915f, +1.986112f, +1.986308f, +1.986504f, +1.986699f, +1.986895f, +1.987091f, +1.987287f, +1.987483f, +1.987679f, +1.987874f, +1.988070f, +1.988266f, +1.988461f, +1.988657f, +1.988852f, +1.989048f, +1.989243f, +1.989439f, +1.989634f, +1.989829f, +1.990025f, +1.990220f, +1.990415f, +1.990610f, +1.990805f, +1.991001f, +1.991196f, +1.991391f, +1.991586f, +1.991781f, +1.991976f, +1.992170f, +1.992365f, +1.992560f, +1.992755f, +1.992950f, +1.993144f, +1.993339f, +1.993533f, +1.993728f, +1.993923f, +1.994117f, +1.994312f, +1.994506f, +1.994700f, +1.994895f, +1.995089f, +1.995283f, +1.995477f, +1.995672f, +1.995866f, +1.996060f, +1.996254f, +1.996448f, +1.996642f, +1.996836f, +1.997030f, +1.997224f, +1.997418f, +1.997612f, +1.997805f, +1.997999f, +1.998193f, +1.998386f, +1.998580f, +1.998774f, +1.998967f, +1.999161f, +1.999354f, +1.999548f, +1.999741f, +1.999934f, +2.000128f, +2.000321f, +2.000514f, +2.000708f, +2.000901f, +2.001094f, +2.001287f, +2.001480f, +2.001673f, +2.001866f, +2.002059f, +2.002252f, +2.002445f, +2.002638f, +2.002830f, +2.003023f, +2.003216f, +2.003409f, +2.003601f, +2.003794f, +2.003987f, +2.004179f, +2.004372f, +2.004564f, +2.004756f, +2.004949f, +2.005141f, +2.005334f, +2.005526f, +2.005718f, +2.005910f, +2.006103f, +2.006295f, +2.006487f, +2.006679f, +2.006871f, +2.007063f, +2.007255f, +2.007447f, +2.007639f, +2.007830f, +2.008022f, +2.008214f, +2.008406f, +2.008597f, +2.008789f, +2.008981f, +2.009172f, +2.009364f, +2.009555f, +2.009747f, +2.009938f, +2.010130f, +2.010321f, +2.010512f, +2.010704f, +2.010895f, +2.011086f, +2.011277f, +2.011469f, +2.011660f, +2.011851f, +2.012042f, +2.012233f, +2.012424f, +2.012615f, +2.012806f, +2.012996f, +2.013187f, +2.013378f, +2.013569f, +2.013760f, +2.013950f, +2.014141f, +2.014331f, +2.014522f, +2.014713f, +2.014903f, +2.015093f, +2.015284f, +2.015474f, +2.015665f, +2.015855f, +2.016045f, +2.016235f, +2.016426f, +2.016616f, +2.016806f, +2.016996f, +2.017186f, +2.017376f, +2.017566f, +2.017756f, +2.017946f, +2.018136f, +2.018326f, +2.018516f, +2.018705f, +2.018895f, +2.019085f, +2.019274f, +2.019464f, +2.019654f, +2.019843f, +2.020033f, +2.020222f, +2.020412f, +2.020601f, +2.020790f, +2.020980f, +2.021169f, +2.021358f, +2.021548f, +2.021737f, +2.021926f, +2.022115f, +2.022304f, +2.022493f, +2.022682f, +2.022871f, +2.023060f, +2.023249f, +2.023438f, +2.023627f, +2.023816f, +2.024004f, +2.024193f, +2.024382f, +2.024570f, +2.024759f, +2.024948f, +2.025136f, +2.025325f, +2.025513f, +2.025702f, +2.025890f, +2.026078f, +2.026267f, +2.026455f, +2.026643f, +2.026832f, +2.027020f, +2.027208f, +2.027396f, +2.027584f, +2.027772f, +2.027960f, +2.028148f, +2.028336f, +2.028524f, +2.028712f, +2.028900f, +2.029088f, +2.029275f, +2.029463f, +2.029651f, +2.029839f, +2.030026f, +2.030214f, +2.030401f, +2.030589f, +2.030776f, +2.030964f, +2.031151f, +2.031339f, +2.031526f, +2.031713f, +2.031901f, +2.032088f, +2.032275f, +2.032462f, +2.032649f, +2.032836f, +2.033024f, +2.033211f, +2.033398f, +2.033585f, +2.033772f, +2.033958f, +2.034145f, +2.034332f, +2.034519f, +2.034706f, +2.034892f, +2.035079f, +2.035266f, +2.035452f, +2.035639f, +2.035825f, +2.036012f, +2.036198f, +2.036385f, +2.036571f, +2.036758f, +2.036944f, +2.037130f, +2.037317f, +2.037503f, +2.037689f, +2.037875f, +2.038061f, +2.038247f, +2.038434f, +2.038620f, +2.038806f, +2.038992f, +2.039177f, +2.039363f, +2.039549f, +2.039735f, +2.039921f, +2.040107f, +2.040292f, +2.040478f, +2.040664f, +2.040849f, +2.041035f, +2.041220f, +2.041406f, +2.041591f, +2.041777f, +2.041962f, +2.042148f, +2.042333f, +2.042518f, +2.042703f, +2.042889f, +2.043074f, +2.043259f, +2.043444f, +2.043629f, +2.043814f, +2.043999f, +2.044184f, +2.044369f, +2.044554f, +2.044739f, +2.044924f, +2.045109f, +2.045294f, +2.045478f, +2.045663f, +2.045848f, +2.046032f, +2.046217f, +2.046402f, +2.046586f, +2.046771f, +2.046955f, +2.047140f, +2.047324f, +2.047508f, +2.047693f, +2.047877f, +2.048061f, +2.048246f, +2.048430f, +2.048614f, +2.048798f, +2.048982f, +2.049166f, +2.049350f, +2.049534f, +2.049718f, +2.049902f, +2.050086f, +2.050270f, +2.050454f, +2.050638f, +2.050822f, +2.051005f, +2.051189f, +2.051373f, +2.051556f, +2.051740f, +2.051924f, +2.052107f, +2.052291f, +2.052474f, +2.052657f, +2.052841f, +2.053024f, +2.053208f, +2.053391f, +2.053574f, +2.053757f, +2.053941f, +2.054124f, +2.054307f, +2.054490f, +2.054673f, +2.054856f, +2.055039f, +2.055222f, +2.055405f, +2.055588f, +2.055771f, +2.055954f, +2.056136f, +2.056319f, +2.056502f, +2.056685f, +2.056867f, +2.057050f, +2.057232f, +2.057415f, +2.057598f, +2.057780f, +2.057963f, +2.058145f, +2.058327f, +2.058510f, +2.058692f, +2.058874f, +2.059057f, +2.059239f, +2.059421f, +2.059603f, +2.059785f, +2.059967f, +2.060149f, +2.060332f, +2.060514f, +2.060695f, +2.060877f, +2.061059f, +2.061241f, +2.061423f, +2.061605f, +2.061787f, +2.061968f, +2.062150f, +2.062332f, +2.062513f, +2.062695f, +2.062877f, +2.063058f, +2.063240f, +2.063421f, +2.063602f, +2.063784f, +2.063965f, +2.064147f, +2.064328f, +2.064509f, +2.064690f, +2.064872f, +2.065053f, +2.065234f, +2.065415f, +2.065596f, +2.065777f, +2.065958f, +2.066139f, +2.066320f, +2.066501f, +2.066682f, +2.066863f, +2.067044f, +2.067224f, +2.067405f, +2.067586f, +2.067767f, +2.067947f, +2.068128f, +2.068308f, +2.068489f, +2.068669f, +2.068850f, +2.069030f, +2.069211f, +2.069391f, +2.069572f, +2.069752f, +2.069932f, +2.070112f, +2.070293f, +2.070473f, +2.070653f, +2.070833f, +2.071013f, +2.071193f, +2.071373f, +2.071553f, +2.071733f, +2.071913f, +2.072093f, +2.072273f, +2.072453f, +2.072633f, +2.072812f, +2.072992f, +2.073172f, +2.073352f, +2.073531f, +2.073711f, +2.073890f, +2.074070f, +2.074250f, +2.074429f, +2.074608f, +2.074788f, +2.074967f, +2.075147f, +2.075326f, +2.075505f, +2.075684f, +2.075864f, +2.076043f, +2.076222f, +2.076401f, +2.076580f, +2.076759f, +2.076938f, +2.077117f, +2.077296f, +2.077475f, +2.077654f, +2.077833f, +2.078012f, +2.078191f, +2.078370f, +2.078548f, +2.078727f, +2.078906f, +2.079084f, +2.079263f, +2.079442f, +2.079620f, +2.079799f, +2.079977f, +2.080156f, +2.080334f, +2.080512f, +2.080691f, +2.080869f, +2.081047f, +2.081226f, +2.081404f, +2.081582f, +2.081760f, +2.081938f, +2.082117f, +2.082295f, +2.082473f, +2.082651f, +2.082829f, +2.083007f, +2.083185f, +2.083362f, +2.083540f, +2.083718f, +2.083896f, +2.084074f, +2.084251f, +2.084429f, +2.084607f, +2.084784f, +2.084962f, +2.085140f, +2.085317f, +2.085495f, +2.085672f, +2.085850f, +2.086027f, +2.086204f, +2.086382f, +2.086559f, +2.086736f, +2.086914f, +2.087091f, +2.087268f, +2.087445f, +2.087622f, +2.087799f, +2.087976f, +2.088153f, +2.088330f, +2.088507f, +2.088684f, +2.088861f, +2.089038f, +2.089215f, +2.089392f, +2.089569f, +2.089745f, +2.089922f, +2.090099f, +2.090275f, +2.090452f, +2.090629f, +2.090805f, +2.090982f, +2.091158f, +2.091335f, +2.091511f, +2.091688f, +2.091864f, +2.092040f, +2.092217f, +2.092393f, +2.092569f, +2.092746f, +2.092922f, +2.093098f, +2.093274f, +2.093450f, +2.093626f, +2.093802f, +2.093978f, +2.094154f, +2.094330f, +2.094506f, +2.094682f, +2.094858f, +2.095034f, +2.095209f, +2.095385f, +2.095561f, +2.095737f, +2.095912f, +2.096088f, +2.096264f, +2.096439f, +2.096615f, +2.096790f, +2.096966f, +2.097141f, +2.097317f, +2.097492f, +2.097667f, +2.097843f, +2.098018f, +2.098193f, +2.098368f, +2.098544f, +2.098719f, +2.098894f, +2.099069f, +2.099244f, +2.099419f, +2.099594f, +2.099769f, +2.099944f, +2.100119f, +2.100294f, +2.100469f, +2.100644f, +2.100819f, +2.100993f, +2.101168f, +2.101343f, +2.101517f, +2.101692f, +2.101867f, +2.102041f, +2.102216f, +2.102390f, +2.102565f, +2.102739f, +2.102914f, +2.103088f, +2.103263f, +2.103437f, +2.103611f, +2.103786f, +2.103960f, +2.104134f, +2.104308f, +2.104483f, +2.104657f, +2.104831f, +2.105005f, +2.105179f, +2.105353f, +2.105527f, +2.105701f, +2.105875f, +2.106049f, +2.106223f, +2.106396f, +2.106570f, +2.106744f, +2.106918f, +2.107091f, +2.107265f, +2.107439f, +2.107612f, +2.107786f, +2.107960f, +2.108133f, +2.108307f, +2.108480f, +2.108654f, +2.108827f, +2.109000f, +2.109174f, +2.109347f, +2.109520f, +2.109694f, +2.109867f, +2.110040f, +2.110213f, +2.110386f, +2.110559f, +2.110733f, +2.110906f, +2.111079f, +2.111252f, +2.111425f, +2.111598f, +2.111770f, +2.111943f, +2.112116f, +2.112289f, +2.112462f, +2.112635f, +2.112807f, +2.112980f, +2.113153f, +2.113325f, +2.113498f, +2.113670f, +2.113843f, +2.114015f, +2.114188f, +2.114360f, +2.114533f, +2.114705f, +2.114878f, +2.115050f, +2.115222f, +2.115395f, +2.115567f, +2.115739f, +2.115911f, +2.116083f, +2.116256f, +2.116428f, +2.116600f, +2.116772f, +2.116944f, +2.117116f, +2.117288f, +2.117460f, +2.117632f, +2.117803f, +2.117975f, +2.118147f, +2.118319f, +2.118491f, +2.118662f, +2.118834f, +2.119006f, +2.119177f, +2.119349f, +2.119520f, +2.119692f, +2.119863f, +2.120035f, +2.120206f, +2.120378f, +2.120549f, +2.120721f, +2.120892f, +2.121063f, +2.121234f, +2.121406f, +2.121577f, +2.121748f, +2.121919f, +2.122090f, +2.122262f, +2.122433f, +2.122604f, +2.122775f, +2.122946f, +2.123117f, +2.123288f, +2.123458f, +2.123629f, +2.123800f, +2.123971f, +2.124142f, +2.124312f, +2.124483f, +2.124654f, +2.124825f, +2.124995f, +2.125166f, +2.125336f, +2.125507f, +2.125677f, +2.125848f, +2.126018f, +2.126189f, +2.126359f, +2.126530f, +2.126700f, +2.126870f, +2.127041f, +2.127211f, +2.127381f, +2.127551f, +2.127721f, +2.127892f, +2.128062f, +2.128232f, +2.128402f, +2.128572f, +2.128742f, +2.128912f, +2.129082f, +2.129252f, +2.129421f, +2.129591f, +2.129761f, +2.129931f, +2.130101f, +2.130270f, +2.130440f, +2.130610f, +2.130779f, +2.130949f, +2.131119f, +2.131288f, +2.131458f, +2.131627f, +2.131797f, +2.131966f, +2.132136f, +2.132305f, +2.132474f, +2.132644f, +2.132813f, +2.132982f, +2.133152f, +2.133321f, +2.133490f, +2.133659f, +2.133828f, +2.133997f, +2.134166f, +2.134335f, +2.134505f, +2.134673f, +2.134842f, +2.135011f, +2.135180f, +2.135349f, +2.135518f, +2.135687f, +2.135856f, +2.136024f, +2.136193f, +2.136362f, +2.136531f, +2.136699f, +2.136868f, +2.137036f, +2.137205f, +2.137373f, +2.137542f, +2.137710f, +2.137879f, +2.138047f, +2.138216f, +2.138384f, +2.138552f, +2.138721f, +2.138889f, +2.139057f, +2.139225f, +2.139394f, +2.139562f, +2.139730f, +2.139898f, +2.140066f, +2.140234f, +2.140402f, +2.140570f, +2.140738f, +2.140906f, +2.141074f, +2.141242f, +2.141410f, +2.141578f, +2.141745f, +2.141913f, +2.142081f, +2.142249f, +2.142416f, +2.142584f, +2.142752f, +2.142919f, +2.143087f, +2.143254f, +2.143422f, +2.143589f, +2.143757f, +2.143924f, +2.144092f, +2.144259f, +2.144426f, +2.144594f, +2.144761f, +2.144928f, +2.145096f, +2.145263f, +2.145430f, +2.145597f, +2.145764f, +2.145931f, +2.146098f, +2.146265f, +2.146432f, +2.146599f, +2.146766f, +2.146933f, +2.147100f, +2.147267f, +2.147434f, +2.147601f, +2.147768f, +2.147934f, +2.148101f, +2.148268f, +2.148434f, +2.148601f, +2.148768f, +2.148934f, +2.149101f, +2.149267f, +2.149434f, +2.149600f, +2.149767f, +2.149933f, +2.150100f, +2.150266f, +2.150432f, +2.150599f, +2.150765f, +2.150931f, +2.151098f, +2.151264f, +2.151430f, +2.151596f, +2.151762f, +2.151928f, +2.152094f, +2.152260f, +2.152426f, +2.152592f, +2.152758f, +2.152924f, +2.153090f, +2.153256f, +2.153422f, +2.153588f, +2.153754f, +2.153919f, +2.154085f, +2.154251f, +2.154416f, +2.154582f, +2.154748f, +2.154913f, +2.155079f, +2.155245f, +2.155410f, +2.155576f, +2.155741f, +2.155906f, +2.156072f, +2.156237f, +2.156403f, +2.156568f, +2.156733f, +2.156898f, +2.157064f, +2.157229f, +2.157394f, +2.157559f, +2.157724f, +2.157890f, +2.158055f, +2.158220f, +2.158385f, +2.158550f, +2.158715f, +2.158880f, +2.159045f, +2.159209f, +2.159374f, +2.159539f, +2.159704f, +2.159869f, +2.160034f, +2.160198f, +2.160363f, +2.160528f, +2.160692f, +2.160857f, +2.161022f, +2.161186f, +2.161351f, +2.161515f, +2.161680f, +2.161844f, +2.162009f, +2.162173f, +2.162337f, +2.162502f, +2.162666f, +2.162830f, +2.162995f, +2.163159f, +2.163323f, +2.163487f, +2.163651f, +2.163816f, +2.163980f, +2.164144f, +2.164308f, +2.164472f, +2.164636f, +2.164800f, +2.164964f, +2.165128f, +2.165292f, +2.165455f, +2.165619f, +2.165783f, +2.165947f, +2.166111f, +2.166274f, +2.166438f, +2.166602f, +2.166765f, +2.166929f, +2.167093f, +2.167256f, +2.167420f, +2.167583f, +2.167747f, +2.167910f, +2.168074f, +2.168237f, +2.168400f, +2.168564f, +2.168727f, +2.168890f, +2.169054f, +2.169217f, +2.169380f, +2.169543f, +2.169707f, +2.169870f, +2.170033f, +2.170196f, +2.170359f, +2.170522f, +2.170685f, +2.170848f, +2.171011f, +2.171174f, +2.171337f, +2.171500f, +2.171663f, +2.171825f, +2.171988f, +2.172151f, +2.172314f, +2.172476f, +2.172639f, +2.172802f, +2.172964f, +2.173127f, +2.173290f, +2.173452f, +2.173615f, +2.173777f, +2.173940f, +2.174102f, +2.174265f, +2.174427f, +2.174589f, +2.174752f, +2.174914f, +2.175076f, +2.175239f, +2.175401f, +2.175563f, +2.175725f, +2.175887f, +2.176050f, +2.176212f, +2.176374f, +2.176536f, +2.176698f, +2.176860f, +2.177022f, +2.177184f, +2.177346f, +2.177508f, +2.177670f, +2.177831f, +2.177993f, +2.178155f, +2.178317f, +2.178479f, +2.178640f, +2.178802f, +2.178964f, +2.179125f, +2.179287f, +2.179448f, +2.179610f, +2.179772f, +2.179933f, +2.180095f, +2.180256f, +2.180417f, +2.180579f, +2.180740f, +2.180902f, +2.181063f, +2.181224f, +2.181386f, +2.181547f, +2.181708f, +2.181869f, +2.182030f, +2.182192f, +2.182353f, +2.182514f, +2.182675f, +2.182836f, +2.182997f, +2.183158f, +2.183319f, +2.183480f, +2.183641f, +2.183802f, +2.183962f, +2.184123f, +2.184284f, +2.184445f, +2.184606f, +2.184766f, +2.184927f, +2.185088f, +2.185248f, +2.185409f, +2.185570f, +2.185730f, +2.185891f, +2.186051f, +2.186212f, +2.186372f, +2.186533f, +2.186693f, +2.186854f, +2.187014f, +2.187174f, +2.187335f, +2.187495f, +2.187655f, +2.187815f, +2.187976f, +2.188136f, +2.188296f, +2.188456f, +2.188616f, +2.188776f, +2.188936f, +2.189096f, +2.189256f, +2.189416f, +2.189576f, +2.189736f, +2.189896f, +2.190056f, +2.190216f, +2.190376f, +2.190536f, +2.190695f, +2.190855f, +2.191015f, +2.191175f, +2.191334f, +2.191494f, +2.191654f, +2.191813f, +2.191973f, +2.192132f, +2.192292f, +2.192451f, +2.192611f, +2.192770f, +2.192930f, +2.193089f, +2.193248f, +2.193408f, +2.193567f, +2.193726f, +2.193886f, +2.194045f, +2.194204f, +2.194363f, +2.194523f, +2.194682f, +2.194841f, +2.195000f, +2.195159f, +2.195318f, +2.195477f, +2.195636f, +2.195795f, +2.195954f, +2.196113f, +2.196272f, +2.196431f, +2.196589f, +2.196748f, +2.196907f, +2.197066f, +2.197225f, +2.197383f, +2.197542f, +2.197701f, +2.197859f, +2.198018f, +2.198177f, +2.198335f, +2.198494f, +2.198652f, +2.198811f, +2.198969f, +2.199128f, +2.199286f, +2.199444f, +2.199603f, +2.199761f, +2.199919f, +2.200078f, +2.200236f, +2.200394f, +2.200552f, +2.200711f, +2.200869f, +2.201027f, +2.201185f, +2.201343f, +2.201501f, +2.201659f, +2.201817f, +2.201975f, +2.202133f, +2.202291f, +2.202449f, +2.202607f, +2.202765f, +2.202923f, +2.203080f, +2.203238f, +2.203396f, +2.203554f, +2.203711f, +2.203869f, +2.204027f, +2.204184f, +2.204342f, +2.204500f, +2.204657f, +2.204815f, +2.204972f, +2.205130f, +2.205287f, +2.205445f, +2.205602f, +2.205759f, +2.205917f, +2.206074f, +2.206232f, +2.206389f, +2.206546f, +2.206703f, +2.206861f, +2.207018f, +2.207175f, +2.207332f, +2.207489f, +2.207646f, +2.207803f, +2.207960f, +2.208117f, +2.208274f, +2.208431f, +2.208588f, +2.208745f, +2.208902f, +2.209059f, +2.209216f, +2.209373f, +2.209530f, +2.209686f, +2.209843f, +2.210000f, +2.210156f, +2.210313f, +2.210470f, +2.210626f, +2.210783f, +2.210940f, +2.211096f, +2.211253f, +2.211409f, +2.211566f, +2.211722f, +2.211879f, +2.212035f, +2.212191f, +2.212348f, +2.212504f, +2.212660f, +2.212817f, +2.212973f, +2.213129f, +2.213285f, +2.213442f, +2.213598f, +2.213754f, +2.213910f, +2.214066f, +2.214222f, +2.214378f, +2.214534f, +2.214690f, +2.214846f, +2.215002f, +2.215158f, +2.215314f, +2.215470f, +2.215626f, +2.215781f, +2.215937f, +2.216093f, +2.216249f, +2.216405f, +2.216560f, +2.216716f, +2.216872f, +2.217027f, +2.217183f, +2.217338f, +2.217494f, +2.217649f, +2.217805f, +2.217960f, +2.218116f, +2.218271f, +2.218427f, +2.218582f, +2.218738f, +2.218893f, +2.219048f, +2.219203f, +2.219359f, +2.219514f, +2.219669f, +2.219824f, +2.219980f, +2.220135f, +2.220290f, +2.220445f, +2.220600f, +2.220755f, +2.220910f, +2.221065f, +2.221220f, +2.221375f, +2.221530f, +2.221685f, +2.221840f, +2.221995f, +2.222149f, +2.222304f, +2.222459f, +2.222614f, +2.222769f, +2.222923f, +2.223078f, +2.223233f, +2.223387f, +2.223542f, +2.223696f, +2.223851f, +2.224006f, +2.224160f, +2.224315f, +2.224469f, +2.224624f, +2.224778f, +2.224932f, +2.225087f, +2.225241f, +2.225395f, +2.225550f, +2.225704f, +2.225858f, +2.226013f, +2.226167f, +2.226321f, +2.226475f, +2.226629f, +2.226783f, +2.226937f, +2.227092f, +2.227246f, +2.227400f, +2.227554f, +2.227708f, +2.227862f, +2.228015f, +2.228169f, +2.228323f, +2.228477f, +2.228631f, +2.228785f, +2.228939f, +2.229092f, +2.229246f, +2.229400f, +2.229553f, +2.229707f, +2.229861f, +2.230014f, +2.230168f, +2.230322f, +2.230475f, +2.230629f, +2.230782f, +2.230936f, +2.231089f, +2.231243f, +2.231396f, +2.231549f, +2.231703f, +2.231856f, +2.232009f, +2.232163f, +2.232316f, +2.232469f, +2.232622f, +2.232776f, +2.232929f, +2.233082f, +2.233235f, +2.233388f, +2.233541f, +2.233694f, +2.233847f, +2.234000f, +2.234153f, +2.234306f, +2.234459f, +2.234612f, +2.234765f, +2.234918f, +2.235071f, +2.235224f, +2.235376f, +2.235529f, +2.235682f, +2.235835f, +2.235987f, +2.236140f, +2.236293f, +2.236445f, +2.236598f, +2.236750f, +2.236903f, +2.237056f, +2.237208f, +2.237361f, +2.237513f, +2.237666f, +2.237818f, +2.237970f, +2.238123f, +2.238275f, +2.238427f, +2.238580f, +2.238732f, +2.238884f, +2.239037f, +2.239189f, +2.239341f, +2.239493f, +2.239645f, +2.239797f, +2.239950f, +2.240102f, +2.240254f, +2.240406f, +2.240558f, +2.240710f, +2.240862f, +2.241014f, +2.241166f, +2.241317f, +2.241469f, +2.241621f, +2.241773f, +2.241925f, +2.242077f, +2.242228f, +2.242380f, +2.242532f, +2.242683f, +2.242835f, +2.242987f, +2.243138f, +2.243290f, +2.243442f, +2.243593f, +2.243745f, +2.243896f, +2.244048f, +2.244199f, +2.244350f, +2.244502f, +2.244653f, +2.244805f, +2.244956f, +2.245107f, +2.245259f, +2.245410f, +2.245561f, +2.245712f, +2.245864f, +2.246015f, +2.246166f, +2.246317f, +2.246468f, +2.246619f, +2.246770f, +2.246921f, +2.247072f, +2.247223f, +2.247374f, +2.247525f, +2.247676f, +2.247827f, +2.247978f, +2.248129f, +2.248280f, +2.248431f, +2.248581f, +2.248732f, +2.248883f, +2.249034f, +2.249184f, +2.249335f, +2.249486f, +2.249636f, +2.249787f, +2.249937f, +2.250088f, +2.250239f, +2.250389f, +2.250540f, +2.250690f, +2.250841f, +2.250991f, +2.251141f, +2.251292f, +2.251442f, +2.251593f, +2.251743f, +2.251893f, +2.252043f, +2.252194f, +2.252344f, +2.252494f, +2.252644f, +2.252794f, +2.252945f, +2.253095f, +2.253245f, +2.253395f, +2.253545f, +2.253695f, +2.253845f, +2.253995f, +2.254145f, +2.254295f, +2.254445f, +2.254595f, +2.254744f, +2.254894f, +2.255044f, +2.255194f, +2.255344f, +2.255493f, +2.255643f, +2.255793f, +2.255943f, +2.256092f, +2.256242f, +2.256392f, +2.256541f, +2.256691f, +2.256840f, +2.256990f, +2.257139f, +2.257289f, +2.257438f, +2.257588f, +2.257737f, +2.257887f, +2.258036f, +2.258185f, +2.258335f, +2.258484f, +2.258633f, +2.258782f, +2.258932f, +2.259081f, +2.259230f, +2.259379f, +2.259528f, +2.259678f, +2.259827f, +2.259976f, +2.260125f, +2.260274f, +2.260423f, +2.260572f, +2.260721f, +2.260870f, +2.261019f, +2.261168f, +2.261317f, +2.261465f, +2.261614f, +2.261763f, +2.261912f, +2.262061f, +2.262209f, +2.262358f, +2.262507f, +2.262656f, +2.262804f, +2.262953f, +2.263101f, +2.263250f, +2.263399f, +2.263547f, +2.263696f, +2.263844f, +2.263993f, +2.264141f, +2.264290f, +2.264438f, +2.264586f, +2.264735f, +2.264883f, +2.265032f, +2.265180f, +2.265328f, +2.265476f, +2.265625f, +2.265773f, +2.265921f, +2.266069f, +2.266217f, +2.266366f, +2.266514f, +2.266662f, +2.266810f, +2.266958f, +2.267106f, +2.267254f, +2.267402f, +2.267550f, +2.267698f, +2.267846f, +2.267994f, +2.268142f, +2.268289f, +2.268437f, +2.268585f, +2.268733f, +2.268881f, +2.269028f, +2.269176f, +2.269324f, +2.269471f, +2.269619f, +2.269767f, +2.269914f, +2.270062f, +2.270209f, +2.270357f, +2.270505f, +2.270652f, +2.270800f, +2.270947f, +2.271094f, +2.271242f, +2.271389f, +2.271537f, +2.271684f, +2.271831f, +2.271979f, +2.272126f, +2.272273f, +2.272420f, +2.272568f, +2.272715f, +2.272862f, +2.273009f, +2.273156f, +2.273303f, +2.273450f, +2.273598f, +2.273745f, +2.273892f, +2.274039f, +2.274186f, +2.274333f, +2.274480f, +2.274626f, +2.274773f, +2.274920f, +2.275067f, +2.275214f, +2.275361f, +2.275507f, +2.275654f, +2.275801f, +2.275948f, +2.276094f, +2.276241f, +2.276388f, +2.276534f, +2.276681f, +2.276828f, +2.276974f, +2.277121f, +2.277267f, +2.277414f, +2.277560f, +2.277707f, +2.277853f, +2.278000f, +2.278146f, +2.278292f, +2.278439f, +2.278585f, +2.278731f, +2.278878f, +2.279024f, +2.279170f, +2.279316f, +2.279463f, +2.279609f, +2.279755f, +2.279901f, +2.280047f, +2.280193f, +2.280339f, +2.280486f, +2.280632f, +2.280778f, +2.280924f, +2.281070f, +2.281216f, +2.281361f, +2.281507f, +2.281653f, +2.281799f, +2.281945f, +2.282091f, +2.282237f, +2.282382f, +2.282528f, +2.282674f, +2.282820f, +2.282965f, +2.283111f, +2.283257f, +2.283402f, +2.283548f, +2.283693f, +2.283839f, +2.283985f, +2.284130f, +2.284276f, +2.284421f, +2.284567f, +2.284712f, +2.284857f, +2.285003f, +2.285148f, +2.285294f, +2.285439f, +2.285584f, +2.285730f, +2.285875f, +2.286020f, +2.286165f, +2.286311f, +2.286456f, +2.286601f, +2.286746f, +2.286891f, +2.287036f, +2.287181f, +2.287326f, +2.287471f, +2.287616f, +2.287761f, +2.287906f, +2.288051f, +2.288196f, +2.288341f, +2.288486f, +2.288631f, +2.288776f, +2.288921f, +2.289066f, +2.289210f, +2.289355f, +2.289500f, +2.289645f, +2.289789f, +2.289934f, +2.290079f, +2.290223f, +2.290368f, +2.290513f, +2.290657f, +2.290802f, +2.290946f, +2.291091f, +2.291235f, +2.291380f, +2.291524f, +2.291669f, +2.291813f, +2.291957f, +2.292102f, +2.292246f, +2.292390f, +2.292535f, +2.292679f, +2.292823f, +2.292968f, +2.293112f, +2.293256f, +2.293400f, +2.293544f, +2.293688f, +2.293833f, +2.293977f, +2.294121f, +2.294265f, +2.294409f, +2.294553f, +2.294697f, +2.294841f, +2.294985f, +2.295129f, +2.295273f, +2.295417f, +2.295560f, +2.295704f, +2.295848f, +2.295992f, +2.296136f, +2.296280f, +2.296423f, +2.296567f, +2.296711f, +2.296854f, +2.296998f, +2.297142f, +2.297285f, +2.297429f, +2.297573f, +2.297716f, +2.297860f, +2.298003f, +2.298147f, +2.298290f, +2.298434f, +2.298577f, +2.298720f, +2.298864f, +2.299007f, +2.299151f, +2.299294f, +2.299437f, +2.299581f, +2.299724f, +2.299867f, +2.300010f, +2.300154f, +2.300297f, +2.300440f, +2.300583f, +2.300726f, +2.300869f, +2.301012f, +2.301156f, +2.301299f, +2.301442f, +2.301585f, +2.301728f, +2.301871f, +2.302014f, +2.302156f, +2.302299f, +2.302442f, +2.302585f diff --git a/rce/rcecalib/dataproc/fit/logx_ext.dat b/rce/rcecalib/dataproc/fit/logx_ext.dat new file mode 100644 index 0000000000000000000000000000000000000000..683d27b30df2c9c4251a8021949dc29fe7c53147 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/logx_ext.dat @@ -0,0 +1,14002 @@ +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-13.122363f, +-0.000002f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.716898f, +-0.000003f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.429216f, +-0.000004f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.206073f, +-0.000005f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-12.023751f, +-0.000006f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.869600f, +-0.000007f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.736069f, +-0.000008f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.618286f, +-0.000009f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.512925f, +-0.000010f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.417615f, +-0.000011f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.330604f, +-0.000012f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.250561f, +-0.000013f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.176453f, +-0.000014f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.107460f, +-0.000015f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-11.042922f, +-0.000016f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.982297f, +-0.000017f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.925139f, +-0.000018f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.871072f, +-0.000019f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.819778f, +-0.000020f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.770988f, +-0.000021f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.724468f, +-0.000022f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.680016f, +-0.000023f, +-10.637457f, +-0.000024f, +-10.637457f, +-0.000024f, +-10.637457f, +-0.000024f, +-10.637457f, +-0.000024f, +-10.637457f, +-0.000024f, +-10.637457f, +-0.000024f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.596635f, +-0.000025f, +-10.557414f, +-0.000026f, +-10.557414f, +-0.000026f, +-10.557414f, +-0.000026f, +-10.557414f, +-0.000026f, +-10.557414f, +-0.000026f, +-10.557414f, +-0.000026f, +-10.519674f, +-0.000027f, +-10.519674f, +-0.000027f, +-10.519674f, +-0.000027f, +-10.519674f, +-0.000027f, +-10.519674f, +-0.000027f, +-10.519674f, +-0.000027f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.483306f, +-0.000028f, +-10.448215f, +-0.000029f, +-10.448215f, +-0.000029f, +-10.448215f, +-0.000029f, +-10.448215f, +-0.000029f, +-10.448215f, +-0.000029f, +-10.414313f, +-0.000030f, +-10.414313f, +-0.000030f, +-10.414313f, +-0.000030f, +-10.414313f, +-0.000030f, +-10.414313f, +-0.000030f, +-10.414313f, +-0.000030f, +-10.381523f, +-0.000031f, +-10.381523f, +-0.000031f, +-10.381523f, +-0.000031f, +-10.381523f, +-0.000031f, +-10.381523f, +-0.000031f, +-10.349775f, +-0.000032f, +-10.349775f, +-0.000032f, +-10.349775f, +-0.000032f, +-10.349775f, +-0.000032f, +-10.349775f, +-0.000032f, +-10.319003f, +-0.000033f, +-10.319003f, +-0.000033f, +-10.319003f, +-0.000033f, +-10.319003f, +-0.000033f, +-10.319003f, +-0.000033f, +-10.319003f, +-0.000033f, +-10.289150f, +-0.000034f, +-10.289150f, +-0.000034f, +-10.289150f, +-0.000034f, +-10.289150f, +-0.000034f, +-10.260162f, +-0.000035f, +-10.260162f, +-0.000035f, +-10.260162f, +-0.000035f, +-10.260162f, +-0.000035f, +-10.260162f, +-0.000035f, +-10.231992f, +-0.000036f, +-10.231992f, +-0.000036f, +-10.231992f, +-0.000036f, +-10.231992f, +-0.000036f, +-10.231992f, +-0.000036f, +-10.204593f, +-0.000037f, +-10.204593f, +-0.000037f, +-10.204593f, +-0.000037f, +-10.204593f, +-0.000037f, +-10.177924f, +-0.000038f, +-10.177924f, +-0.000038f, +-10.177924f, +-0.000038f, +-10.177924f, +-0.000038f, +-10.177924f, +-0.000038f, +-10.151949f, +-0.000039f, +-10.151949f, +-0.000039f, +-10.151949f, +-0.000039f, +-10.151949f, +-0.000039f, +-10.126631f, +-0.000040f, +-10.126631f, +-0.000040f, +-10.126631f, +-0.000040f, +-10.126631f, +-0.000040f, +-10.101939f, +-0.000041f, +-10.101939f, +-0.000041f, +-10.101939f, +-0.000041f, +-10.101939f, +-0.000041f, +-10.101939f, +-0.000041f, +-10.077841f, +-0.000042f, +-10.077841f, +-0.000042f, +-10.077841f, +-0.000042f, +-10.077841f, +-0.000042f, +-10.054310f, +-0.000043f, +-10.054310f, +-0.000043f, +-10.054310f, +-0.000043f, +-10.054310f, +-0.000043f, +-10.031321f, +-0.000044f, +-10.031321f, +-0.000044f, +-10.031321f, +-0.000044f, +-10.031321f, +-0.000044f, +-10.008848f, +-0.000045f, +-10.008848f, +-0.000045f, +-10.008848f, +-0.000045f, +-9.986869f, +-0.000046f, +-9.986869f, +-0.000046f, +-9.986869f, +-0.000046f, +-9.986869f, +-0.000046f, +-9.965363f, +-0.000047f, +-9.965363f, +-0.000047f, +-9.965363f, +-0.000047f, +-9.965363f, +-0.000047f, +-9.944310f, +-0.000048f, +-9.944310f, +-0.000048f, +-9.944310f, +-0.000048f, +-9.923690f, +-0.000049f, +-9.923690f, +-0.000049f, +-9.923690f, +-0.000049f, +-9.923690f, +-0.000049f, +-9.903488f, +-0.000050f, +-9.903488f, +-0.000050f, +-9.903488f, +-0.000050f, +-9.883685f, +-0.000051f, +-9.883685f, +-0.000051f, +-9.883685f, +-0.000051f, +-9.883685f, +-0.000051f, +-9.864267f, +-0.000052f, +-9.864267f, +-0.000052f, +-9.864267f, +-0.000052f, +-9.845219f, +-0.000053f, +-9.845219f, +-0.000053f, +-9.845219f, +-0.000053f, +-9.826527f, +-0.000054f, +-9.826527f, +-0.000054f, +-9.826527f, +-0.000054f, +-9.808177f, +-0.000055f, +-9.808177f, +-0.000055f, +-9.808177f, +-0.000055f, +-9.790159f, +-0.000056f, +-9.790159f, +-0.000056f, +-9.790159f, +-0.000056f, +-9.772459f, +-0.000057f, +-9.772459f, +-0.000057f, +-9.772459f, +-0.000057f, +-9.772459f, +-0.000057f, +-9.755068f, +-0.000058f, +-9.755068f, +-0.000058f, +-9.737973f, +-0.000059f, +-9.737973f, +-0.000059f, +-9.737973f, +-0.000059f, +-9.721166f, +-0.000060f, +-9.721166f, +-0.000060f, +-9.721166f, +-0.000060f, +-9.704637f, +-0.000061f, +-9.704637f, +-0.000061f, +-9.704637f, +-0.000061f, +-9.688376f, +-0.000062f, +-9.688376f, +-0.000062f, +-9.688376f, +-0.000062f, +-9.672376f, +-0.000063f, +-9.672376f, +-0.000063f, +-9.672376f, +-0.000063f, +-9.656627f, +-0.000064f, +-9.656627f, +-0.000064f, +-9.641123f, +-0.000065f, +-9.641123f, +-0.000065f, +-9.641123f, +-0.000065f, +-9.625856f, +-0.000066f, +-9.625856f, +-0.000066f, +-9.625856f, +-0.000066f, +-9.610818f, +-0.000067f, +-9.610818f, +-0.000067f, +-9.596003f, +-0.000068f, +-9.596003f, +-0.000068f, +-9.596003f, +-0.000068f, +-9.581404f, +-0.000069f, +-9.581404f, +-0.000069f, +-9.567015f, +-0.000070f, +-9.567015f, +-0.000070f, +-9.567015f, +-0.000070f, +-9.552831f, +-0.000071f, +-9.552831f, +-0.000071f, +-9.538844f, +-0.000072f, +-9.538844f, +-0.000072f, +-9.538844f, +-0.000072f, +-9.525051f, +-0.000073f, +-9.525051f, +-0.000073f, +-9.511445f, +-0.000074f, +-9.511445f, +-0.000074f, +-9.511445f, +-0.000074f, +-9.498022f, +-0.000075f, +-9.498022f, +-0.000075f, +-9.484777f, +-0.000076f, +-9.484777f, +-0.000076f, +-9.471705f, +-0.000077f, +-9.471705f, +-0.000077f, +-9.471705f, +-0.000077f, +-9.458802f, +-0.000078f, +-9.458802f, +-0.000078f, +-9.446063f, +-0.000079f, +-9.446063f, +-0.000079f, +-9.433484f, +-0.000080f, +-9.433484f, +-0.000080f, +-9.421061f, +-0.000081f, +-9.421061f, +-0.000081f, +-9.408791f, +-0.000082f, +-9.408791f, +-0.000082f, +-9.408791f, +-0.000082f, +-9.396670f, +-0.000083f, +-9.396670f, +-0.000083f, +-9.384694f, +-0.000084f, +-9.384694f, +-0.000084f, +-9.372859f, +-0.000085f, +-9.372859f, +-0.000085f, +-9.361163f, +-0.000086f, +-9.361163f, +-0.000086f, +-9.349602f, +-0.000087f, +-9.349602f, +-0.000087f, +-9.338174f, +-0.000088f, +-9.338174f, +-0.000088f, +-9.326874f, +-0.000089f, +-9.326874f, +-0.000089f, +-9.315701f, +-0.000090f, +-9.315701f, +-0.000090f, +-9.304651f, +-0.000091f, +-9.304651f, +-0.000091f, +-9.293722f, +-0.000092f, +-9.293722f, +-0.000092f, +-9.282911f, +-0.000093f, +-9.282911f, +-0.000093f, +-9.272216f, +-0.000094f, +-9.272216f, +-0.000094f, +-9.261634f, +-0.000095f, +-9.261634f, +-0.000095f, +-9.251162f, +-0.000096f, +-9.240800f, +-0.000097f, +-9.240800f, +-0.000097f, +-9.230543f, +-0.000098f, +-9.230543f, +-0.000098f, +-9.220391f, +-0.000099f, +-9.220391f, +-0.000099f, +-9.210340f, +-0.000100f, +-9.210340f, +-0.000100f, +-9.200390f, +-0.000101f, +-9.190538f, +-0.000102f, +-9.190538f, +-0.000102f, +-9.180782f, +-0.000103f, +-9.180782f, +-0.000103f, +-9.171120f, +-0.000104f, +-9.171120f, +-0.000104f, +-9.161550f, +-0.000105f, +-9.152071f, +-0.000106f, +-9.152071f, +-0.000106f, +-9.142682f, +-0.000107f, +-9.142682f, +-0.000107f, +-9.133379f, +-0.000108f, +-9.124163f, +-0.000109f, +-9.124163f, +-0.000109f, +-9.115030f, +-0.000110f, +-9.115030f, +-0.000110f, +-9.105980f, +-0.000111f, +-9.097012f, +-0.000112f, +-9.097012f, +-0.000112f, +-9.088123f, +-0.000113f, +-9.079312f, +-0.000114f, +-9.079312f, +-0.000114f, +-9.070578f, +-0.000115f, +-9.070578f, +-0.000115f, +-9.061920f, +-0.000116f, +-9.053337f, +-0.000117f, +-9.053337f, +-0.000117f, +-9.044826f, +-0.000118f, +-9.036387f, +-0.000119f, +-9.036387f, +-0.000119f, +-9.028019f, +-0.000120f, +-9.019720f, +-0.000121f, +-9.019720f, +-0.000121f, +-9.011490f, +-0.000122f, +-9.003326f, +-0.000123f, +-9.003326f, +-0.000123f, +-8.995229f, +-0.000124f, +-8.987197f, +-0.000125f, +-8.987197f, +-0.000125f, +-8.979229f, +-0.000126f, +-8.971323f, +-0.000127f, +-8.963480f, +-0.000128f, +-8.963480f, +-0.000128f, +-8.955698f, +-0.000129f, +-8.947976f, +-0.000130f, +-8.947976f, +-0.000130f, +-8.940313f, +-0.000131f, +-8.932709f, +-0.000132f, +-8.925161f, +-0.000133f, +-8.925161f, +-0.000133f, +-8.917671f, +-0.000134f, +-8.910236f, +-0.000135f, +-8.910236f, +-0.000135f, +-8.902856f, +-0.000136f, +-8.895530f, +-0.000137f, +-8.888257f, +-0.000138f, +-8.888257f, +-0.000138f, +-8.881037f, +-0.000139f, +-8.873868f, +-0.000140f, +-8.866751f, +-0.000141f, +-8.859683f, +-0.000142f, +-8.859683f, +-0.000142f, +-8.852666f, +-0.000143f, +-8.845697f, +-0.000144f, +-8.838777f, +-0.000145f, +-8.838777f, +-0.000145f, +-8.831904f, +-0.000146f, +-8.825078f, +-0.000147f, +-8.818298f, +-0.000148f, +-8.811564f, +-0.000149f, +-8.804875f, +-0.000150f, +-8.804875f, +-0.000150f, +-8.798231f, +-0.000151f, +-8.791630f, +-0.000152f, +-8.785073f, +-0.000153f, +-8.778558f, +-0.000154f, +-8.778558f, +-0.000154f, +-8.772085f, +-0.000155f, +-8.765655f, +-0.000156f, +-8.759265f, +-0.000157f, +-8.752916f, +-0.000158f, +-8.746606f, +-0.000159f, +-8.740337f, +-0.000160f, +-8.740337f, +-0.000160f, +-8.734106f, +-0.000161f, +-8.727914f, +-0.000162f, +-8.721760f, +-0.000163f, +-8.715644f, +-0.000164f, +-8.709565f, +-0.000165f, +-8.703523f, +-0.000166f, +-8.697517f, +-0.000167f, +-8.691547f, +-0.000168f, +-8.685612f, +-0.000169f, +-8.685612f, +-0.000169f, +-8.679712f, +-0.000170f, +-8.673847f, +-0.000171f, +-8.668016f, +-0.000172f, +-8.662219f, +-0.000173f, +-8.656455f, +-0.000174f, +-8.650725f, +-0.000175f, +-8.645027f, +-0.000176f, +-8.639361f, +-0.000177f, +-8.633727f, +-0.000178f, +-8.628125f, +-0.000179f, +-8.622554f, +-0.000180f, +-8.617014f, +-0.000181f, +-8.611504f, +-0.000182f, +-8.606024f, +-0.000183f, +-8.600575f, +-0.000184f, +-8.595155f, +-0.000185f, +-8.589764f, +-0.000186f, +-8.584402f, +-0.000187f, +-8.579069f, +-0.000188f, +-8.573764f, +-0.000189f, +-8.568486f, +-0.000190f, +-8.563237f, +-0.000191f, +-8.558015f, +-0.000192f, +-8.552820f, +-0.000193f, +-8.547652f, +-0.000194f, +-8.542511f, +-0.000195f, +-8.537396f, +-0.000196f, +-8.532307f, +-0.000197f, +-8.527244f, +-0.000198f, +-8.522206f, +-0.000199f, +-8.517193f, +-0.000200f, +-8.512206f, +-0.000201f, +-8.507243f, +-0.000202f, +-8.502305f, +-0.000203f, +-8.492501f, +-0.000205f, +-8.487634f, +-0.000206f, +-8.482792f, +-0.000207f, +-8.477972f, +-0.000208f, +-8.473176f, +-0.000209f, +-8.468403f, +-0.000210f, +-8.463652f, +-0.000211f, +-8.458924f, +-0.000212f, +-8.449535f, +-0.000214f, +-8.444873f, +-0.000215f, +-8.440232f, +-0.000216f, +-8.435613f, +-0.000217f, +-8.431015f, +-0.000218f, +-8.426439f, +-0.000219f, +-8.421883f, +-0.000220f, +-8.412833f, +-0.000222f, +-8.408339f, +-0.000223f, +-8.403864f, +-0.000224f, +-8.399410f, +-0.000225f, +-8.394976f, +-0.000226f, +-8.386165f, +-0.000228f, +-8.381789f, +-0.000229f, +-8.377431f, +-0.000230f, +-8.373093f, +-0.000231f, +-8.368773f, +-0.000232f, +-8.360189f, +-0.000234f, +-8.355925f, +-0.000235f, +-8.351679f, +-0.000236f, +-8.347450f, +-0.000237f, +-8.339047f, +-0.000239f, +-8.334872f, +-0.000240f, +-8.330714f, +-0.000241f, +-8.322449f, +-0.000243f, +-8.318342f, +-0.000244f, +-8.314252f, +-0.000245f, +-8.310179f, +-0.000246f, +-8.302082f, +-0.000248f, +-8.298058f, +-0.000249f, +-8.294050f, +-0.000250f, +-8.286081f, +-0.000252f, +-8.282121f, +-0.000253f, +-8.278176f, +-0.000254f, +-8.270333f, +-0.000256f, +-8.266434f, +-0.000257f, +-8.262551f, +-0.000258f, +-8.254829f, +-0.000260f, +-8.250990f, +-0.000261f, +-8.247166f, +-0.000262f, +-8.239561f, +-0.000264f, +-8.235781f, +-0.000265f, +-8.228262f, +-0.000267f, +-8.224524f, +-0.000268f, +-8.217089f, +-0.000270f, +-8.213392f, +-0.000271f, +-8.209708f, +-0.000272f, +-8.202382f, +-0.000274f, +-8.198739f, +-0.000275f, +-8.191493f, +-0.000277f, +-8.187889f, +-0.000278f, +-8.180721f, +-0.000280f, +-8.177156f, +-0.000281f, +-8.170064f, +-0.000283f, +-8.166536f, +-0.000284f, +-8.159519f, +-0.000286f, +-8.156028f, +-0.000287f, +-8.149084f, +-0.000289f, +-8.145630f, +-0.000290f, +-8.138757f, +-0.000292f, +-8.135338f, +-0.000293f, +-8.128535f, +-0.000295f, +-8.125151f, +-0.000296f, +-8.118417f, +-0.000298f, +-8.115067f, +-0.000299f, +-8.108400f, +-0.000301f, +-8.105084f, +-0.000302f, +-8.098483f, +-0.000304f, +-8.091925f, +-0.000306f, +-8.088663f, +-0.000307f, +-8.082169f, +-0.000309f, +-8.078938f, +-0.000310f, +-8.072507f, +-0.000312f, +-8.066118f, +-0.000314f, +-8.062938f, +-0.000315f, +-8.056609f, +-0.000317f, +-8.050319f, +-0.000319f, +-8.047190f, +-0.000320f, +-8.040959f, +-0.000322f, +-8.034767f, +-0.000324f, +-8.031685f, +-0.000325f, +-8.025550f, +-0.000327f, +-8.019453f, +-0.000329f, +-8.016418f, +-0.000330f, +-8.010376f, +-0.000332f, +-8.004370f, +-0.000334f, +-8.001380f, +-0.000335f, +-7.995428f, +-0.000337f, +-7.989510f, +-0.000339f, +-7.983628f, +-0.000341f, +-7.980700f, +-0.000342f, +-7.974869f, +-0.000344f, +-7.969072f, +-0.000346f, +-7.963308f, +-0.000348f, +-7.957577f, +-0.000350f, +-7.954724f, +-0.000351f, +-7.949042f, +-0.000353f, +-7.943393f, +-0.000355f, +-7.937775f, +-0.000357f, +-7.932188f, +-0.000359f, +-7.926633f, +-0.000361f, +-7.923866f, +-0.000362f, +-7.918357f, +-0.000364f, +-7.912877f, +-0.000366f, +-7.907428f, +-0.000368f, +-7.902008f, +-0.000370f, +-7.896617f, +-0.000372f, +-7.891255f, +-0.000374f, +-7.885921f, +-0.000376f, +-7.880616f, +-0.000378f, +-7.875339f, +-0.000380f, +-7.870090f, +-0.000382f, +-7.864868f, +-0.000384f, +-7.862267f, +-0.000385f, +-7.857086f, +-0.000387f, +-7.851931f, +-0.000389f, +-7.846803f, +-0.000391f, +-7.841701f, +-0.000393f, +-7.834096f, +-0.000396f, +-7.829059f, +-0.000398f, +-7.824046f, +-0.000400f, +-7.819058f, +-0.000402f, +-7.814096f, +-0.000404f, +-7.809157f, +-0.000406f, +-7.804243f, +-0.000408f, +-7.799353f, +-0.000410f, +-7.794487f, +-0.000412f, +-7.789645f, +-0.000414f, +-7.784825f, +-0.000416f, +-7.780029f, +-0.000418f, +-7.775256f, +-0.000420f, +-7.768138f, +-0.000423f, +-7.763421f, +-0.000425f, +-7.758727f, +-0.000427f, +-7.754054f, +-0.000429f, +-7.749402f, +-0.000431f, +-7.742466f, +-0.000434f, +-7.737868f, +-0.000436f, +-7.733292f, +-0.000438f, +-7.728736f, +-0.000440f, +-7.724201f, +-0.000442f, +-7.717436f, +-0.000445f, +-7.712952f, +-0.000447f, +-7.708488f, +-0.000449f, +-7.704043f, +-0.000451f, +-7.697413f, +-0.000454f, +-7.693018f, +-0.000456f, +-7.688641f, +-0.000458f, +-7.682113f, +-0.000461f, +-7.677783f, +-0.000463f, +-7.673473f, +-0.000465f, +-7.667042f, +-0.000468f, +-7.662778f, +-0.000470f, +-7.658532f, +-0.000472f, +-7.652196f, +-0.000475f, +-7.647994f, +-0.000477f, +-7.641724f, +-0.000480f, +-7.637566f, +-0.000482f, +-7.631362f, +-0.000485f, +-7.627246f, +-0.000487f, +-7.623148f, +-0.000489f, +-7.617032f, +-0.000492f, +-7.612975f, +-0.000494f, +-7.606921f, +-0.000497f, +-7.602904f, +-0.000499f, +-7.596910f, +-0.000502f, +-7.592934f, +-0.000504f, +-7.587000f, +-0.000507f, +-7.581100f, +-0.000510f, +-7.577186f, +-0.000512f, +-7.571344f, +-0.000515f, +-7.567468f, +-0.000517f, +-7.561682f, +-0.000520f, +-7.557843f, +-0.000522f, +-7.552112f, +-0.000525f, +-7.546414f, +-0.000528f, +-7.542634f, +-0.000530f, +-7.536989f, +-0.000533f, +-7.531376f, +-0.000536f, +-7.527652f, +-0.000538f, +-7.522091f, +-0.000541f, +-7.516561f, +-0.000544f, +-7.511062f, +-0.000547f, +-7.507412f, +-0.000549f, +-7.501962f, +-0.000552f, +-7.496542f, +-0.000555f, +-7.491152f, +-0.000558f, +-7.487574f, +-0.000560f, +-7.482231f, +-0.000563f, +-7.476916f, +-0.000566f, +-7.471630f, +-0.000569f, +-7.466372f, +-0.000572f, +-7.462881f, +-0.000574f, +-7.457668f, +-0.000577f, +-7.452482f, +-0.000580f, +-7.447323f, +-0.000583f, +-7.442191f, +-0.000586f, +-7.437084f, +-0.000589f, +-7.432004f, +-0.000592f, +-7.426949f, +-0.000595f, +-7.421920f, +-0.000598f, +-7.416916f, +-0.000601f, +-7.411936f, +-0.000604f, +-7.406982f, +-0.000607f, +-7.402052f, +-0.000610f, +-7.397146f, +-0.000613f, +-7.392264f, +-0.000616f, +-7.387405f, +-0.000619f, +-7.382570f, +-0.000622f, +-7.377759f, +-0.000625f, +-7.372970f, +-0.000628f, +-7.368205f, +-0.000631f, +-7.363462f, +-0.000634f, +-7.358741f, +-0.000637f, +-7.352481f, +-0.000641f, +-7.347812f, +-0.000644f, +-7.343164f, +-0.000647f, +-7.338538f, +-0.000650f, +-7.333933f, +-0.000653f, +-7.327827f, +-0.000657f, +-7.323271f, +-0.000660f, +-7.318736f, +-0.000663f, +-7.314221f, +-0.000666f, +-7.308233f, +-0.000670f, +-7.303765f, +-0.000673f, +-7.299317f, +-0.000676f, +-7.293418f, +-0.000680f, +-7.289016f, +-0.000683f, +-7.284633f, +-0.000686f, +-7.278819f, +-0.000690f, +-7.274481f, +-0.000693f, +-7.270161f, +-0.000696f, +-7.264430f, +-0.000700f, +-7.260154f, +-0.000703f, +-7.254480f, +-0.000707f, +-7.250246f, +-0.000710f, +-7.244628f, +-0.000714f, +-7.240435f, +-0.000717f, +-7.234871f, +-0.000721f, +-7.230719f, +-0.000724f, +-7.225209f, +-0.000728f, +-7.221097f, +-0.000731f, +-7.215640f, +-0.000735f, +-7.210213f, +-0.000739f, +-7.206161f, +-0.000742f, +-7.200785f, +-0.000746f, +-7.196772f, +-0.000749f, +-7.191445f, +-0.000753f, +-7.186147f, +-0.000757f, +-7.182192f, +-0.000760f, +-7.176943f, +-0.000764f, +-7.171721f, +-0.000768f, +-7.166526f, +-0.000772f, +-7.162647f, +-0.000775f, +-7.157500f, +-0.000779f, +-7.152378f, +-0.000783f, +-7.147282f, +-0.000787f, +-7.142213f, +-0.000791f, +-7.138427f, +-0.000794f, +-7.133402f, +-0.000798f, +-7.128402f, +-0.000802f, +-7.123427f, +-0.000806f, +-7.118476f, +-0.000810f, +-7.113550f, +-0.000814f, +-7.108648f, +-0.000818f, +-7.103770f, +-0.000822f, +-7.098916f, +-0.000826f, +-7.094085f, +-0.000830f, +-7.089277f, +-0.000834f, +-7.084492f, +-0.000838f, +-7.079731f, +-0.000842f, +-7.074991f, +-0.000846f, +-7.070274f, +-0.000850f, +-7.065579f, +-0.000854f, +-7.060906f, +-0.000858f, +-7.055096f, +-0.000863f, +-7.050472f, +-0.000867f, +-7.045869f, +-0.000871f, +-7.041287f, +-0.000875f, +-7.036726f, +-0.000879f, +-7.031054f, +-0.000884f, +-7.026539f, +-0.000888f, +-7.022044f, +-0.000892f, +-7.017570f, +-0.000896f, +-7.012005f, +-0.000901f, +-7.007576f, +-0.000905f, +-7.003165f, +-0.000909f, +-6.997680f, +-0.000914f, +-6.993313f, +-0.000918f, +-6.987881f, +-0.000923f, +-6.983557f, +-0.000927f, +-6.979251f, +-0.000931f, +-6.973895f, +-0.000936f, +-6.969631f, +-0.000940f, +-6.964326f, +-0.000945f, +-6.960102f, +-0.000949f, +-6.954847f, +-0.000954f, +-6.949619f, +-0.000959f, +-6.945457f, +-0.000963f, +-6.940278f, +-0.000968f, +-6.936155f, +-0.000972f, +-6.931024f, +-0.000977f, +-6.925919f, +-0.000982f, +-6.921854f, +-0.000986f, +-6.916796f, +-0.000991f, +-6.911763f, +-0.000996f, +-6.906756f, +-0.001002f, +-6.902768f, +-0.001006f, +-6.897805f, +-0.001011f, +-6.892867f, +-0.001016f, +-6.887953f, +-0.001021f, +-6.883063f, +-0.001026f, +-6.878196f, +-0.001031f, +-6.874321f, +-0.001035f, +-6.869497f, +-0.001040f, +-6.864696f, +-0.001045f, +-6.859918f, +-0.001050f, +-6.855163f, +-0.001055f, +-6.850430f, +-0.001060f, +-6.845720f, +-0.001065f, +-6.841032f, +-0.001070f, +-6.836365f, +-0.001075f, +-6.830794f, +-0.001081f, +-6.826175f, +-0.001086f, +-6.821578f, +-0.001091f, +-6.817001f, +-0.001096f, +-6.812445f, +-0.001101f, +-6.807910f, +-0.001106f, +-6.802495f, +-0.001112f, +-6.798004f, +-0.001117f, +-6.793534f, +-0.001122f, +-6.789084f, +-0.001127f, +-6.783769f, +-0.001133f, +-6.779362f, +-0.001138f, +-6.774974f, +-0.001143f, +-6.769734f, +-0.001149f, +-6.765388f, +-0.001154f, +-6.760198f, +-0.001160f, +-6.755893f, +-0.001165f, +-6.750752f, +-0.001171f, +-6.746487f, +-0.001176f, +-6.741394f, +-0.001182f, +-6.737169f, +-0.001187f, +-6.732123f, +-0.001193f, +-6.727937f, +-0.001198f, +-6.722937f, +-0.001204f, +-6.717962f, +-0.001210f, +-6.713835f, +-0.001215f, +-6.708904f, +-0.001221f, +-6.703998f, +-0.001227f, +-6.699116f, +-0.001233f, +-6.695066f, +-0.001238f, +-6.690227f, +-0.001244f, +-6.685412f, +-0.001250f, +-6.680620f, +-0.001256f, +-6.675850f, +-0.001262f, +-6.671103f, +-0.001268f, +-6.666379f, +-0.001274f, +-6.662459f, +-0.001279f, +-6.657775f, +-0.001285f, +-6.653113f, +-0.001291f, +-6.648473f, +-0.001297f, +-6.643086f, +-0.001304f, +-6.638492f, +-0.001310f, +-6.633919f, +-0.001316f, +-6.629366f, +-0.001322f, +-6.624835f, +-0.001328f, +-6.620323f, +-0.001334f, +-6.615832f, +-0.001340f, +-6.610618f, +-0.001347f, +-6.606170f, +-0.001353f, +-6.601742f, +-0.001359f, +-6.597334f, +-0.001365f, +-6.592215f, +-0.001372f, +-6.587848f, +-0.001378f, +-6.582777f, +-0.001385f, +-6.578452f, +-0.001391f, +-6.573428f, +-0.001398f, +-6.569142f, +-0.001404f, +-6.564875f, +-0.001410f, +-6.559919f, +-0.001417f, +-6.554988f, +-0.001424f, +-6.550780f, +-0.001430f, +-6.545894f, +-0.001437f, +-6.541724f, +-0.001443f, +-6.536882f, +-0.001450f, +-6.532062f, +-0.001457f, +-6.527266f, +-0.001464f, +-6.523173f, +-0.001470f, +-6.518420f, +-0.001477f, +-6.513688f, +-0.001484f, +-6.508979f, +-0.001491f, +-6.504292f, +-0.001498f, +-6.500292f, +-0.001504f, +-6.495646f, +-0.001511f, +-6.491021f, +-0.001518f, +-6.486417f, +-0.001525f, +-6.481834f, +-0.001532f, +-6.477272f, +-0.001539f, +-6.472084f, +-0.001547f, +-6.467567f, +-0.001554f, +-6.463069f, +-0.001561f, +-6.458592f, +-0.001568f, +-6.454135f, +-0.001575f, +-6.449698f, +-0.001582f, +-6.444650f, +-0.001590f, +-6.440255f, +-0.001597f, +-6.435878f, +-0.001604f, +-6.430900f, +-0.001612f, +-6.426564f, +-0.001619f, +-6.422247f, +-0.001626f, +-6.417336f, +-0.001634f, +-6.413059f, +-0.001641f, +-6.408193f, +-0.001649f, +-6.403954f, +-0.001656f, +-6.399132f, +-0.001664f, +-6.394932f, +-0.001671f, +-6.390153f, +-0.001679f, +-6.385396f, +-0.001687f, +-6.381253f, +-0.001694f, +-6.376539f, +-0.001702f, +-6.371847f, +-0.001710f, +-6.367177f, +-0.001718f, +-6.362528f, +-0.001726f, +-6.358478f, +-0.001734f, +-6.353870f, +-0.001742f, +-6.349283f, +-0.001750f, +-6.344717f, +-0.001758f, +-6.340171f, +-0.001766f, +-6.335646f, +-0.001774f, +-6.331142f, +-0.001782f, +-6.326658f, +-0.001790f, +-6.322193f, +-0.001798f, +-6.317195f, +-0.001807f, +-6.312772f, +-0.001815f, +-6.308369f, +-0.001823f, +-6.303986f, +-0.001831f, +-6.299621f, +-0.001839f, +-6.294734f, +-0.001848f, +-6.290410f, +-0.001856f, +-6.285567f, +-0.001865f, +-6.281282f, +-0.001873f, +-6.277016f, +-0.001881f, +-6.272237f, +-0.001890f, +-6.268009f, +-0.001898f, +-6.263273f, +-0.001907f, +-6.258560f, +-0.001916f, +-6.254389f, +-0.001924f, +-6.249717f, +-0.001933f, +-6.245067f, +-0.001942f, +-6.240952f, +-0.001950f, +-6.236343f, +-0.001959f, +-6.231754f, +-0.001968f, +-6.227187f, +-0.001977f, +-6.222640f, +-0.001986f, +-6.218114f, +-0.001995f, +-6.214108f, +-0.002003f, +-6.209621f, +-0.002012f, +-6.204658f, +-0.002022f, +-6.200212f, +-0.002031f, +-6.195786f, +-0.002040f, +-6.191380f, +-0.002049f, +-6.186993f, +-0.002058f, +-6.182625f, +-0.002067f, +-6.178276f, +-0.002076f, +-6.173466f, +-0.002086f, +-6.169157f, +-0.002095f, +-6.164866f, +-0.002104f, +-6.160120f, +-0.002114f, +-6.155868f, +-0.002123f, +-6.151164f, +-0.002133f, +-6.146949f, +-0.002142f, +-6.142287f, +-0.002152f, +-6.138110f, +-0.002161f, +-6.133489f, +-0.002171f, +-6.128889f, +-0.002181f, +-6.124767f, +-0.002190f, +-6.120207f, +-0.002200f, +-6.115668f, +-0.002210f, +-6.111149f, +-0.002220f, +-6.106651f, +-0.002230f, +-6.102173f, +-0.002241f, +-6.097714f, +-0.002251f, +-6.093719f, +-0.002260f, +-6.088857f, +-0.002271f, +-6.084457f, +-0.002281f, +-6.080077f, +-0.002291f, +-6.075716f, +-0.002301f, +-6.071374f, +-0.002311f, +-6.067051f, +-0.002321f, +-6.062316f, +-0.002332f, +-6.058032f, +-0.002342f, +-6.053766f, +-0.002352f, +-6.049094f, +-0.002363f, +-6.044865f, +-0.002373f, +-6.040235f, +-0.002384f, +-6.036044f, +-0.002394f, +-6.031454f, +-0.002405f, +-6.027299f, +-0.002415f, +-6.022749f, +-0.002426f, +-6.018219f, +-0.002437f, +-6.014119f, +-0.002447f, +-6.009628f, +-0.002458f, +-6.005158f, +-0.002469f, +-6.000707f, +-0.002480f, +-5.996276f, +-0.002491f, +-5.991865f, +-0.002502f, +-5.987473f, +-0.002513f, +-5.983100f, +-0.002524f, +-5.978746f, +-0.002535f, +-5.974411f, +-0.002546f, +-5.970095f, +-0.002557f, +-5.965797f, +-0.002568f, +-5.961517f, +-0.002579f, +-5.956870f, +-0.002591f, +-5.952629f, +-0.002602f, +-5.948022f, +-0.002614f, +-5.943818f, +-0.002625f, +-5.939631f, +-0.002636f, +-5.935084f, +-0.002649f, +-5.930558f, +-0.002661f, +-5.926426f, +-0.002672f, +-5.921939f, +-0.002684f, +-5.917471f, +-0.002696f, +-5.913393f, +-0.002707f, +-5.908963f, +-0.002719f, +-5.904553f, +-0.002731f, +-5.900162f, +-0.002743f, +-5.895791f, +-0.002755f, +-5.891438f, +-0.002767f, +-5.887105f, +-0.002779f, +-5.882790f, +-0.002791f, +-5.878493f, +-0.002803f, +-5.874215f, +-0.002815f, +-5.869955f, +-0.002827f, +-5.865361f, +-0.002840f, +-5.861138f, +-0.002852f, +-5.856934f, +-0.002864f, +-5.852399f, +-0.002877f, +-5.848230f, +-0.002889f, +-5.843734f, +-0.002902f, +-5.839602f, +-0.002914f, +-5.835145f, +-0.002927f, +-5.830707f, +-0.002940f, +-5.826628f, +-0.002952f, +-5.822228f, +-0.002965f, +-5.817847f, +-0.002978f, +-5.813486f, +-0.002991f, +-5.809143f, +-0.003005f, +-5.804819f, +-0.003018f, +-5.800514f, +-0.003031f, +-5.796227f, +-0.003044f, +-5.791958f, +-0.003057f, +-5.787708f, +-0.003070f, +-5.783475f, +-0.003083f, +-5.779261f, +-0.003096f, +-5.774742f, +-0.003110f, +-5.770564f, +-0.003123f, +-5.766083f, +-0.003137f, +-5.761941f, +-0.003150f, +-5.757500f, +-0.003164f, +-5.753393f, +-0.003177f, +-5.748989f, +-0.003191f, +-5.744917f, +-0.003204f, +-5.740550f, +-0.003218f, +-5.736202f, +-0.003232f, +-5.731873f, +-0.003246f, +-5.727563f, +-0.003260f, +-5.723271f, +-0.003274f, +-5.718998f, +-0.003288f, +-5.714742f, +-0.003302f, +-5.710505f, +-0.003316f, +-5.706286f, +-0.003331f, +-5.702084f, +-0.003345f, +-5.697602f, +-0.003360f, +-5.693436f, +-0.003374f, +-5.689288f, +-0.003388f, +-5.684863f, +-0.003403f, +-5.680750f, +-0.003417f, +-5.676362f, +-0.003432f, +-5.672284f, +-0.003446f, +-5.667933f, +-0.003461f, +-5.663601f, +-0.003476f, +-5.659287f, +-0.003491f, +-5.655278f, +-0.003505f, +-5.651000f, +-0.003520f, +-5.646741f, +-0.003535f, +-5.642499f, +-0.003550f, +-5.638276f, +-0.003565f, +-5.634070f, +-0.003580f, +-5.629603f, +-0.003596f, +-5.625434f, +-0.003612f, +-5.621281f, +-0.003627f, +-5.617146f, +-0.003642f, +-5.612754f, +-0.003658f, +-5.608654f, +-0.003673f, +-5.604299f, +-0.003689f, +-5.600234f, +-0.003704f, +-5.595915f, +-0.003720f, +-5.591615f, +-0.003736f, +-5.587334f, +-0.003752f, +-5.583336f, +-0.003767f, +-5.579090f, +-0.003783f, +-5.574862f, +-0.003799f, +-5.570651f, +-0.003815f, +-5.566458f, +-0.003831f, +-5.562283f, +-0.003847f, +-5.557866f, +-0.003864f, +-5.553726f, +-0.003881f, +-5.549603f, +-0.003897f, +-5.545498f, +-0.003913f, +-5.541154f, +-0.003930f, +-5.537082f, +-0.003946f, +-5.532775f, +-0.003963f, +-5.528486f, +-0.003980f, +-5.524465f, +-0.003996f, +-5.520212f, +-0.004013f, +-5.515976f, +-0.004030f, +-5.511758f, +-0.004047f, +-5.507558f, +-0.004064f, +-5.503375f, +-0.004081f, +-5.499210f, +-0.004098f, +-5.495062f, +-0.004115f, +-5.490932f, +-0.004133f, +-5.486818f, +-0.004150f, +-5.482721f, +-0.004167f, +-5.478401f, +-0.004185f, +-5.474339f, +-0.004202f, +-5.470055f, +-0.004220f, +-5.466026f, +-0.004237f, +-5.461778f, +-0.004255f, +-5.457548f, +-0.004273f, +-5.453335f, +-0.004291f, +-5.449373f, +-0.004308f, +-5.445195f, +-0.004326f, +-5.441034f, +-0.004344f, +-5.436890f, +-0.004363f, +-5.432763f, +-0.004381f, +-5.428426f, +-0.004400f, +-5.424334f, +-0.004418f, +-5.420259f, +-0.004436f, +-5.416200f, +-0.004454f, +-5.411934f, +-0.004473f, +-5.407909f, +-0.004491f, +-5.403678f, +-0.004510f, +-5.399465f, +-0.004529f, +-5.395489f, +-0.004547f, +-5.391310f, +-0.004566f, +-5.387149f, +-0.004585f, +-5.383004f, +-0.004605f, +-5.378877f, +-0.004624f, +-5.374767f, +-0.004643f, +-5.370673f, +-0.004662f, +-5.366596f, +-0.004681f, +-5.362323f, +-0.004701f, +-5.358280f, +-0.004720f, +-5.354253f, +-0.004739f, +-5.350032f, +-0.004759f, +-5.346038f, +-0.004778f, +-5.341851f, +-0.004798f, +-5.337682f, +-0.004819f, +-5.333530f, +-0.004839f, +-5.329602f, +-0.004858f, +-5.325483f, +-0.004878f, +-5.321381f, +-0.004898f, +-5.317296f, +-0.004918f, +-5.313025f, +-0.004939f, +-5.308974f, +-0.004959f, +-5.304939f, +-0.004979f, +-5.300921f, +-0.004999f, +-5.296719f, +-0.005021f, +-5.292733f, +-0.005041f, +-5.288565f, +-0.005062f, +-5.284414f, +-0.005083f, +-5.280477f, +-0.005103f, +-5.276360f, +-0.005124f, +-5.272260f, +-0.005145f, +-5.268176f, +-0.005166f, +-5.264109f, +-0.005187f, +-5.260059f, +-0.005209f, +-5.256024f, +-0.005230f, +-5.251816f, +-0.005252f, +-5.247814f, +-0.005273f, +-5.243829f, +-0.005294f, +-5.239671f, +-0.005316f, +-5.235530f, +-0.005338f, +-5.231594f, +-0.005359f, +-5.227486f, +-0.005381f, +-5.223395f, +-0.005404f, +-5.219321f, +-0.005426f, +-5.215264f, +-0.005448f, +-5.211223f, +-0.005470f, +-5.207198f, +-0.005492f, +-5.203189f, +-0.005514f, +-5.199196f, +-0.005536f, +-5.195039f, +-0.005559f, +-5.191079f, +-0.005582f, +-5.186955f, +-0.005605f, +-5.183026f, +-0.005627f, +-5.178936f, +-0.005650f, +-5.174862f, +-0.005673f, +-5.170804f, +-0.005696f, +-5.166763f, +-0.005719f, +-5.162738f, +-0.005742f, +-5.158729f, +-0.005766f, +-5.154737f, +-0.005789f, +-5.150760f, +-0.005812f, +-5.146627f, +-0.005836f, +-5.142682f, +-0.005859f, +-5.138582f, +-0.005883f, +-5.134669f, +-0.005906f, +-5.130602f, +-0.005931f, +-5.126551f, +-0.005955f, +-5.122517f, +-0.005979f, +-5.118666f, +-0.006002f, +-5.114497f, +-0.006027f, +-5.110511f, +-0.006051f, +-5.106541f, +-0.006075f, +-5.102586f, +-0.006100f, +-5.098483f, +-0.006125f, +-5.094561f, +-0.006149f, +-5.090491f, +-0.006174f, +-5.086599f, +-0.006198f, +-5.082561f, +-0.006223f, +-5.078539f, +-0.006248f, +-5.074534f, +-0.006274f, +-5.070545f, +-0.006299f, +-5.066571f, +-0.006324f, +-5.062613f, +-0.006349f, +-5.058671f, +-0.006374f, +-5.054744f, +-0.006399f, +-5.050676f, +-0.006426f, +-5.046781f, +-0.006451f, +-5.042745f, +-0.006477f, +-5.038726f, +-0.006503f, +-5.034877f, +-0.006528f, +-5.030889f, +-0.006554f, +-5.026917f, +-0.006581f, +-5.022961f, +-0.006607f, +-5.018869f, +-0.006634f, +-5.014945f, +-0.006660f, +-5.011035f, +-0.006686f, +-5.006992f, +-0.006713f, +-5.003114f, +-0.006740f, +-4.999102f, +-0.006767f, +-4.995254f, +-0.006793f, +-4.991274f, +-0.006820f, +-4.987309f, +-0.006847f, +-4.983361f, +-0.006875f, +-4.979427f, +-0.006902f, +-4.975509f, +-0.006929f, +-4.971463f, +-0.006957f, +-4.967576f, +-0.006984f, +-4.963561f, +-0.007013f, +-4.959705f, +-0.007040f, +-4.955721f, +-0.007068f, +-4.951753f, +-0.007096f, +-4.947942f, +-0.007123f, +-4.944005f, +-0.007152f, +-4.940084f, +-0.007180f, +-4.936038f, +-0.007209f, +-4.932148f, +-0.007237f, +-4.928272f, +-0.007265f, +-4.924274f, +-0.007295f, +-4.920429f, +-0.007323f, +-4.916462f, +-0.007352f, +-4.912647f, +-0.007380f, +-4.908711f, +-0.007409f, +-4.904790f, +-0.007439f, +-4.900884f, +-0.007468f, +-4.896994f, +-0.007497f, +-4.892986f, +-0.007527f, +-4.889126f, +-0.007556f, +-4.885281f, +-0.007586f, +-4.881319f, +-0.007616f, +-4.877373f, +-0.007646f, +-4.873573f, +-0.007675f, +-4.869657f, +-0.007706f, +-4.865756f, +-0.007736f, +-4.861870f, +-0.007766f, +-4.858000f, +-0.007796f, +-4.854144f, +-0.007827f, +-4.850176f, +-0.007858f, +-4.846350f, +-0.007888f, +-4.842413f, +-0.007919f, +-4.838490f, +-0.007951f, +-4.834709f, +-0.007981f, +-4.830817f, +-0.008012f, +-4.826940f, +-0.008043f, +-4.823077f, +-0.008075f, +-4.819230f, +-0.008106f, +-4.815274f, +-0.008138f, +-4.811457f, +-0.008169f, +-4.807531f, +-0.008202f, +-4.803743f, +-0.008233f, +-4.799848f, +-0.008265f, +-4.795968f, +-0.008297f, +-4.792102f, +-0.008330f, +-4.788252f, +-0.008362f, +-4.784416f, +-0.008394f, +-4.780596f, +-0.008426f, +-4.776671f, +-0.008460f, +-4.772879f, +-0.008492f, +-4.768984f, +-0.008525f, +-4.765222f, +-0.008558f, +-4.761356f, +-0.008591f, +-4.757506f, +-0.008624f, +-4.753670f, +-0.008657f, +-4.749849f, +-0.008691f, +-4.745928f, +-0.008725f, +-4.742136f, +-0.008758f, +-4.738245f, +-0.008793f, +-4.734482f, +-0.008826f, +-4.730620f, +-0.008860f, +-4.726773f, +-0.008894f, +-4.722941f, +-0.008929f, +-4.719123f, +-0.008963f, +-4.715320f, +-0.008997f, +-4.711531f, +-0.009032f, +-4.707646f, +-0.009067f, +-4.703886f, +-0.009101f, +-4.700030f, +-0.009137f, +-4.696190f, +-0.009172f, +-4.692473f, +-0.009206f, +-4.688661f, +-0.009242f, +-4.684863f, +-0.009277f, +-4.680972f, +-0.009313f, +-4.677203f, +-0.009349f, +-4.673449f, +-0.009384f, +-4.669602f, +-0.009420f, +-4.665770f, +-0.009457f, +-4.661952f, +-0.009493f, +-4.658255f, +-0.009528f, +-4.654360f, +-0.009566f, +-4.650586f, +-0.009602f, +-4.646826f, +-0.009638f, +-4.643080f, +-0.009675f, +-4.639244f, +-0.009712f, +-4.635423f, +-0.009749f, +-4.631720f, +-0.009786f, +-4.627927f, +-0.009823f, +-4.624149f, +-0.009860f, +-4.620385f, +-0.009898f, +-4.616535f, +-0.009936f, +-4.612799f, +-0.009974f, +-4.609078f, +-0.010011f, +-4.605270f, +-0.010049f, +-4.601477f, +-0.010088f, +-4.597698f, +-0.010126f, +-4.593934f, +-0.010164f, +-4.590183f, +-0.010203f, +-4.586447f, +-0.010241f, +-4.582724f, +-0.010280f, +-4.578918f, +-0.010319f, +-4.575126f, +-0.010358f, +-4.571445f, +-0.010397f, +-4.567682f, +-0.010436f, +-4.563932f, +-0.010476f, +-4.560197f, +-0.010515f, +-4.556380f, +-0.010556f, +-4.552673f, +-0.010595f, +-4.548884f, +-0.010635f, +-4.545205f, +-0.010675f, +-4.541445f, +-0.010715f, +-4.537698f, +-0.010756f, +-4.533966f, +-0.010796f, +-4.530248f, +-0.010837f, +-4.526544f, +-0.010877f, +-4.522761f, +-0.010918f, +-4.519084f, +-0.010959f, +-4.515329f, +-0.011000f, +-4.511589f, +-0.011042f, +-4.507862f, +-0.011083f, +-4.504149f, +-0.011125f, +-4.500450f, +-0.011166f, +-4.496675f, +-0.011209f, +-4.493003f, +-0.011250f, +-4.489256f, +-0.011293f, +-4.485611f, +-0.011334f, +-4.481891f, +-0.011376f, +-4.478185f, +-0.011419f, +-4.474405f, +-0.011462f, +-4.470727f, +-0.011505f, +-4.467062f, +-0.011547f, +-4.463323f, +-0.011591f, +-4.459599f, +-0.011634f, +-4.455975f, +-0.011677f, +-4.452277f, +-0.011720f, +-4.448508f, +-0.011765f, +-4.444839f, +-0.011808f, +-4.441182f, +-0.011852f, +-4.437455f, +-0.011896f, +-4.433825f, +-0.011940f, +-4.430125f, +-0.011985f, +-4.426438f, +-0.012029f, +-4.422765f, +-0.012074f, +-4.419023f, +-0.012119f, +-4.415377f, +-0.012164f, +-4.411661f, +-0.012209f, +-4.408042f, +-0.012254f, +-4.404354f, +-0.012299f, +-4.400680f, +-0.012345f, +-4.397018f, +-0.012390f, +-4.393371f, +-0.012436f, +-4.389656f, +-0.012483f, +-4.386035f, +-0.012528f, +-4.382347f, +-0.012575f, +-4.378672f, +-0.012621f, +-4.375011f, +-0.012668f, +-4.371364f, +-0.012714f, +-4.367729f, +-0.012761f, +-4.364108f, +-0.012808f, +-4.360422f, +-0.012855f, +-4.356749f, +-0.012903f, +-4.353089f, +-0.012950f, +-4.349443f, +-0.012998f, +-4.345810f, +-0.013046f, +-4.342191f, +-0.013093f, +-4.338584f, +-0.013141f, +-4.334914f, +-0.013190f, +-4.331257f, +-0.013238f, +-4.327614f, +-0.013287f, +-4.323984f, +-0.013336f, +-4.320367f, +-0.013384f, +-4.316763f, +-0.013433f, +-4.313098f, +-0.013482f, +-4.309520f, +-0.013531f, +-4.305881f, +-0.013581f, +-4.302255f, +-0.013630f, +-4.298642f, +-0.013680f, +-4.294969f, +-0.013731f, +-4.291382f, +-0.013781f, +-4.287735f, +-0.013831f, +-4.284174f, +-0.013881f, +-4.280554f, +-0.013932f, +-4.276946f, +-0.013982f, +-4.273352f, +-0.014033f, +-4.269698f, +-0.014085f, +-4.266130f, +-0.014135f, +-4.262503f, +-0.014187f, +-4.258889f, +-0.014239f, +-4.255288f, +-0.014291f, +-4.251700f, +-0.014342f, +-4.248125f, +-0.014394f, +-4.244493f, +-0.014447f, +-4.240944f, +-0.014499f, +-4.237338f, +-0.014551f, +-4.233745f, +-0.014604f, +-4.230164f, +-0.014657f, +-4.226597f, +-0.014710f, +-4.222974f, +-0.014763f, +-4.219432f, +-0.014816f, +-4.215834f, +-0.014870f, +-4.212250f, +-0.014924f, +-4.208679f, +-0.014978f, +-4.205120f, +-0.015031f, +-4.201573f, +-0.015085f, +-4.197973f, +-0.015140f, +-4.194386f, +-0.015195f, +-4.190811f, +-0.015250f, +-4.187250f, +-0.015305f, +-4.183700f, +-0.015359f, +-4.180164f, +-0.015414f, +-4.176575f, +-0.015470f, +-4.172998f, +-0.015526f, +-4.169499f, +-0.015581f, +-4.165948f, +-0.015637f, +-4.162345f, +-0.015694f, +-4.158819f, +-0.015749f, +-4.155242f, +-0.015806f, +-4.151741f, +-0.015862f, +-4.148189f, +-0.015919f, +-4.144649f, +-0.015976f, +-4.141059f, +-0.016034f, +-4.137544f, +-0.016091f, +-4.133980f, +-0.016149f, +-4.130490f, +-0.016206f, +-4.126950f, +-0.016264f, +-4.123423f, +-0.016321f, +-4.119847f, +-0.016380f, +-4.116345f, +-0.016438f, +-4.112794f, +-0.016497f, +-4.109316f, +-0.016555f, +-4.105790f, +-0.016614f, +-4.102216f, +-0.016674f, +-4.098714f, +-0.016733f, +-4.095225f, +-0.016792f, +-4.091688f, +-0.016852f, +-4.088164f, +-0.016912f, +-4.084652f, +-0.016972f, +-4.081152f, +-0.017032f, +-4.077664f, +-0.017092f, +-4.074130f, +-0.017153f, +-4.070608f, +-0.017214f, +-4.067099f, +-0.017275f, +-4.063602f, +-0.017336f, +-4.060117f, +-0.017397f, +-4.056644f, +-0.017459f, +-4.053126f, +-0.017521f, +-4.049620f, +-0.017583f, +-4.046126f, +-0.017645f, +-4.042644f, +-0.017707f, +-4.039175f, +-0.017769f, +-4.035661f, +-0.017832f, +-4.032159f, +-0.017895f, +-4.028669f, +-0.017958f, +-4.025192f, +-0.018021f, +-4.021726f, +-0.018085f, +-4.018273f, +-0.018148f, +-4.014776f, +-0.018212f, +-4.011291f, +-0.018276f, +-4.007818f, +-0.018340f, +-4.004358f, +-0.018404f, +-4.000854f, +-0.018470f, +-3.997417f, +-0.018534f, +-3.993938f, +-0.018599f, +-3.990471f, +-0.018664f, +-3.987016f, +-0.018729f, +-3.983573f, +-0.018795f, +-3.980088f, +-0.018861f, +-3.976615f, +-0.018927f, +-3.973154f, +-0.018993f, +-3.969705f, +-0.019059f, +-3.966268f, +-0.019126f, +-3.962843f, +-0.019192f, +-3.959377f, +-0.019259f, +-3.955923f, +-0.019327f, +-3.952480f, +-0.019394f, +-3.949050f, +-0.019461f, +-3.945580f, +-0.019529f, +-3.942173f, +-0.019597f, +-3.938726f, +-0.019665f, +-3.935292f, +-0.019733f, +-3.931818f, +-0.019803f, +-3.928407f, +-0.019871f, +-3.924956f, +-0.019940f, +-3.921568f, +-0.020009f, +-3.918142f, +-0.020078f, +-3.914677f, +-0.020149f, +-3.911273f, +-0.020218f, +-3.907832f, +-0.020288f, +-3.904452f, +-0.020358f, +-3.900984f, +-0.020429f, +-3.897578f, +-0.020500f, +-3.894183f, +-0.020570f, +-3.890751f, +-0.020642f, +-3.887330f, +-0.020713f, +-3.883922f, +-0.020785f, +-3.880524f, +-0.020856f, +-3.877139f, +-0.020927f, +-3.873716f, +-0.021000f, +-3.870305f, +-0.021072f, +-3.866906f, +-0.021145f, +-3.863519f, +-0.021218f, +-3.860142f, +-0.021290f, +-3.856730f, +-0.021364f, +-3.853330f, +-0.021437f, +-3.849941f, +-0.021511f, +-3.846563f, +-0.021584f, +-3.843150f, +-0.021659f, +-3.839795f, +-0.021732f, +-3.836405f, +-0.021807f, +-3.833027f, +-0.021882f, +-3.829614f, +-0.021957f, +-3.826258f, +-0.022032f, +-3.822868f, +-0.022108f, +-3.819489f, +-0.022183f, +-3.816122f, +-0.022259f, +-3.812721f, +-0.022336f, +-3.809376f, +-0.022411f, +-3.805998f, +-0.022488f, +-3.802631f, +-0.022565f, +-3.799275f, +-0.022641f, +-3.795886f, +-0.022719f, +-3.792552f, +-0.022796f, +-3.789186f, +-0.022874f, +-3.785831f, +-0.022951f, +-3.782487f, +-0.023029f, +-3.779111f, +-0.023108f, +-3.775745f, +-0.023187f, +-3.772392f, +-0.023266f, +-3.769049f, +-0.023344f, +-3.765717f, +-0.023423f, +-3.762354f, +-0.023503f, +-3.759002f, +-0.023583f, +-3.755661f, +-0.023663f, +-3.752331f, +-0.023743f, +-3.749012f, +-0.023823f, +-3.745661f, +-0.023903f, +-3.742322f, +-0.023984f, +-3.738994f, +-0.024065f, +-3.735678f, +-0.024146f, +-3.732330f, +-0.024228f, +-3.728993f, +-0.024310f, +-3.725668f, +-0.024392f, +-3.722354f, +-0.024474f, +-3.719009f, +-0.024557f, +-3.715716f, +-0.024639f, +-3.712394f, +-0.024722f, +-3.709082f, +-0.024805f, +-3.705741f, +-0.024889f, +-3.702451f, +-0.024972f, +-3.699132f, +-0.025056f, +-3.695824f, +-0.025140f, +-3.692486f, +-0.025226f, +-3.689199f, +-0.025310f, +-3.685884f, +-0.025395f, +-3.682579f, +-0.025480f, +-3.679286f, +-0.025565f, +-3.676003f, +-0.025650f, +-3.672691f, +-0.025736f, +-3.669391f, +-0.025823f, +-3.666101f, +-0.025909f, +-3.662822f, +-0.025995f, +-3.659515f, +-0.026082f, +-3.656219f, +-0.026169f, +-3.652933f, +-0.026257f, +-3.649659f, +-0.026344f, +-3.646356f, +-0.026432f, +-3.643065f, +-0.026521f, +-3.639785f, +-0.026609f, +-3.636515f, +-0.026697f, +-3.633256f, +-0.026786f, +-3.629969f, +-0.026875f, +-3.626694f, +-0.026964f, +-3.623429f, +-0.027054f, +-3.620137f, +-0.027144f, +-3.616894f, +-0.027233f, +-3.613624f, +-0.027324f, +-3.610364f, +-0.027414f, +-3.607078f, +-0.027506f, +-3.603840f, +-0.027596f, +-3.600576f, +-0.027688f, +-3.597322f, +-0.027779f, +-3.594042f, +-0.027872f, +-3.590809f, +-0.027963f, +-3.587551f, +-0.028056f, +-3.584303f, +-0.028148f, +-3.581066f, +-0.028241f, +-3.577803f, +-0.028335f, +-3.574551f, +-0.028428f, +-3.571310f, +-0.028522f, +-3.568079f, +-0.028616f, +-3.564823f, +-0.028710f, +-3.561577f, +-0.028805f, +-3.558343f, +-0.028900f, +-3.555118f, +-0.028994f, +-3.551904f, +-0.029089f, +-3.548665f, +-0.029185f, +-3.545437f, +-0.029281f, +-3.542185f, +-0.029377f, +-3.538978f, +-0.029473f, +-3.535746f, +-0.029570f, +-3.532525f, +-0.029667f, +-3.529315f, +-0.029764f, +-3.526081f, +-0.029861f, +-3.522857f, +-0.029959f, +-3.519643f, +-0.030057f, +-3.516440f, +-0.030155f, +-3.513213f, +-0.030254f, +-3.510031f, +-0.030352f, +-3.506825f, +-0.030451f, +-3.503596f, +-0.030551f, +-3.500410f, +-0.030650f, +-3.497202f, +-0.030750f, +-3.494004f, +-0.030850f, +-3.490783f, +-0.030951f, +-3.487605f, +-0.031051f, +-3.484405f, +-0.031152f, +-3.481215f, +-0.031253f, +-3.478003f, +-0.031355f, +-3.474833f, +-0.031457f, +-3.471641f, +-0.031559f, +-3.468428f, +-0.031662f, +-3.465256f, +-0.031764f, +-3.462063f, +-0.031867f, +-3.458879f, +-0.031971f, +-3.455706f, +-0.032074f, +-3.452543f, +-0.032177f, +-3.449359f, +-0.032281f, +-3.446184f, +-0.032386f, +-3.443020f, +-0.032490f, +-3.439834f, +-0.032596f, +-3.436659f, +-0.032701f, +-3.433493f, +-0.032806f, +-3.430338f, +-0.032912f, +-3.427162f, +-0.033018f, +-3.423995f, +-0.033125f, +-3.420839f, +-0.033231f, +-3.417693f, +-0.033338f, +-3.414526f, +-0.033445f, +-3.411369f, +-0.033553f, +-3.408222f, +-0.033660f, +-3.405055f, +-0.033769f, +-3.401898f, +-0.033877f, +-3.398750f, +-0.033986f, +-3.395613f, +-0.034095f, +-3.392456f, +-0.034204f, +-3.389338f, +-0.034313f, +-3.386171f, +-0.034424f, +-3.383043f, +-0.034533f, +-3.379896f, +-0.034644f, +-3.376758f, +-0.034755f, +-3.373631f, +-0.034866f, +-3.370513f, +-0.034977f, +-3.367376f, +-0.035088f, +-3.364248f, +-0.035200f, +-3.361102f, +-0.035313f, +-3.357994f, +-0.035425f, +-3.354867f, +-0.035538f, +-3.351750f, +-0.035651f, +-3.348614f, +-0.035765f, +-3.345488f, +-0.035879f, +-3.342372f, +-0.035993f, +-3.339265f, +-0.036107f, +-3.336140f, +-0.036222f, +-3.333053f, +-0.036336f, +-3.329919f, +-0.036452f, +-3.326823f, +-0.036568f, +-3.323709f, +-0.036684f, +-3.320604f, +-0.036800f, +-3.317509f, +-0.036916f, +-3.314396f, +-0.037033f, +-3.311293f, +-0.037151f, +-3.308199f, +-0.037268f, +-3.305115f, +-0.037385f, +-3.302013f, +-0.037504f, +-3.298921f, +-0.037622f, +-3.295838f, +-0.037740f, +-3.292738f, +-0.037860f, +-3.289647f, +-0.037979f, +-3.286566f, +-0.038099f, +-3.283494f, +-0.038218f, +-3.280406f, +-0.038339f, +-3.277326f, +-0.038459f, +-3.274230f, +-0.038581f, +-3.271170f, +-0.038701f, +-3.268092f, +-0.038823f, +-3.265024f, +-0.038945f, +-3.261940f, +-0.039067f, +-3.258865f, +-0.039190f, +-3.255799f, +-0.039313f, +-3.252743f, +-0.039435f, +-3.249670f, +-0.039559f, +-3.246607f, +-0.039683f, +-3.243553f, +-0.039807f, +-3.240483f, +-0.039932f, +-3.237422f, +-0.040057f, +-3.234370f, +-0.040182f, +-3.231303f, +-0.040308f, +-3.228270f, +-0.040432f, +-3.225221f, +-0.040558f, +-3.222156f, +-0.040686f, +-3.219126f, +-0.040812f, +-3.216080f, +-0.040939f, +-3.213018f, +-0.041067f, +-3.209990f, +-0.041194f, +-3.206947f, +-0.041322f, +-3.203913f, +-0.041450f, +-3.200864f, +-0.041580f, +-3.197824f, +-0.041709f, +-3.194793f, +-0.041838f, +-3.191771f, +-0.041967f, +-3.188735f, +-0.042098f, +-3.185707f, +-0.042228f, +-3.182689f, +-0.042359f, +-3.179655f, +-0.042490f, +-3.176631f, +-0.042622f, +-3.173616f, +-0.042753f, +-3.170586f, +-0.042886f, +-3.167565f, +-0.043018f, +-3.164553f, +-0.043151f, +-3.161527f, +-0.043284f, +-3.158534f, +-0.043417f, +-3.155502f, +-0.043552f, +-3.152503f, +-0.043685f, +-3.149490f, +-0.043820f, +-3.146485f, +-0.043955f, +-3.143490f, +-0.044090f, +-3.140481f, +-0.044226f, +-3.137480f, +-0.044362f, +-3.134489f, +-0.044497f, +-3.131483f, +-0.044634f, +-3.128487f, +-0.044771f, +-3.125499f, +-0.044908f, +-3.122498f, +-0.045047f, +-3.119506f, +-0.045185f, +-3.116522f, +-0.045323f, +-3.113548f, +-0.045461f, +-3.110560f, +-0.045600f, +-3.107558f, +-0.045740f, +-3.104588f, +-0.045880f, +-3.101604f, +-0.046020f, +-3.098629f, +-0.046160f, +-3.095663f, +-0.046301f, +-3.092684f, +-0.046442f, +-3.089713f, +-0.046583f, +-3.086730f, +-0.046726f, +-3.083755f, +-0.046868f, +-3.080789f, +-0.047011f, +-3.077832f, +-0.047153f, +-3.074862f, +-0.047297f, +-3.071901f, +-0.047441f, +-3.068948f, +-0.047584f, +-3.065983f, +-0.047729f, +-3.063027f, +-0.047874f, +-3.060079f, +-0.048019f, +-3.057118f, +-0.048165f, +-3.054167f, +-0.048310f, +-3.051203f, +-0.048457f, +-3.048268f, +-0.048603f, +-3.045322f, +-0.048750f, +-3.042363f, +-0.048898f, +-3.039433f, +-0.049045f, +-3.036492f, +-0.049193f, +-3.033538f, +-0.049343f, +-3.030614f, +-0.049491f, +-3.027677f, +-0.049640f, +-3.024729f, +-0.049790f, +-3.021809f, +-0.049939f, +-3.018878f, +-0.050090f, +-3.015935f, +-0.050241f, +-3.013021f, +-0.050392f, +-3.010075f, +-0.050544f, +-3.007157f, +-0.050696f, +-3.004228f, +-0.050848f, +-3.001308f, +-0.051001f, +-2.998396f, +-0.051153f, +-2.995472f, +-0.051307f, +-2.992557f, +-0.051461f, +-2.989651f, +-0.051614f, +-2.986733f, +-0.051769f, +-2.983823f, +-0.051924f, +-2.980922f, +-0.052079f, +-2.978010f, +-0.052235f, +-2.975106f, +-0.052391f, +-2.972192f, +-0.052548f, +-2.969305f, +-0.052704f, +-2.966387f, +-0.052862f, +-2.963497f, +-0.053019f, +-2.960597f, +-0.053177f, +-2.957705f, +-0.053335f, +-2.954802f, +-0.053495f, +-2.951926f, +-0.053653f, +-2.949020f, +-0.053813f, +-2.946142f, +-0.053973f, +-2.943254f, +-0.054133f, +-2.940373f, +-0.054294f, +-2.937482f, +-0.054455f, +-2.934600f, +-0.054617f, +-2.931725f, +-0.054778f, +-2.928840f, +-0.054941f, +-2.925964f, +-0.055104f, +-2.923095f, +-0.055266f, +-2.920217f, +-0.055430f, +-2.917346f, +-0.055594f, +-2.914484f, +-0.055758f, +-2.911612f, +-0.055923f, +-2.908748f, +-0.056088f, +-2.905873f, +-0.056254f, +-2.903025f, +-0.056419f, +-2.900149f, +-0.056586f, +-2.897300f, +-0.056752f, +-2.894440f, +-0.056920f, +-2.891588f, +-0.057087f, +-2.888727f, +-0.057255f, +-2.885874f, +-0.057424f, +-2.883029f, +-0.057592f, +-2.880174f, +-0.057762f, +-2.877327f, +-0.057931f, +-2.874489f, +-0.058101f, +-2.871640f, +-0.058271f, +-2.868800f, +-0.058442f, +-2.865950f, +-0.058614f, +-2.863126f, +-0.058784f, +-2.860275f, +-0.058957f, +-2.857450f, +-0.059129f, +-2.854615f, +-0.059302f, +-2.851788f, +-0.059475f, +-2.848952f, +-0.059649f, +-2.846123f, +-0.059823f, +-2.843303f, +-0.059997f, +-2.840474f, +-0.060173f, +-2.837652f, +-0.060348f, +-2.834822f, +-0.060524f, +-2.831999f, +-0.060701f, +-2.829185f, +-0.060877f, +-2.826378f, +-0.061053f, +-2.823562f, +-0.061231f, +-2.820737f, +-0.061410f, +-2.817938f, +-0.061587f, +-2.815129f, +-0.061766f, +-2.812311f, +-0.061946f, +-2.809502f, +-0.062125f, +-2.806700f, +-0.062305f, +-2.803906f, +-0.062485f, +-2.801103f, +-0.062666f, +-2.798292f, +-0.062848f, +-2.795505f, +-0.063029f, +-2.792710f, +-0.063211f, +-2.789906f, +-0.063395f, +-2.787126f, +-0.063577f, +-2.784321f, +-0.063761f, +-2.781541f, +-0.063945f, +-2.778752f, +-0.064129f, +-2.775970f, +-0.064313f, +-2.773181f, +-0.064499f, +-2.770399f, +-0.064685f, +-2.767625f, +-0.064870f, +-2.764843f, +-0.065057f, +-2.762068f, +-0.065244f, +-2.759286f, +-0.065432f, +-2.756511f, +-0.065620f, +-2.753743f, +-0.065808f, +-2.750968f, +-0.065997f, +-2.748201f, +-0.066186f, +-2.745441f, +-0.066375f, +-2.742673f, +-0.066565f, +-2.739912f, +-0.066755f, +-2.737144f, +-0.066947f, +-2.734384f, +-0.067138f, +-2.731631f, +-0.067330f, +-2.728870f, +-0.067522f, +-2.726117f, +-0.067715f, +-2.723357f, +-0.067908f, +-2.720604f, +-0.068102f, +-2.717858f, +-0.068296f, +-2.715105f, +-0.068491f, +-2.712359f, +-0.068686f, +-2.709621f, +-0.068881f, +-2.706876f, +-0.069077f, +-2.704138f, +-0.069273f, +-2.701392f, +-0.069470f, +-2.698655f, +-0.069667f, +-2.695924f, +-0.069865f, +-2.693186f, +-0.070063f, +-2.690456f, +-0.070262f, +-2.687718f, +-0.070461f, +-2.684988f, +-0.070661f, +-2.682266f, +-0.070860f, +-2.679536f, +-0.071061f, +-2.676813f, +-0.071262f, +-2.674098f, +-0.071463f, +-2.671376f, +-0.071665f, +-2.668647f, +-0.071868f, +-2.665939f, +-0.072070f, +-2.663211f, +-0.072274f, +-2.660504f, +-0.072477f, +-2.657790f, +-0.072681f, +-2.655083f, +-0.072886f, +-2.652370f, +-0.073091f, +-2.649663f, +-0.073297f, +-2.646950f, +-0.073503f, +-2.644259f, +-0.073709f, +-2.641546f, +-0.073917f, +-2.638855f, +-0.074124f, +-2.636158f, +-0.074331f, +-2.633453f, +-0.074540f, +-2.630756f, +-0.074749f, +-2.628066f, +-0.074958f, +-2.625369f, +-0.075169f, +-2.622680f, +-0.075379f, +-2.619998f, +-0.075589f, +-2.617310f, +-0.075801f, +-2.614614f, +-0.076013f, +-2.611940f, +-0.076225f, +-2.609260f, +-0.076437f, +-2.606573f, +-0.076651f, +-2.603893f, +-0.076865f, +-2.601220f, +-0.077079f, +-2.598541f, +-0.077294f, +-2.595870f, +-0.077509f, +-2.593191f, +-0.077725f, +-2.590534f, +-0.077940f, +-2.587857f, +-0.078157f, +-2.585187f, +-0.078375f, +-2.582524f, +-0.078592f, +-2.579868f, +-0.078809f, +-2.577206f, +-0.079028f, +-2.574538f, +-0.079248f, +-2.571877f, +-0.079468f, +-2.569223f, +-0.079687f, +-2.566577f, +-0.079907f, +-2.563924f, +-0.080128f, +-2.561265f, +-0.080350f, +-2.558613f, +-0.080573f, +-2.555969f, +-0.080795f, +-2.553318f, +-0.081018f, +-2.550675f, +-0.081242f, +-2.548038f, +-0.081465f, +-2.545396f, +-0.081690f, +-2.542748f, +-0.081915f, +-2.540119f, +-0.082140f, +-2.537472f, +-0.082367f, +-2.534845f, +-0.082593f, +-2.532212f, +-0.082820f, +-2.529574f, +-0.083048f, +-2.526954f, +-0.083275f, +-2.524317f, +-0.083504f, +-2.521699f, +-0.083733f, +-2.519076f, +-0.083962f, +-2.516447f, +-0.084193f, +-2.513825f, +-0.084423f, +-2.511210f, +-0.084654f, +-2.508589f, +-0.084886f, +-2.505975f, +-0.085118f, +-2.503356f, +-0.085351f, +-2.500743f, +-0.085584f, +-2.498138f, +-0.085817f, +-2.495527f, +-0.086051f, +-2.492911f, +-0.086287f, +-2.490313f, +-0.086521f, +-2.487711f, +-0.086757f, +-2.485103f, +-0.086994f, +-2.482502f, +-0.087230f, +-2.479907f, +-0.087467f, +-2.477308f, +-0.087705f, +-2.474703f, +-0.087944f, +-2.472117f, +-0.088182f, +-2.469526f, +-0.088421f, +-2.466929f, +-0.088662f, +-2.464340f, +-0.088902f, +-2.461757f, +-0.089143f, +-2.459169f, +-0.089384f, +-2.456587f, +-0.089626f, +-2.454001f, +-0.089869f, +-2.451422f, +-0.090112f, +-2.448837f, +-0.090356f, +-2.446259f, +-0.090600f, +-2.443688f, +-0.090844f, +-2.441112f, +-0.091089f, +-2.438542f, +-0.091335f, +-2.435968f, +-0.091581f, +-2.433400f, +-0.091828f, +-2.430828f, +-0.092076f, +-2.428262f, +-0.092324f, +-2.425702f, +-0.092572f, +-2.423138f, +-0.092821f, +-2.420581f, +-0.093070f, +-2.418018f, +-0.093320f, +-2.415463f, +-0.093570f, +-2.412902f, +-0.093822f, +-2.410349f, +-0.094073f, +-2.407801f, +-0.094325f, +-2.405249f, +-0.094578f, +-2.402704f, +-0.094831f, +-2.400154f, +-0.095085f, +-2.397610f, +-0.095339f, +-2.395062f, +-0.095594f, +-2.392521f, +-0.095849f, +-2.389975f, +-0.096106f, +-2.387446f, +-0.096361f, +-2.384902f, +-0.096619f, +-2.382365f, +-0.096877f, +-2.379833f, +-0.097134f, +-2.377298f, +-0.097393f, +-2.374769f, +-0.097653f, +-2.372246f, +-0.097912f, +-2.369719f, +-0.098172f, +-2.367188f, +-0.098433f, +-2.364663f, +-0.098695f, +-2.362144f, +-0.098957f, +-2.359621f, +-0.099219f, +-2.357105f, +-0.099482f, +-2.354584f, +-0.099746f, +-2.352069f, +-0.100010f, +-2.349551f, +-0.100276f, +-2.347039f, +-0.100541f, +-2.344533f, +-0.100806f, +-2.342023f, +-0.101073f, +-2.339519f, +-0.101340f, +-2.337011f, +-0.101608f, +-2.334509f, +-0.101875f, +-2.332004f, +-0.102145f, +-2.329504f, +-0.102414f, +-2.327001f, +-0.102684f, +-2.324504f, +-0.102955f, +-2.322013f, +-0.103225f, +-2.319518f, +-0.103497f, +-2.317019f, +-0.103770f, +-2.314536f, +-0.104041f, +-2.312040f, +-0.104316f, +-2.309559f, +-0.104589f, +-2.307075f, +-0.104863f, +-2.304587f, +-0.105138f, +-2.302105f, +-0.105414f, +-2.299620f, +-0.105691f, +-2.297140f, +-0.105967f, +-2.294667f, +-0.106244f, +-2.292189f, +-0.106522f, +-2.289718f, +-0.106800f, +-2.287243f, +-0.107080f, +-2.284775f, +-0.107359f, +-2.282302f, +-0.107640f, +-2.279836f, +-0.107920f, +-2.277376f, +-0.108201f, +-2.274912f, +-0.108483f, +-2.272444f, +-0.108766f, +-2.269982f, +-0.109050f, +-2.267527f, +-0.109333f, +-2.265068f, +-0.109617f, +-2.262615f, +-0.109902f, +-2.260158f, +-0.110188f, +-2.257707f, +-0.110474f, +-2.255253f, +-0.110761f, +-2.252805f, +-0.111048f, +-2.250353f, +-0.111336f, +-2.247908f, +-0.111625f, +-2.245468f, +-0.111913f, +-2.243025f, +-0.112203f, +-2.240587f, +-0.112493f, +-2.238147f, +-0.112784f, +-2.235702f, +-0.113076f, +-2.233274f, +-0.113367f, +-2.230832f, +-0.113660f, +-2.228406f, +-0.113953f, +-2.225976f, +-0.114247f, +-2.223543f, +-0.114541f, +-2.221116f, +-0.114836f, +-2.218685f, +-0.115133f, +-2.216261f, +-0.115429f, +-2.213842f, +-0.115725f, +-2.211420f, +-0.116023f, +-2.209004f, +-0.116320f, +-2.206584f, +-0.116619f, +-2.204171f, +-0.116918f, +-2.201754f, +-0.117218f, +-2.199343f, +-0.117519f, +-2.196929f, +-0.117820f, +-2.194520f, +-0.118122f, +-2.192109f, +-0.118424f, +-2.189703f, +-0.118727f, +-2.187303f, +-0.119030f, +-2.184900f, +-0.119334f, +-2.182494f, +-0.119640f, +-2.180093f, +-0.119945f, +-2.177698f, +-0.120251f, +-2.175301f, +-0.120558f, +-2.172909f, +-0.120865f, +-2.170514f, +-0.121173f, +-2.168124f, +-0.121481f, +-2.165732f, +-0.121790f, +-2.163345f, +-0.122100f, +-2.160955f, +-0.122411f, +-2.158571f, +-0.122721f, +-2.156193f, +-0.123032f, +-2.153812f, +-0.123345f, +-2.151427f, +-0.123658f, +-2.149049f, +-0.123972f, +-2.146676f, +-0.124285f, +-2.144300f, +-0.124600f, +-2.141921f, +-0.124916f, +-2.139557f, +-0.125231f, +-2.137181f, +-0.125548f, +-2.134811f, +-0.125866f, +-2.132446f, +-0.126184f, +-2.130078f, +-0.126502f, +-2.127716f, +-0.126821f, +-2.125360f, +-0.127140f, +-2.123001f, +-0.127461f, +-2.120639f, +-0.127782f, +-2.118282f, +-0.128104f, +-2.115923f, +-0.128427f, +-2.113569f, +-0.128750f, +-2.111221f, +-0.129073f, +-2.108870f, +-0.129397f, +-2.106525f, +-0.129722f, +-2.104177f, +-0.130047f, +-2.101826f, +-0.130374f, +-2.099481f, +-0.130701f, +-2.097141f, +-0.131028f, +-2.094799f, +-0.131357f, +-2.092462f, +-0.131685f, +-2.090122f, +-0.132015f, +-2.087788f, +-0.132345f, +-2.085460f, +-0.132675f, +-2.083120f, +-0.133007f, +-2.080794f, +-0.133338f, +-2.078466f, +-0.133671f, +-2.076135f, +-0.134005f, +-2.073809f, +-0.134339f, +-2.071489f, +-0.134673f, +-2.069166f, +-0.135008f, +-2.066841f, +-0.135344f, +-2.064521f, +-0.135681f, +-2.062207f, +-0.136018f, +-2.059890f, +-0.136356f, +-2.057578f, +-0.136694f, +-2.055264f, +-0.137034f, +-2.052955f, +-0.137373f, +-2.050644f, +-0.137714f, +-2.048331f, +-0.138056f, +-2.046030f, +-0.138397f, +-2.043727f, +-0.138739f, +-2.041422f, +-0.139083f, +-2.039121f, +-0.139426f, +-2.036819f, +-0.139771f, +-2.034522f, +-0.140116f, +-2.032222f, +-0.140463f, +-2.029928f, +-0.140809f, +-2.027639f, +-0.141156f, +-2.025347f, +-0.141504f, +-2.023054f, +-0.141853f, +-2.020765f, +-0.142202f, +-2.018482f, +-0.142551f, +-2.016196f, +-0.142902f, +-2.013908f, +-0.143254f, +-2.011633f, +-0.143605f, +-2.009348f, +-0.143958f, +-2.007069f, +-0.144312f, +-2.004794f, +-0.144665f, +-2.002518f, +-0.145020f, +-2.000246f, +-0.145375f, +-1.997972f, +-0.145731f, +-1.995703f, +-0.146088f, +-1.993433f, +-0.146445f, +-1.991167f, +-0.146803f, +-1.988899f, +-0.147162f, +-1.986636f, +-0.147521f, +-1.984379f, +-0.147881f, +-1.982112f, +-0.148242f, +-1.979857f, +-0.148603f, +-1.977600f, +-0.148965f, +-1.975341f, +-0.149329f, +-1.973087f, +-0.149692f, +-1.970838f, +-0.150056f, +-1.968587f, +-0.150421f, +-1.966334f, +-0.150787f, +-1.964086f, +-0.151153f, +-1.961843f, +-0.151520f, +-1.959598f, +-0.151887f, +-1.957351f, +-0.152256f, +-1.955109f, +-0.152626f, +-1.952872f, +-0.152995f, +-1.950633f, +-0.153366f, +-1.948399f, +-0.153736f, +-1.946163f, +-0.154109f, +-1.943932f, +-0.154481f, +-1.941699f, +-0.154854f, +-1.939471f, +-0.155228f, +-1.937241f, +-0.155603f, +-1.935016f, +-0.155978f, +-1.932789f, +-0.156354f, +-1.930567f, +-0.156731f, +-1.928342f, +-0.157109f, +-1.926123f, +-0.157487f, +-1.923902f, +-0.157866f, +-1.921686f, +-0.158246f, +-1.919475f, +-0.158625f, +-1.917261f, +-0.159006f, +-1.915046f, +-0.159389f, +-1.912836f, +-0.159771f, +-1.910631f, +-0.160153f, +-1.908417f, +-0.160539f, +-1.906215f, +-0.160923f, +-1.904010f, +-0.161308f, +-1.901811f, +-0.161693f, +-1.899610f, +-0.162080f, +-1.897407f, +-0.162468f, +-1.895208f, +-0.162857f, +-1.893015f, +-0.163245f, +-1.890820f, +-0.163635f, +-1.888629f, +-0.164025f, +-1.886437f, +-0.164416f, +-1.884243f, +-0.164809f, +-1.882061f, +-0.165200f, +-1.879870f, +-0.165594f, +-1.877690f, +-0.165987f, +-1.875502f, +-0.166383f, +-1.873325f, +-0.166777f, +-1.871140f, +-0.167174f, +-1.868967f, +-0.167570f, +-1.866785f, +-0.167969f, +-1.864614f, +-0.168367f, +-1.862442f, +-0.168765f, +-1.860267f, +-0.169166f, +-1.858098f, +-0.169566f, +-1.855927f, +-0.169968f, +-1.853760f, +-0.170370f, +-1.851592f, +-0.170773f, +-1.849429f, +-0.171176f, +-1.847270f, +-0.171580f, +-1.845110f, +-0.171985f, +-1.842947f, +-0.172391f, +-1.840790f, +-0.172797f, +-1.838637f, +-0.173204f, +-1.836483f, +-0.173612f, +-1.834327f, +-0.174021f, +-1.832175f, +-0.174431f, +-1.830028f, +-0.174840f, +-1.827880f, +-0.175251f, +-1.825736f, +-0.175663f, +-1.823591f, +-0.176075f, +-1.821444f, +-0.176489f, +-1.819307f, +-0.176902f, +-1.817163f, +-0.177317f, +-1.815024f, +-0.177733f, +-1.812889f, +-0.178149f, +-1.810753f, +-0.178566f, +-1.808621f, +-0.178983f, +-1.806487f, +-0.179402f, +-1.804358f, +-0.179821f, +-1.802228f, +-0.180241f, +-1.800102f, +-0.180661f, +-1.797975f, +-0.181083f, +-1.795852f, +-0.181505f, +-1.793733f, +-0.181927f, +-1.791607f, +-0.182352f, +-1.789492f, +-0.182776f, +-1.787375f, +-0.183201f, +-1.785257f, +-0.183627f, +-1.783143f, +-0.184054f, +-1.781033f, +-0.184481f, +-1.778922f, +-0.184909f, +-1.776810f, +-0.185338f, +-1.774702f, +-0.185768f, +-1.772598f, +-0.186198f, +-1.770493f, +-0.186630f, +-1.768387f, +-0.187062f, +-1.766285f, +-0.187495f, +-1.764187f, +-0.187928f, +-1.762088f, +-0.188363f, +-1.759988f, +-0.188799f, +-1.757897f, +-0.189234f, +-1.755800f, +-0.189671f, +-1.753707f, +-0.190109f, +-1.751618f, +-0.190547f, +-1.749528f, +-0.190986f, +-1.747442f, +-0.191426f, +-1.745355f, +-0.191867f, +-1.743272f, +-0.192308f, +-1.741188f, +-0.192750f, +-1.739108f, +-0.193193f, +-1.737027f, +-0.193637f, +-1.734950f, +-0.194081f, +-1.732878f, +-0.194526f, +-1.730804f, +-0.194972f, +-1.728728f, +-0.195419f, +-1.726657f, +-0.195866f, +-1.724585f, +-0.196315f, +-1.722517f, +-0.196765f, +-1.720453f, +-0.197214f, +-1.718388f, +-0.197665f, +-1.716322f, +-0.198117f, +-1.714260f, +-0.198569f, +-1.712202f, +-0.199022f, +-1.710143f, +-0.199476f, +-1.708082f, +-0.199931f, +-1.706026f, +-0.200387f, +-1.703974f, +-0.200843f, +-1.701921f, +-0.201300f, +-1.699872f, +-0.201758f, +-1.697821f, +-0.202217f, +-1.695775f, +-0.202676f, +-1.693728f, +-0.203136f, +-1.691684f, +-0.203597f, +-1.689640f, +-0.204059f, +-1.687599f, +-0.204522f, +-1.685558f, +-0.204986f, +-1.683521f, +-0.205450f, +-1.681482f, +-0.205915f, +-1.679447f, +-0.206381f, +-1.677417f, +-0.206847f, +-1.675385f, +-0.207314f, +-1.673353f, +-0.207783f, +-1.671324f, +-0.208252f, +-1.669294f, +-0.208723f, +-1.667268f, +-0.209194f, +-1.665247f, +-0.209665f, +-1.663224f, +-0.210137f, +-1.661205f, +-0.210610f, +-1.659185f, +-0.211084f, +-1.657164f, +-0.211560f, +-1.655152f, +-0.212034f, +-1.653134f, +-0.212512f, +-1.651120f, +-0.212989f, +-1.649110f, +-0.213467f, +-1.647098f, +-0.213946f, +-1.645091f, +-0.214425f, +-1.643083f, +-0.214906f, +-1.641078f, +-0.215387f, +-1.639078f, +-0.215869f, +-1.637071f, +-0.216353f, +-1.635074f, +-0.216836f, +-1.633075f, +-0.217321f, +-1.631075f, +-0.217807f, +-1.629080f, +-0.218293f, +-1.627088f, +-0.218779f, +-1.625095f, +-0.219267f, +-1.623101f, +-0.219757f, +-1.621111f, +-0.220246f, +-1.619125f, +-0.220736f, +-1.617137f, +-0.221228f, +-1.615154f, +-0.221720f, +-1.613170f, +-0.222213f, +-1.611189f, +-0.222706f, +-1.609208f, +-0.223201f, +-1.607230f, +-0.223696f, +-1.605252f, +-0.224193f, +-1.603277f, +-0.224690f, +-1.601301f, +-0.225188f, +-1.599329f, +-0.225687f, +-1.597361f, +-0.226186f, +-1.595392f, +-0.226686f, +-1.593422f, +-0.227188f, +-1.591456f, +-0.227690f, +-1.589493f, +-0.228193f, +-1.587530f, +-0.228696f, +-1.585565f, +-0.229202f, +-1.583609f, +-0.229706f, +-1.581648f, +-0.230213f, +-1.579690f, +-0.230721f, +-1.577736f, +-0.231229f, +-1.575781f, +-0.231738f, +-1.573829f, +-0.232247f, +-1.571882f, +-0.232757f, +-1.569934f, +-0.233268f, +-1.567984f, +-0.233781f, +-1.566038f, +-0.234294f, +-1.564092f, +-0.234809f, +-1.562149f, +-0.235324f, +-1.560210f, +-0.235839f, +-1.558270f, +-0.236355f, +-1.556333f, +-0.236872f, +-1.554396f, +-0.237391f, +-1.552458f, +-0.237911f, +-1.550528f, +-0.238430f, +-1.548592f, +-0.238952f, +-1.546665f, +-0.239472f, +-1.544737f, +-0.239995f, +-1.542808f, +-0.240519f, +-1.540882f, +-0.241043f, +-1.538956f, +-0.241569f, +-1.537034f, +-0.242094f, +-1.535115f, +-0.242621f, +-1.533195f, +-0.243149f, +-1.531279f, +-0.243677f, +-1.529361f, +-0.244206f, +-1.527443f, +-0.244738f, +-1.525533f, +-0.245268f, +-1.523618f, +-0.245801f, +-1.521711f, +-0.246333f, +-1.519803f, +-0.246866f, +-1.517894f, +-0.247402f, +-1.515989f, +-0.247937f, +-1.514082f, +-0.248474f, +-1.512180f, +-0.249012f, +-1.510281f, +-0.249549f, +-1.508381f, +-0.250088f, +-1.506484f, +-0.250628f, +-1.504587f, +-0.251169f, +-1.502693f, +-0.251710f, +-1.500799f, +-0.252253f, +-1.498908f, +-0.252796f, +-1.497016f, +-0.253341f, +-1.495128f, +-0.253886f, +-1.493243f, +-0.254432f, +-1.491357f, +-0.254979f, +-1.489471f, +-0.255527f, +-1.487588f, +-0.256076f, +-1.485708f, +-0.256625f, +-1.483828f, +-0.257176f, +-1.481951f, +-0.257727f, +-1.480073f, +-0.258280f, +-1.478199f, +-0.258833f, +-1.476324f, +-0.259388f, +-1.474453f, +-0.259942f, +-1.472585f, +-0.260498f, +-1.470716f, +-0.261054f, +-1.468846f, +-0.261613f, +-1.466984f, +-0.262170f, +-1.465117f, +-0.262731f, +-1.463257f, +-0.263290f, +-1.461393f, +-0.263852f, +-1.459536f, +-0.264414f, +-1.457679f, +-0.264976f, +-1.455820f, +-0.265541f, +-1.453965f, +-0.266106f, +-1.452114f, +-0.266671f, +-1.450261f, +-0.267238f, +-1.448412f, +-0.267805f, +-1.446563f, +-0.268374f, +-1.444716f, +-0.268943f, +-1.442869f, +-0.269513f, +-1.441025f, +-0.270084f, +-1.439181f, +-0.270657f, +-1.437339f, +-0.271230f, +-1.435501f, +-0.271803f, +-1.433663f, +-0.272378f, +-1.431827f, +-0.272954f, +-1.429991f, +-0.273531f, +-1.428159f, +-0.274108f, +-1.426325f, +-0.274687f, +-1.424495f, +-0.275266f, +-1.422668f, +-0.275846f, +-1.420840f, +-0.276427f, +-1.419012f, +-0.277010f, +-1.417191f, +-0.277592f, +-1.415365f, +-0.278177f, +-1.413546f, +-0.278761f, +-1.411727f, +-0.279346f, +-1.409907f, +-0.279934f, +-1.408090f, +-0.280521f, +-1.406277f, +-0.281109f, +-1.404462f, +-0.281699f, +-1.402651f, +-0.282289f, +-1.400840f, +-0.282880f, +-1.399031f, +-0.283472f, +-1.397222f, +-0.284066f, +-1.395416f, +-0.284660f, +-1.393613f, +-0.285254f, +-1.391810f, +-0.285850f, +-1.390009f, +-0.286447f, +-1.388208f, +-0.287045f, +-1.386410f, +-0.287643f, +-1.384612f, +-0.288244f, +-1.382816f, +-0.288844f, +-1.381024f, +-0.289445f, +-1.379231f, +-0.290048f, +-1.377438f, +-0.290652f, +-1.375651f, +-0.291255f, +-1.373864f, +-0.291860f, +-1.372076f, +-0.292467f, +-1.370291f, +-0.293074f, +-1.368509f, +-0.293681f, +-1.366727f, +-0.294291f, +-1.364944f, +-0.294901f, +-1.363168f, +-0.295511f, +-1.361391f, +-0.296123f, +-1.359613f, +-0.296736f, +-1.357839f, +-0.297350f, +-1.356068f, +-0.297964f, +-1.354296f, +-0.298580f, +-1.352527f, +-0.299196f, +-1.350757f, +-0.299814f, +-1.348991f, +-0.300432f, +-1.347224f, +-0.301052f, +-1.345463f, +-0.301671f, +-1.343699f, +-0.302294f, +-1.341941f, +-0.302915f, +-1.340178f, +-0.303539f, +-1.338423f, +-0.304162f, +-1.336666f, +-0.304788f, +-1.334909f, +-0.305414f, +-1.333159f, +-0.306040f, +-1.331405f, +-0.306669f, +-1.329657f, +-0.307297f, +-1.327908f, +-0.307927f, +-1.326159f, +-0.308558f, +-1.324417f, +-0.309189f, +-1.322670f, +-0.309823f, +-1.320930f, +-0.310455f, +-1.319185f, +-0.311091f, +-1.317448f, +-0.311726f, +-1.315709f, +-0.312363f, +-1.313974f, +-0.313000f, +-1.312237f, +-0.313639f, +-1.310504f, +-0.314278f, +-1.308771f, +-0.314919f, +-1.307040f, +-0.315560f, +-1.305312f, +-0.316202f, +-1.303583f, +-0.316846f, +-1.301858f, +-0.317490f, +-1.300135f, +-0.318134f, +-1.298412f, +-0.318781f, +-1.296688f, +-0.319429f, +-1.294970f, +-0.320076f, +-1.293249f, +-0.320726f, +-1.291533f, +-0.321375f, +-1.289818f, +-0.322026f, +-1.288105f, +-0.322678f, +-1.286391f, +-0.323331f, +-1.284680f, +-0.323985f, +-1.282969f, +-0.324641f, +-1.281261f, +-0.325297f, +-1.279555f, +-0.325953f, +-1.277849f, +-0.326611f, +-1.276146f, +-0.327270f, +-1.274442f, +-0.327931f, +-1.272744f, +-0.328590f, +-1.271043f, +-0.329253f, +-1.269347f, +-0.329915f, +-1.267648f, +-0.330580f, +-1.265955f, +-0.331244f, +-1.264261f, +-0.331910f, +-1.262570f, +-0.332576f, +-1.260878f, +-0.333244f, +-1.259190f, +-0.333913f, +-1.257504f, +-0.334582f, +-1.255817f, +-0.335253f, +-1.254133f, +-0.335925f, +-1.252449f, +-0.336598f, +-1.250767f, +-0.337272f, +-1.249089f, +-0.337946f, +-1.247409f, +-0.338622f, +-1.245733f, +-0.339298f, +-1.244059f, +-0.339975f, +-1.242384f, +-0.340654f, +-1.240709f, +-0.341335f, +-1.239041f, +-0.342014f, +-1.237371f, +-0.342696f, +-1.235701f, +-0.343379f, +-1.234037f, +-0.344062f, +-1.232369f, +-0.344748f, +-1.230707f, +-0.345433f, +-1.229045f, +-0.346119f, +-1.227385f, +-0.346807f, +-1.225724f, +-0.347496f, +-1.224067f, +-0.348185f, +-1.222412f, +-0.348875f, +-1.220756f, +-0.349567f, +-1.219103f, +-0.350260f, +-1.217450f, +-0.350954f, +-1.215799f, +-0.351649f, +-1.214151f, +-0.352344f, +-1.212502f, +-0.353042f, +-1.210856f, +-0.353739f, +-1.209213f, +-0.354437f, +-1.207569f, +-0.355138f, +-1.205928f, +-0.355838f, +-1.204290f, +-0.356539f, +-1.202650f, +-0.357242f, +-1.201014f, +-0.357946f, +-1.199377f, +-0.358651f, +-1.197742f, +-0.359357f, +-1.196111f, +-0.360064f, +-1.194478f, +-0.360772f, +-1.192848f, +-0.361481f, +-1.191221f, +-0.362190f, +-1.189593f, +-0.362901f, +-1.187968f, +-0.363613f, +-1.186346f, +-0.364326f, +-1.184723f, +-0.365040f, +-1.183102f, +-0.365755f, +-1.181481f, +-0.366471f, +-1.179866f, +-0.367187f, +-1.178247f, +-0.367906f, +-1.176633f, +-0.368625f, +-1.175019f, +-0.369345f, +-1.173408f, +-0.370066f, +-1.171796f, +-0.370788f, +-1.170187f, +-0.371512f, +-1.168580f, +-0.372235f, +-1.166973f, +-0.372961f, +-1.165368f, +-0.373687f, +-1.163765f, +-0.374414f, +-1.162163f, +-0.375143f, +-1.160562f, +-0.375872f, +-1.158964f, +-0.376602f, +-1.157366f, +-0.377334f, +-1.155770f, +-0.378066f, +-1.154174f, +-0.378801f, +-1.152580f, +-0.379536f, +-1.150988f, +-0.380271f, +-1.149399f, +-0.381007f, +-1.147810f, +-0.381745f, +-1.146223f, +-0.382484f, +-1.144638f, +-0.383223f, +-1.143053f, +-0.383964f, +-1.141471f, +-0.384706f, +-1.139887f, +-0.385449f, +-1.138307f, +-0.386193f, +-1.136729f, +-0.386938f, +-1.135153f, +-0.387684f, +-1.133576f, +-0.388431f, +-1.132003f, +-0.389179f, +-1.130428f, +-0.389929f, +-1.128856f, +-0.390679f, +-1.127286f, +-0.391431f, +-1.125719f, +-0.392182f, +-1.124152f, +-0.392936f, +-1.122586f, +-0.393690f, +-1.121024f, +-0.394445f, +-1.119460f, +-0.395202f, +-1.117899f, +-0.395959f, +-1.116337f, +-0.396719f, +-1.114781f, +-0.397478f, +-1.113225f, +-0.398238f, +-1.111667f, +-0.399001f, +-1.110112f, +-0.399764f, +-1.108560f, +-0.400528f, +-1.107009f, +-0.401293f, +-1.105459f, +-0.402059f, +-1.103910f, +-0.402827f, +-1.102364f, +-0.403594f, +-1.100821f, +-0.404363f, +-1.099277f, +-0.405133f, +-1.097732f, +-0.405906f, +-1.096192f, +-0.406677f, +-1.094652f, +-0.407451f, +-1.093114f, +-0.408225f, +-1.091576f, +-0.409002f, +-1.090043f, +-0.409777f, +-1.088510f, +-0.410555f, +-1.086975f, +-0.411335f, +-1.085443f, +-0.412115f, +-1.083914f, +-0.412896f, +-1.082387f, +-0.413678f, +-1.080859f, +-0.414461f, +-1.079336f, +-0.415244f, +-1.077810f, +-0.416031f, +-1.076289f, +-0.416816f, +-1.074768f, +-0.417604f, +-1.073249f, +-0.418392f, +-1.071729f, +-0.419183f, +-1.070214f, +-0.419972f, +-1.068699f, +-0.420764f, +-1.067183f, +-0.421558f, +-1.065673f, +-0.422351f, +-1.064162f, +-0.423146f, +-1.062653f, +-0.423942f, +-1.061143f, +-0.424740f, +-1.059636f, +-0.425538f, +-1.058131f, +-0.426337f, +-1.056628f, +-0.427137f, +-1.055125f, +-0.427939f, +-1.053624f, +-0.428742f, +-1.052125f, +-0.429545f, +-1.050625f, +-0.430351f, +-1.049131f, +-0.431155f, +-1.047633f, +-0.431964f, +-1.046140f, +-0.432771f, +-1.044647f, +-0.433581f, +-1.043156f, +-0.434391f, +-1.041667f, +-0.435202f, +-1.040180f, +-0.436013f, +-1.038693f, +-0.436827f, +-1.037208f, +-0.437642f, +-1.035725f, +-0.438457f, +-1.034241f, +-0.439274f, +-1.032760f, +-0.440092f, +-1.031281f, +-0.440911f, +-1.029801f, +-0.441732f, +-1.028326f, +-0.442552f, +-1.026851f, +-0.443374f, +-1.025375f, +-0.444199f, +-1.023904f, +-0.445022f, +-1.022432f, +-0.445848f, +-1.020963f, +-0.446675f, +-1.019495f, +-0.447502f, +-1.018027f, +-0.448331f, +-1.016561f, +-0.449162f, +-1.015098f, +-0.449992f, +-1.013636f, +-0.450824f, +-1.012174f, +-0.451658f, +-1.010714f, +-0.452492f, +-1.009256f, +-0.453327f, +-1.007798f, +-0.454165f, +-1.006344f, +-0.455002f, +-1.004890f, +-0.455840f, +-1.003438f, +-0.456680f, +-1.001985f, +-0.457522f, +-1.000534f, +-0.458364f, +-0.999086f, +-0.459208f, +-0.997639f, +-0.460052f, +-0.996195f, +-0.460896f, +-0.994750f, +-0.461743f, +-0.993307f, +-0.462591f, +-0.991866f, +-0.463440f, +-0.990424f, +-0.464290f, +-0.988985f, +-0.465142f, +-0.987548f, +-0.465994f, +-0.986113f, +-0.466847f, +-0.984679f, +-0.467701f, +-0.983246f, +-0.468557f, +-0.981814f, +-0.469413f, +-0.980384f, +-0.470271f, +-0.978954f, +-0.471131f, +-0.977525f, +-0.471991f, +-0.976102f, +-0.472851f, +-0.974675f, +-0.473715f, +-0.973253f, +-0.474577f, +-0.971830f, +-0.475442f, +-0.970409f, +-0.476308f, +-0.968990f, +-0.477175f, +-0.967574f, +-0.478042f, +-0.966156f, +-0.478912f, +-0.964743f, +-0.479781f, +-0.963327f, +-0.480654f, +-0.961916f, +-0.481526f, +-0.960506f, +-0.482399f, +-0.959096f, +-0.483274f, +-0.957688f, +-0.484150f, +-0.956282f, +-0.485026f, +-0.954876f, +-0.485905f, +-0.953474f, +-0.486784f, +-0.952071f, +-0.487664f, +-0.950670f, +-0.488546f, +-0.949271f, +-0.489428f, +-0.947872f, +-0.490312f, +-0.946474f, +-0.491198f, +-0.945079f, +-0.492084f, +-0.943685f, +-0.492971f, +-0.942293f, +-0.493859f, +-0.940901f, +-0.494749f, +-0.939511f, +-0.495640f, +-0.938122f, +-0.496532f, +-0.936736f, +-0.497424f, +-0.935351f, +-0.498318f, +-0.933966f, +-0.499213f, +-0.932583f, +-0.500110f, +-0.931201f, +-0.501007f, +-0.929822f, +-0.501906f, +-0.928442f, +-0.502806f, +-0.927064f, +-0.503708f, +-0.925690f, +-0.504608f, +-0.924313f, +-0.505513f, +-0.922940f, +-0.506417f, +-0.921570f, +-0.507322f, +-0.920198f, +-0.508229f, +-0.918829f, +-0.509137f, +-0.917461f, +-0.510046f, +-0.916096f, +-0.510956f, +-0.914729f, +-0.511868f, +-0.913365f, +-0.512781f, +-0.912005f, +-0.513693f, +-0.910642f, +-0.514609f, +-0.909283f, +-0.515525f, +-0.907926f, +-0.516441f, +-0.906568f, +-0.517360f, +-0.905212f, +-0.518280f, +-0.903858f, +-0.519201f, +-0.902506f, +-0.520122f, +-0.901156f, +-0.521044f, +-0.899805f, +-0.521969f, +-0.898456f, +-0.522895f, +-0.897108f, +-0.523821f, +-0.895763f, +-0.524749f, +-0.894419f, +-0.525677f, +-0.893075f, +-0.526608f, +-0.891735f, +-0.527538f, +-0.890394f, +-0.528470f, +-0.889055f, +-0.529404f, +-0.887718f, +-0.530338f, +-0.886380f, +-0.531275f, +-0.885046f, +-0.532211f, +-0.883712f, +-0.533150f, +-0.882380f, +-0.534089f, +-0.881049f, +-0.535030f, +-0.879720f, +-0.535971f, +-0.878393f, +-0.536913f, +-0.877065f, +-0.537858f, +-0.875739f, +-0.538803f, +-0.874415f, +-0.539750f, +-0.873092f, +-0.540697f, +-0.871772f, +-0.541646f, +-0.870453f, +-0.542595f, +-0.869133f, +-0.543547f, +-0.867817f, +-0.544498f, +-0.866501f, +-0.545452f, +-0.865187f, +-0.546406f, +-0.863874f, +-0.547362f, +-0.862560f, +-0.548320f, +-0.861251f, +-0.549277f, +-0.859941f, +-0.550237f, +-0.858633f, +-0.551198f, +-0.857326f, +-0.552160f, +-0.856021f, +-0.553123f, +-0.854718f, +-0.554086f, +-0.853417f, +-0.555051f, +-0.852115f, +-0.556018f, +-0.850817f, +-0.556985f, +-0.849518f, +-0.557954f, +-0.848221f, +-0.558924f, +-0.846926f, +-0.559895f, +-0.845630f, +-0.560869f, +-0.844338f, +-0.561842f, +-0.843047f, +-0.562816f, +-0.841756f, +-0.563792f, +-0.840467f, +-0.564770f, +-0.839179f, +-0.565748f, +-0.837893f, +-0.566728f, +-0.836609f, +-0.567708f, +-0.835326f, +-0.568690f, +-0.834043f, +-0.569674f, +-0.832763f, +-0.570657f, +-0.831483f, +-0.571643f, +-0.830205f, +-0.572630f, +-0.828928f, +-0.573618f, +-0.827653f, +-0.574607f, +-0.826379f, +-0.575597f, +-0.825105f, +-0.576590f, +-0.823835f, +-0.577582f, +-0.822564f, +-0.578576f, +-0.821297f, +-0.579570f, +-0.820029f, +-0.580567f, +-0.818763f, +-0.581565f, +-0.817498f, +-0.582563f, +-0.816235f, +-0.583563f, +-0.814971f, +-0.584565f, +-0.813712f, +-0.585567f, +-0.812451f, +-0.586572f, +-0.811195f, +-0.587575f, +-0.809937f, +-0.588582f, +-0.808681f, +-0.589589f, +-0.807427f, +-0.590598f, +-0.806175f, +-0.591607f, +-0.804924f, +-0.592618f, +-0.803674f, +-0.593630f, +-0.802424f, +-0.594644f, +-0.801178f, +-0.595658f, +-0.799931f, +-0.596674f, +-0.798688f, +-0.597690f, +-0.797444f, +-0.598708f, +-0.796201f, +-0.599728f, +-0.794961f, +-0.600749f, +-0.793721f, +-0.601770f, +-0.792484f, +-0.602793f, +-0.791245f, +-0.603818f, +-0.790011f, +-0.604843f, +-0.788777f, +-0.605869f, +-0.787544f, +-0.606898f, +-0.786311f, +-0.607928f, +-0.785083f, +-0.608957f, +-0.783853f, +-0.609989f, +-0.782626f, +-0.611022f, +-0.781399f, +-0.612056f, +-0.780175f, +-0.613091f, +-0.778951f, +-0.614127f, +-0.777729f, +-0.615164f, +-0.776507f, +-0.616205f, +-0.775288f, +-0.617244f, +-0.774069f, +-0.618286f, +-0.772853f, +-0.619328f, +-0.771636f, +-0.620373f, +-0.770424f, +-0.621416f, +-0.769210f, +-0.622463f, +-0.767998f, +-0.623511f, +-0.766787f, +-0.624560f, +-0.765578f, +-0.625610f, +-0.764370f, +-0.626661f, +-0.763164f, +-0.627713f, +-0.761959f, +-0.628767f, +-0.760754f, +-0.629823f, +-0.759552f, +-0.630879f, +-0.758352f, +-0.631935f, +-0.757150f, +-0.632995f, +-0.755953f, +-0.634054f, +-0.754755f, +-0.635116f, +-0.753558f, +-0.636179f, +-0.752364f, +-0.637241f, +-0.751170f, +-0.638307f, +-0.749978f, +-0.639373f, +-0.748787f, +-0.640441f, +-0.747597f, +-0.641510f, +-0.746409f, +-0.642580f, +-0.745222f, +-0.643651f, +-0.744036f, +-0.644723f, +-0.742852f, +-0.645796f, +-0.741670f, +-0.646871f, +-0.740488f, +-0.647946f, +-0.739308f, +-0.649023f, +-0.738128f, +-0.650103f, +-0.736951f, +-0.651182f, +-0.735773f, +-0.652264f, +-0.734599f, +-0.653346f, +-0.733426f, +-0.654429f, +-0.732252f, +-0.655514f, +-0.731082f, +-0.656599f, +-0.729911f, +-0.657687f, +-0.728741f, +-0.658777f, +-0.727575f, +-0.659865f, +-0.726408f, +-0.660957f, +-0.725243f, +-0.662050f, +-0.724079f, +-0.663144f, +-0.722918f, +-0.664237f, +-0.721757f, +-0.665334f, +-0.720596f, +-0.666431f, +-0.719438f, +-0.667530f, +-0.718280f, +-0.668630f, +-0.717124f, +-0.669731f, +-0.715970f, +-0.670834f, +-0.714816f, +-0.671938f, +-0.713664f, +-0.673043f, +-0.712514f, +-0.674149f, +-0.711364f, +-0.675256f, +-0.710216f, +-0.676365f, +-0.709069f, +-0.677475f, +-0.707924f, +-0.678586f, +-0.706780f, +-0.679698f, +-0.705637f, +-0.680812f, +-0.704495f, +-0.681926f, +-0.703355f, +-0.683042f, +-0.702214f, +-0.684162f, +-0.701077f, +-0.685280f, +-0.699940f, +-0.686400f, +-0.698805f, +-0.687521f, +-0.697671f, +-0.688643f, +-0.696539f, +-0.689767f, +-0.695406f, +-0.690894f, +-0.694276f, +-0.692020f, +-0.693147f, +-0.693147f, +-0.693147f, +-0.693147f, +-0.693147f, +-0.693147f, +-0.692020f, +-0.694276f, +-0.690894f, +-0.695406f, +-0.689767f, +-0.696539f, +-0.688643f, +-0.697671f, +-0.687521f, +-0.698805f, +-0.686400f, +-0.699940f, +-0.685280f, +-0.701077f, +-0.684162f, +-0.702214f, +-0.683042f, +-0.703355f, +-0.681926f, +-0.704495f, +-0.680812f, +-0.705637f, +-0.679698f, +-0.706780f, +-0.678586f, +-0.707924f, +-0.677475f, +-0.709069f, +-0.676365f, +-0.710216f, +-0.675256f, +-0.711364f, +-0.674149f, +-0.712514f, +-0.673043f, +-0.713664f, +-0.671938f, +-0.714816f, +-0.670834f, +-0.715970f, +-0.669731f, +-0.717124f, +-0.668630f, +-0.718280f, +-0.667530f, +-0.719438f, +-0.666431f, +-0.720596f, +-0.665334f, +-0.721757f, +-0.664237f, +-0.722918f, +-0.663144f, +-0.724079f, +-0.662050f, +-0.725243f, +-0.660957f, +-0.726408f, +-0.659865f, +-0.727575f, +-0.658777f, +-0.728741f, +-0.657687f, +-0.729911f, +-0.656599f, +-0.731082f, +-0.655514f, +-0.732252f, +-0.654429f, +-0.733426f, +-0.653346f, +-0.734599f, +-0.652264f, +-0.735773f, +-0.651182f, +-0.736951f, +-0.650103f, +-0.738128f, +-0.649023f, +-0.739308f, +-0.647946f, +-0.740488f, +-0.646871f, +-0.741670f, +-0.645796f, +-0.742852f, +-0.644723f, +-0.744036f, +-0.643651f, +-0.745222f, +-0.642580f, +-0.746409f, +-0.641510f, +-0.747597f, +-0.640441f, +-0.748787f, +-0.639373f, +-0.749978f, +-0.638307f, +-0.751170f, +-0.637241f, +-0.752364f, +-0.636179f, +-0.753558f, +-0.635116f, +-0.754755f, +-0.634054f, +-0.755953f, +-0.632995f, +-0.757150f, +-0.631935f, +-0.758351f, +-0.630879f, +-0.759552f, +-0.629823f, +-0.760754f, +-0.628767f, +-0.761959f, +-0.627713f, +-0.763164f, +-0.626661f, +-0.764370f, +-0.625610f, +-0.765578f, +-0.624560f, +-0.766787f, +-0.623511f, +-0.767998f, +-0.622463f, +-0.769210f, +-0.621416f, +-0.770424f, +-0.620373f, +-0.771636f, +-0.619328f, +-0.772853f, +-0.618286f, +-0.774069f, +-0.617244f, +-0.775288f, +-0.616205f, +-0.776507f, +-0.615164f, +-0.777730f, +-0.614127f, +-0.778951f, +-0.613091f, +-0.780175f, +-0.612056f, +-0.781399f, +-0.611022f, +-0.782626f, +-0.609989f, +-0.783853f, +-0.608957f, +-0.785083f, +-0.607928f, +-0.786311f, +-0.606898f, +-0.787544f, +-0.605869f, +-0.788777f, +-0.604843f, +-0.790011f, +-0.603818f, +-0.791245f, +-0.602793f, +-0.792484f, +-0.601770f, +-0.793721f, +-0.600749f, +-0.794961f, +-0.599728f, +-0.796201f, +-0.598708f, +-0.797444f, +-0.597690f, +-0.798688f, +-0.596674f, +-0.799931f, +-0.595658f, +-0.801178f, +-0.594644f, +-0.802424f, +-0.593630f, +-0.803674f, +-0.592618f, +-0.804924f, +-0.591607f, +-0.806175f, +-0.590598f, +-0.807427f, +-0.589589f, +-0.808681f, +-0.588582f, +-0.809937f, +-0.587575f, +-0.811195f, +-0.586572f, +-0.812451f, +-0.585567f, +-0.813712f, +-0.584565f, +-0.814971f, +-0.583563f, +-0.816235f, +-0.582563f, +-0.817498f, +-0.581565f, +-0.818763f, +-0.580567f, +-0.820029f, +-0.579570f, +-0.821297f, +-0.578576f, +-0.822564f, +-0.577582f, +-0.823835f, +-0.576590f, +-0.825105f, +-0.575597f, +-0.826379f, +-0.574607f, +-0.827653f, +-0.573618f, +-0.828928f, +-0.572630f, +-0.830205f, +-0.571643f, +-0.831483f, +-0.570657f, +-0.832763f, +-0.569674f, +-0.834043f, +-0.568690f, +-0.835326f, +-0.567708f, +-0.836609f, +-0.566728f, +-0.837893f, +-0.565748f, +-0.839179f, +-0.564770f, +-0.840467f, +-0.563792f, +-0.841756f, +-0.562816f, +-0.843047f, +-0.561842f, +-0.844338f, +-0.560869f, +-0.845630f, +-0.559895f, +-0.846926f, +-0.558924f, +-0.848221f, +-0.557954f, +-0.849518f, +-0.556985f, +-0.850817f, +-0.556018f, +-0.852115f, +-0.555051f, +-0.853417f, +-0.554086f, +-0.854718f, +-0.553123f, +-0.856022f, +-0.552160f, +-0.857326f, +-0.551198f, +-0.858633f, +-0.550237f, +-0.859941f, +-0.549277f, +-0.861251f, +-0.548320f, +-0.862560f, +-0.547362f, +-0.863874f, +-0.546406f, +-0.865187f, +-0.545452f, +-0.866501f, +-0.544498f, +-0.867817f, +-0.543547f, +-0.869133f, +-0.542595f, +-0.870452f, +-0.541646f, +-0.871772f, +-0.540697f, +-0.873092f, +-0.539750f, +-0.874415f, +-0.538803f, +-0.875739f, +-0.537858f, +-0.877065f, +-0.536913f, +-0.878393f, +-0.535971f, +-0.879720f, +-0.535030f, +-0.881049f, +-0.534089f, +-0.882380f, +-0.533150f, +-0.883712f, +-0.532211f, +-0.885046f, +-0.531275f, +-0.886380f, +-0.530338f, +-0.887718f, +-0.529404f, +-0.889055f, +-0.528470f, +-0.890394f, +-0.527538f, +-0.891735f, +-0.526608f, +-0.893075f, +-0.525677f, +-0.894419f, +-0.524749f, +-0.895763f, +-0.523821f, +-0.897108f, +-0.522895f, +-0.898456f, +-0.521969f, +-0.899805f, +-0.521044f, +-0.901156f, +-0.520122f, +-0.902506f, +-0.519201f, +-0.903858f, +-0.518280f, +-0.905212f, +-0.517360f, +-0.906568f, +-0.516441f, +-0.907926f, +-0.515525f, +-0.909283f, +-0.514609f, +-0.910642f, +-0.513693f, +-0.912005f, +-0.512781f, +-0.913365f, +-0.511868f, +-0.914729f, +-0.510956f, +-0.916096f, +-0.510046f, +-0.917461f, +-0.509137f, +-0.918829f, +-0.508229f, +-0.920198f, +-0.507322f, +-0.921570f, +-0.506417f, +-0.922940f, +-0.505513f, +-0.924313f, +-0.504608f, +-0.925690f, +-0.503708f, +-0.927064f, +-0.502806f, +-0.928442f, +-0.501906f, +-0.929822f, +-0.501007f, +-0.931201f, +-0.500110f, +-0.932583f, +-0.499213f, +-0.933966f, +-0.498318f, +-0.935351f, +-0.497424f, +-0.936736f, +-0.496532f, +-0.938122f, +-0.495640f, +-0.939511f, +-0.494749f, +-0.940901f, +-0.493859f, +-0.942293f, +-0.492971f, +-0.943685f, +-0.492084f, +-0.945079f, +-0.491198f, +-0.946474f, +-0.490312f, +-0.947872f, +-0.489428f, +-0.949271f, +-0.488546f, +-0.950670f, +-0.487664f, +-0.952071f, +-0.486784f, +-0.953474f, +-0.485905f, +-0.954876f, +-0.485026f, +-0.956282f, +-0.484150f, +-0.957688f, +-0.483274f, +-0.959097f, +-0.482399f, +-0.960506f, +-0.481526f, +-0.961916f, +-0.480654f, +-0.963327f, +-0.479781f, +-0.964743f, +-0.478912f, +-0.966156f, +-0.478042f, +-0.967574f, +-0.477175f, +-0.968990f, +-0.476308f, +-0.970409f, +-0.475442f, +-0.971830f, +-0.474577f, +-0.973253f, +-0.473714f, +-0.974675f, +-0.472851f, +-0.976102f, +-0.471991f, +-0.977525f, +-0.471131f, +-0.978954f, +-0.470271f, +-0.980384f, +-0.469413f, +-0.981814f, +-0.468557f, +-0.983245f, +-0.467701f, +-0.984679f, +-0.466847f, +-0.986113f, +-0.465994f, +-0.987548f, +-0.465142f, +-0.988985f, +-0.464290f, +-0.990424f, +-0.463440f, +-0.991866f, +-0.462591f, +-0.993307f, +-0.461743f, +-0.994750f, +-0.460896f, +-0.996195f, +-0.460052f, +-0.997639f, +-0.459208f, +-0.999086f, +-0.458364f, +-1.000534f, +-0.457522f, +-1.001985f, +-0.456680f, +-1.003438f, +-0.455840f, +-1.004890f, +-0.455002f, +-1.006344f, +-0.454165f, +-1.007798f, +-0.453327f, +-1.009256f, +-0.452492f, +-1.010714f, +-0.451658f, +-1.012174f, +-0.450824f, +-1.013636f, +-0.449992f, +-1.015098f, +-0.449162f, +-1.016561f, +-0.448331f, +-1.018027f, +-0.447502f, +-1.019495f, +-0.446675f, +-1.020963f, +-0.445848f, +-1.022432f, +-0.445022f, +-1.023904f, +-0.444199f, +-1.025375f, +-0.443374f, +-1.026851f, +-0.442552f, +-1.028326f, +-0.441732f, +-1.029801f, +-0.440911f, +-1.031281f, +-0.440092f, +-1.032760f, +-0.439274f, +-1.034241f, +-0.438457f, +-1.035725f, +-0.437642f, +-1.037208f, +-0.436827f, +-1.038693f, +-0.436013f, +-1.040180f, +-0.435202f, +-1.041667f, +-0.434391f, +-1.043156f, +-0.433581f, +-1.044647f, +-0.432771f, +-1.046140f, +-0.431964f, +-1.047633f, +-0.431155f, +-1.049131f, +-0.430351f, +-1.050625f, +-0.429545f, +-1.052125f, +-0.428742f, +-1.053624f, +-0.427939f, +-1.055125f, +-0.427137f, +-1.056628f, +-0.426337f, +-1.058131f, +-0.425538f, +-1.059636f, +-0.424740f, +-1.061143f, +-0.423942f, +-1.062653f, +-0.423146f, +-1.064162f, +-0.422351f, +-1.065673f, +-0.421558f, +-1.067183f, +-0.420764f, +-1.068699f, +-0.419972f, +-1.070214f, +-0.419183f, +-1.071729f, +-0.418392f, +-1.073249f, +-0.417604f, +-1.074768f, +-0.416816f, +-1.076289f, +-0.416031f, +-1.077810f, +-0.415244f, +-1.079336f, +-0.414461f, +-1.080859f, +-0.413678f, +-1.082387f, +-0.412896f, +-1.083914f, +-0.412115f, +-1.085443f, +-0.411335f, +-1.086975f, +-0.410555f, +-1.088509f, +-0.409777f, +-1.090043f, +-0.409002f, +-1.091576f, +-0.408225f, +-1.093114f, +-0.407451f, +-1.094652f, +-0.406677f, +-1.096192f, +-0.405906f, +-1.097732f, +-0.405133f, +-1.099277f, +-0.404363f, +-1.100821f, +-0.403594f, +-1.102364f, +-0.402827f, +-1.103910f, +-0.402059f, +-1.105459f, +-0.401293f, +-1.107009f, +-0.400528f, +-1.108560f, +-0.399764f, +-1.110112f, +-0.399001f, +-1.111667f, +-0.398238f, +-1.113225f, +-0.397478f, +-1.114781f, +-0.396719f, +-1.116338f, +-0.395959f, +-1.117899f, +-0.395202f, +-1.119460f, +-0.394445f, +-1.121024f, +-0.393690f, +-1.122586f, +-0.392936f, +-1.124152f, +-0.392182f, +-1.125719f, +-0.391431f, +-1.127286f, +-0.390679f, +-1.128856f, +-0.389929f, +-1.130428f, +-0.389179f, +-1.132003f, +-0.388431f, +-1.133577f, +-0.387684f, +-1.135153f, +-0.386938f, +-1.136729f, +-0.386194f, +-1.138307f, +-0.385449f, +-1.139888f, +-0.384706f, +-1.141471f, +-0.383964f, +-1.143053f, +-0.383223f, +-1.144638f, +-0.382484f, +-1.146223f, +-0.381745f, +-1.147810f, +-0.381007f, +-1.149399f, +-0.380271f, +-1.150988f, +-0.379536f, +-1.152580f, +-0.378801f, +-1.154174f, +-0.378066f, +-1.155770f, +-0.377334f, +-1.157366f, +-0.376602f, +-1.158964f, +-0.375872f, +-1.160562f, +-0.375143f, +-1.162163f, +-0.374414f, +-1.163765f, +-0.373687f, +-1.165368f, +-0.372961f, +-1.166972f, +-0.372235f, +-1.168580f, +-0.371512f, +-1.170187f, +-0.370788f, +-1.171796f, +-0.370066f, +-1.173408f, +-0.369345f, +-1.175019f, +-0.368625f, +-1.176633f, +-0.367906f, +-1.178247f, +-0.367187f, +-1.179866f, +-0.366471f, +-1.181481f, +-0.365755f, +-1.183102f, +-0.365040f, +-1.184723f, +-0.364326f, +-1.186346f, +-0.363613f, +-1.187968f, +-0.362901f, +-1.189593f, +-0.362190f, +-1.191221f, +-0.361481f, +-1.192848f, +-0.360772f, +-1.194478f, +-0.360064f, +-1.196111f, +-0.359357f, +-1.197742f, +-0.358651f, +-1.199377f, +-0.357946f, +-1.201014f, +-0.357242f, +-1.202650f, +-0.356539f, +-1.204290f, +-0.355838f, +-1.205928f, +-0.355138f, +-1.207569f, +-0.354437f, +-1.209213f, +-0.353739f, +-1.210857f, +-0.353042f, +-1.212503f, +-0.352344f, +-1.214151f, +-0.351649f, +-1.215799f, +-0.350954f, +-1.217450f, +-0.350260f, +-1.219103f, +-0.349567f, +-1.220756f, +-0.348875f, +-1.222412f, +-0.348185f, +-1.224067f, +-0.347496f, +-1.225724f, +-0.346807f, +-1.227385f, +-0.346119f, +-1.229044f, +-0.345433f, +-1.230707f, +-0.344748f, +-1.232369f, +-0.344062f, +-1.234037f, +-0.343379f, +-1.235701f, +-0.342696f, +-1.237371f, +-0.342014f, +-1.239041f, +-0.341335f, +-1.240709f, +-0.340654f, +-1.242385f, +-0.339975f, +-1.244059f, +-0.339298f, +-1.245733f, +-0.338622f, +-1.247409f, +-0.337946f, +-1.249089f, +-0.337272f, +-1.250768f, +-0.336598f, +-1.252449f, +-0.335925f, +-1.254133f, +-0.335253f, +-1.255817f, +-0.334582f, +-1.257504f, +-0.333913f, +-1.259190f, +-0.333244f, +-1.260878f, +-0.332576f, +-1.262570f, +-0.331910f, +-1.264261f, +-0.331244f, +-1.265955f, +-0.330580f, +-1.267648f, +-0.329915f, +-1.269347f, +-0.329253f, +-1.271043f, +-0.328590f, +-1.272744f, +-0.327931f, +-1.274442f, +-0.327270f, +-1.276146f, +-0.326611f, +-1.277849f, +-0.325953f, +-1.279555f, +-0.325297f, +-1.281261f, +-0.324641f, +-1.282969f, +-0.323985f, +-1.284680f, +-0.323331f, +-1.286391f, +-0.322678f, +-1.288105f, +-0.322026f, +-1.289818f, +-0.321375f, +-1.291533f, +-0.320726f, +-1.293249f, +-0.320076f, +-1.294970f, +-0.319429f, +-1.296688f, +-0.318781f, +-1.298412f, +-0.318134f, +-1.300135f, +-0.317490f, +-1.301858f, +-0.316846f, +-1.303583f, +-0.316202f, +-1.305312f, +-0.315560f, +-1.307040f, +-0.314919f, +-1.308771f, +-0.314278f, +-1.310504f, +-0.313639f, +-1.312237f, +-0.313000f, +-1.313974f, +-0.312363f, +-1.315709f, +-0.311726f, +-1.317448f, +-0.311091f, +-1.319185f, +-0.310455f, +-1.320930f, +-0.309823f, +-1.322670f, +-0.309189f, +-1.324417f, +-0.308558f, +-1.326159f, +-0.307927f, +-1.327909f, +-0.307297f, +-1.329657f, +-0.306669f, +-1.331405f, +-0.306040f, +-1.333159f, +-0.305414f, +-1.334910f, +-0.304788f, +-1.336666f, +-0.304162f, +-1.338423f, +-0.303539f, +-1.340178f, +-0.302915f, +-1.341941f, +-0.302294f, +-1.343699f, +-0.301671f, +-1.345463f, +-0.301052f, +-1.347224f, +-0.300432f, +-1.348991f, +-0.299814f, +-1.350757f, +-0.299196f, +-1.352527f, +-0.298580f, +-1.354296f, +-0.297964f, +-1.356068f, +-0.297350f, +-1.357839f, +-0.296736f, +-1.359613f, +-0.296123f, +-1.361391f, +-0.295511f, +-1.363168f, +-0.294901f, +-1.364944f, +-0.294290f, +-1.366727f, +-0.293681f, +-1.368509f, +-0.293074f, +-1.370291f, +-0.292467f, +-1.372076f, +-0.291860f, +-1.373864f, +-0.291255f, +-1.375651f, +-0.290652f, +-1.377438f, +-0.290048f, +-1.379231f, +-0.289445f, +-1.381024f, +-0.288844f, +-1.382816f, +-0.288244f, +-1.384612f, +-0.287643f, +-1.386410f, +-0.287045f, +-1.388208f, +-0.286447f, +-1.390009f, +-0.285850f, +-1.391810f, +-0.285254f, +-1.393613f, +-0.284660f, +-1.395416f, +-0.284066f, +-1.397222f, +-0.283472f, +-1.399031f, +-0.282880f, +-1.400840f, +-0.282289f, +-1.402651f, +-0.281699f, +-1.404462f, +-0.281109f, +-1.406277f, +-0.280521f, +-1.408090f, +-0.279934f, +-1.409907f, +-0.279346f, +-1.411727f, +-0.278761f, +-1.413546f, +-0.278177f, +-1.415365f, +-0.277592f, +-1.417191f, +-0.277010f, +-1.419012f, +-0.276427f, +-1.420840f, +-0.275846f, +-1.422668f, +-0.275266f, +-1.424495f, +-0.274687f, +-1.426325f, +-0.274108f, +-1.428158f, +-0.273531f, +-1.429991f, +-0.272954f, +-1.431827f, +-0.272378f, +-1.433663f, +-0.271803f, +-1.435501f, +-0.271230f, +-1.437339f, +-0.270657f, +-1.439181f, +-0.270084f, +-1.441025f, +-0.269513f, +-1.442869f, +-0.268943f, +-1.444716f, +-0.268374f, +-1.446562f, +-0.267805f, +-1.448412f, +-0.267238f, +-1.450261f, +-0.266671f, +-1.452114f, +-0.266106f, +-1.453965f, +-0.265541f, +-1.455820f, +-0.264976f, +-1.457679f, +-0.264414f, +-1.459536f, +-0.263852f, +-1.461393f, +-0.263290f, +-1.463257f, +-0.262731f, +-1.465117f, +-0.262170f, +-1.466984f, +-0.261613f, +-1.468846f, +-0.261054f, +-1.470716f, +-0.260498f, +-1.472585f, +-0.259942f, +-1.474453f, +-0.259387f, +-1.476324f, +-0.258833f, +-1.478199f, +-0.258280f, +-1.480073f, +-0.257727f, +-1.481951f, +-0.257176f, +-1.483828f, +-0.256625f, +-1.485708f, +-0.256076f, +-1.487588f, +-0.255527f, +-1.489471f, +-0.254979f, +-1.491357f, +-0.254432f, +-1.493243f, +-0.253886f, +-1.495128f, +-0.253341f, +-1.497016f, +-0.252796f, +-1.498908f, +-0.252253f, +-1.500799f, +-0.251710f, +-1.502693f, +-0.251169f, +-1.504587f, +-0.250628f, +-1.506484f, +-0.250088f, +-1.508381f, +-0.249549f, +-1.510280f, +-0.249012f, +-1.512180f, +-0.248474f, +-1.514082f, +-0.247937f, +-1.515988f, +-0.247402f, +-1.517894f, +-0.246866f, +-1.519803f, +-0.246333f, +-1.521711f, +-0.245801f, +-1.523618f, +-0.245268f, +-1.525534f, +-0.244738f, +-1.527443f, +-0.244206f, +-1.529361f, +-0.243677f, +-1.531279f, +-0.243149f, +-1.533195f, +-0.242621f, +-1.535115f, +-0.242094f, +-1.537034f, +-0.241568f, +-1.538956f, +-0.241043f, +-1.540883f, +-0.240519f, +-1.542808f, +-0.239995f, +-1.544737f, +-0.239472f, +-1.546665f, +-0.238952f, +-1.548592f, +-0.238430f, +-1.550528f, +-0.237911f, +-1.552457f, +-0.237391f, +-1.554396f, +-0.236872f, +-1.556333f, +-0.236355f, +-1.558270f, +-0.235839f, +-1.560210f, +-0.235324f, +-1.562149f, +-0.234809f, +-1.564092f, +-0.234294f, +-1.566038f, +-0.233781f, +-1.567984f, +-0.233268f, +-1.569934f, +-0.232757f, +-1.571882f, +-0.232247f, +-1.573829f, +-0.231738f, +-1.575781f, +-0.231229f, +-1.577736f, +-0.230721f, +-1.579690f, +-0.230214f, +-1.581648f, +-0.229706f, +-1.583609f, +-0.229202f, +-1.585565f, +-0.228696f, +-1.587530f, +-0.228193f, +-1.589493f, +-0.227690f, +-1.591455f, +-0.227188f, +-1.593422f, +-0.226686f, +-1.595392f, +-0.226186f, +-1.597361f, +-0.225687f, +-1.599329f, +-0.225188f, +-1.601301f, +-0.224690f, +-1.603277f, +-0.224193f, +-1.605252f, +-0.223696f, +-1.607230f, +-0.223201f, +-1.609208f, +-0.222706f, +-1.611189f, +-0.222213f, +-1.613170f, +-0.221720f, +-1.615154f, +-0.221228f, +-1.617137f, +-0.220736f, +-1.619125f, +-0.220246f, +-1.621111f, +-0.219757f, +-1.623101f, +-0.219267f, +-1.625095f, +-0.218779f, +-1.627088f, +-0.218293f, +-1.629080f, +-0.217807f, +-1.631075f, +-0.217321f, +-1.633075f, +-0.216836f, +-1.635074f, +-0.216353f, +-1.637071f, +-0.215869f, +-1.639078f, +-0.215387f, +-1.641078f, +-0.214906f, +-1.643083f, +-0.214425f, +-1.645091f, +-0.213946f, +-1.647098f, +-0.213467f, +-1.649110f, +-0.212989f, +-1.651120f, +-0.212512f, +-1.653134f, +-0.212034f, +-1.655152f, +-0.211560f, +-1.657164f, +-0.211084f, +-1.659185f, +-0.210610f, +-1.661205f, +-0.210137f, +-1.663224f, +-0.209665f, +-1.665247f, +-0.209194f, +-1.667268f, +-0.208723f, +-1.669294f, +-0.208252f, +-1.671324f, +-0.207783f, +-1.673353f, +-0.207315f, +-1.675385f, +-0.206847f, +-1.677417f, +-0.206381f, +-1.679447f, +-0.205915f, +-1.681482f, +-0.205450f, +-1.683520f, +-0.204986f, +-1.685558f, +-0.204522f, +-1.687600f, +-0.204059f, +-1.689640f, +-0.203597f, +-1.691684f, +-0.203136f, +-1.693728f, +-0.202676f, +-1.695775f, +-0.202217f, +-1.697821f, +-0.201758f, +-1.699871f, +-0.201300f, +-1.701921f, +-0.200843f, +-1.703974f, +-0.200387f, +-1.706026f, +-0.199931f, +-1.708082f, +-0.199476f, +-1.710143f, +-0.199022f, +-1.712202f, +-0.198569f, +-1.714260f, +-0.198117f, +-1.716322f, +-0.197665f, +-1.718388f, +-0.197214f, +-1.720453f, +-0.196765f, +-1.722517f, +-0.196315f, +-1.724585f, +-0.195867f, +-1.726657f, +-0.195419f, +-1.728728f, +-0.194972f, +-1.730803f, +-0.194526f, +-1.732878f, +-0.194081f, +-1.734950f, +-0.193637f, +-1.737027f, +-0.193193f, +-1.739108f, +-0.192750f, +-1.741188f, +-0.192308f, +-1.743272f, +-0.191867f, +-1.745355f, +-0.191426f, +-1.747442f, +-0.190986f, +-1.749528f, +-0.190547f, +-1.751618f, +-0.190109f, +-1.753707f, +-0.189671f, +-1.755800f, +-0.189234f, +-1.757897f, +-0.188799f, +-1.759987f, +-0.188363f, +-1.762088f, +-0.187928f, +-1.764187f, +-0.187495f, +-1.766285f, +-0.187062f, +-1.768387f, +-0.186630f, +-1.770493f, +-0.186198f, +-1.772598f, +-0.185768f, +-1.774702f, +-0.185338f, +-1.776810f, +-0.184909f, +-1.778922f, +-0.184481f, +-1.781033f, +-0.184054f, +-1.783143f, +-0.183627f, +-1.785257f, +-0.183201f, +-1.787375f, +-0.182776f, +-1.789492f, +-0.182352f, +-1.791607f, +-0.181927f, +-1.793733f, +-0.181505f, +-1.795852f, +-0.181083f, +-1.797975f, +-0.180661f, +-1.800102f, +-0.180241f, +-1.802228f, +-0.179821f, +-1.804359f, +-0.179402f, +-1.806487f, +-0.178983f, +-1.808621f, +-0.178566f, +-1.810753f, +-0.178149f, +-1.812889f, +-0.177733f, +-1.815024f, +-0.177317f, +-1.817163f, +-0.176902f, +-1.819308f, +-0.176489f, +-1.821444f, +-0.176075f, +-1.823591f, +-0.175663f, +-1.825736f, +-0.175251f, +-1.827880f, +-0.174840f, +-1.830029f, +-0.174431f, +-1.832175f, +-0.174021f, +-1.834327f, +-0.173612f, +-1.836483f, +-0.173204f, +-1.838637f, +-0.172797f, +-1.840790f, +-0.172391f, +-1.842948f, +-0.171985f, +-1.845110f, +-0.171580f, +-1.847270f, +-0.171176f, +-1.849429f, +-0.170773f, +-1.851592f, +-0.170370f, +-1.853760f, +-0.169968f, +-1.855927f, +-0.169566f, +-1.858098f, +-0.169166f, +-1.860267f, +-0.168765f, +-1.862442f, +-0.168367f, +-1.864614f, +-0.167969f, +-1.866785f, +-0.167570f, +-1.868967f, +-0.167174f, +-1.871140f, +-0.166777f, +-1.873325f, +-0.166383f, +-1.875502f, +-0.165987f, +-1.877690f, +-0.165594f, +-1.879870f, +-0.165200f, +-1.882061f, +-0.164809f, +-1.884243f, +-0.164416f, +-1.886437f, +-0.164025f, +-1.888630f, +-0.163635f, +-1.890820f, +-0.163245f, +-1.893015f, +-0.162857f, +-1.895209f, +-0.162468f, +-1.897407f, +-0.162080f, +-1.899610f, +-0.161693f, +-1.901811f, +-0.161308f, +-1.904010f, +-0.160923f, +-1.906215f, +-0.160539f, +-1.908417f, +-0.160154f, +-1.910631f, +-0.159771f, +-1.912836f, +-0.159389f, +-1.915046f, +-0.159006f, +-1.917261f, +-0.158625f, +-1.919475f, +-0.158246f, +-1.921686f, +-0.157866f, +-1.923902f, +-0.157487f, +-1.926123f, +-0.157109f, +-1.928342f, +-0.156731f, +-1.930566f, +-0.156354f, +-1.932789f, +-0.155978f, +-1.935016f, +-0.155603f, +-1.937241f, +-0.155228f, +-1.939471f, +-0.154854f, +-1.941699f, +-0.154481f, +-1.943932f, +-0.154109f, +-1.946163f, +-0.153736f, +-1.948399f, +-0.153366f, +-1.950633f, +-0.152995f, +-1.952872f, +-0.152626f, +-1.955109f, +-0.152256f, +-1.957351f, +-0.151887f, +-1.959599f, +-0.151520f, +-1.961843f, +-0.151153f, +-1.964086f, +-0.150787f, +-1.966334f, +-0.150421f, +-1.968587f, +-0.150056f, +-1.970838f, +-0.149692f, +-1.973087f, +-0.149329f, +-1.975341f, +-0.148965f, +-1.977600f, +-0.148603f, +-1.979857f, +-0.148242f, +-1.982112f, +-0.147881f, +-1.984379f, +-0.147521f, +-1.986636f, +-0.147162f, +-1.988899f, +-0.146803f, +-1.991167f, +-0.146445f, +-1.993433f, +-0.146088f, +-1.995703f, +-0.145731f, +-1.997972f, +-0.145375f, +-2.000246f, +-0.145020f, +-2.002518f, +-0.144665f, +-2.004794f, +-0.144312f, +-2.007069f, +-0.143958f, +-2.009348f, +-0.143605f, +-2.011633f, +-0.143254f, +-2.013908f, +-0.142902f, +-2.016196f, +-0.142551f, +-2.018482f, +-0.142202f, +-2.020765f, +-0.141853f, +-2.023053f, +-0.141504f, +-2.025347f, +-0.141156f, +-2.027639f, +-0.140809f, +-2.029928f, +-0.140463f, +-2.032222f, +-0.140116f, +-2.034522f, +-0.139771f, +-2.036819f, +-0.139426f, +-2.039122f, +-0.139083f, +-2.041421f, +-0.138739f, +-2.043727f, +-0.138397f, +-2.046030f, +-0.138056f, +-2.048331f, +-0.137714f, +-2.050644f, +-0.137373f, +-2.052955f, +-0.137034f, +-2.055264f, +-0.136694f, +-2.057579f, +-0.136356f, +-2.059890f, +-0.136018f, +-2.062207f, +-0.135681f, +-2.064522f, +-0.135344f, +-2.066841f, +-0.135008f, +-2.069167f, +-0.134673f, +-2.071489f, +-0.134339f, +-2.073809f, +-0.134005f, +-2.076135f, +-0.133671f, +-2.078466f, +-0.133338f, +-2.080794f, +-0.133007f, +-2.083120f, +-0.132675f, +-2.085460f, +-0.132345f, +-2.087789f, +-0.132015f, +-2.090122f, +-0.131685f, +-2.092462f, +-0.131357f, +-2.094799f, +-0.131028f, +-2.097141f, +-0.130701f, +-2.099481f, +-0.130374f, +-2.101826f, +-0.130047f, +-2.104177f, +-0.129722f, +-2.106525f, +-0.129397f, +-2.108870f, +-0.129073f, +-2.111221f, +-0.128750f, +-2.113570f, +-0.128427f, +-2.115923f, +-0.128104f, +-2.118282f, +-0.127782f, +-2.120639f, +-0.127461f, +-2.123001f, +-0.127140f, +-2.125360f, +-0.126821f, +-2.127716f, +-0.126502f, +-2.130078f, +-0.126184f, +-2.132446f, +-0.125866f, +-2.134811f, +-0.125548f, +-2.137181f, +-0.125231f, +-2.139557f, +-0.124916f, +-2.141921f, +-0.124600f, +-2.144300f, +-0.124285f, +-2.146676f, +-0.123971f, +-2.149049f, +-0.123658f, +-2.151428f, +-0.123345f, +-2.153812f, +-0.123032f, +-2.156193f, +-0.122721f, +-2.158571f, +-0.122411f, +-2.160955f, +-0.122100f, +-2.163345f, +-0.121790f, +-2.165732f, +-0.121481f, +-2.168124f, +-0.121173f, +-2.170514f, +-0.120865f, +-2.172909f, +-0.120558f, +-2.175300f, +-0.120251f, +-2.177699f, +-0.119945f, +-2.180093f, +-0.119640f, +-2.182494f, +-0.119334f, +-2.184900f, +-0.119030f, +-2.187303f, +-0.118727f, +-2.189703f, +-0.118424f, +-2.192109f, +-0.118122f, +-2.194520f, +-0.117820f, +-2.196929f, +-0.117519f, +-2.199343f, +-0.117218f, +-2.201754f, +-0.116918f, +-2.204170f, +-0.116619f, +-2.206584f, +-0.116320f, +-2.209004f, +-0.116023f, +-2.211420f, +-0.115725f, +-2.213842f, +-0.115429f, +-2.216261f, +-0.115133f, +-2.218685f, +-0.114836f, +-2.221115f, +-0.114541f, +-2.223543f, +-0.114247f, +-2.225976f, +-0.113953f, +-2.228406f, +-0.113660f, +-2.230832f, +-0.113367f, +-2.233273f, +-0.113076f, +-2.235702f, +-0.112784f, +-2.238146f, +-0.112493f, +-2.240587f, +-0.112203f, +-2.243025f, +-0.111913f, +-2.245468f, +-0.111625f, +-2.247907f, +-0.111336f, +-2.250353f, +-0.111048f, +-2.252805f, +-0.110761f, +-2.255253f, +-0.110474f, +-2.257707f, +-0.110188f, +-2.260158f, +-0.109902f, +-2.262615f, +-0.109617f, +-2.265068f, +-0.109333f, +-2.267527f, +-0.109050f, +-2.269983f, +-0.108766f, +-2.272444f, +-0.108483f, +-2.274912f, +-0.108201f, +-2.277375f, +-0.107920f, +-2.279836f, +-0.107640f, +-2.282302f, +-0.107359f, +-2.284775f, +-0.107080f, +-2.287243f, +-0.106800f, +-2.289718f, +-0.106522f, +-2.292189f, +-0.106244f, +-2.294667f, +-0.105967f, +-2.297140f, +-0.105691f, +-2.299620f, +-0.105414f, +-2.302105f, +-0.105138f, +-2.304587f, +-0.104863f, +-2.307075f, +-0.104589f, +-2.309560f, +-0.104315f, +-2.312040f, +-0.104041f, +-2.314536f, +-0.103770f, +-2.317019f, +-0.103497f, +-2.319517f, +-0.103225f, +-2.322013f, +-0.102955f, +-2.324503f, +-0.102684f, +-2.327001f, +-0.102414f, +-2.329504f, +-0.102145f, +-2.332004f, +-0.101876f, +-2.334509f, +-0.101608f, +-2.337011f, +-0.101340f, +-2.339519f, +-0.101073f, +-2.342023f, +-0.100806f, +-2.344533f, +-0.100541f, +-2.347039f, +-0.100276f, +-2.349551f, +-0.100010f, +-2.352070f, +-0.099746f, +-2.354584f, +-0.099482f, +-2.357104f, +-0.099219f, +-2.359621f, +-0.098957f, +-2.362144f, +-0.098695f, +-2.364662f, +-0.098433f, +-2.367188f, +-0.098172f, +-2.369719f, +-0.097912f, +-2.372246f, +-0.097653f, +-2.374769f, +-0.097393f, +-2.377298f, +-0.097134f, +-2.379833f, +-0.096877f, +-2.382364f, +-0.096619f, +-2.384902f, +-0.096361f, +-2.387446f, +-0.096106f, +-2.389975f, +-0.095849f, +-2.392521f, +-0.095594f, +-2.395063f, +-0.095339f, +-2.397610f, +-0.095085f, +-2.400154f, +-0.094831f, +-2.402704f, +-0.094578f, +-2.405249f, +-0.094325f, +-2.407801f, +-0.094073f, +-2.410348f, +-0.093822f, +-2.412902f, +-0.093570f, +-2.415462f, +-0.093320f, +-2.418019f, +-0.093070f, +-2.420581f, +-0.092821f, +-2.423138f, +-0.092572f, +-2.425703f, +-0.092324f, +-2.428261f, +-0.092076f, +-2.430828f, +-0.091828f, +-2.433400f, +-0.091581f, +-2.435968f, +-0.091335f, +-2.438542f, +-0.091090f, +-2.441111f, +-0.090844f, +-2.443688f, +-0.090600f, +-2.446259f, +-0.090356f, +-2.448837f, +-0.090112f, +-2.451422f, +-0.089869f, +-2.454001f, +-0.089626f, +-2.456588f, +-0.089384f, +-2.459168f, +-0.089143f, +-2.461757f, +-0.088902f, +-2.464340f, +-0.088662f, +-2.466929f, +-0.088421f, +-2.469525f, +-0.088182f, +-2.472117f, +-0.087944f, +-2.474703f, +-0.087705f, +-2.477308f, +-0.087467f, +-2.479907f, +-0.087230f, +-2.482502f, +-0.086994f, +-2.485103f, +-0.086757f, +-2.487710f, +-0.086521f, +-2.490313f, +-0.086287f, +-2.492910f, +-0.086051f, +-2.495527f, +-0.085817f, +-2.498138f, +-0.085584f, +-2.500744f, +-0.085351f, +-2.503356f, +-0.085118f, +-2.505975f, +-0.084886f, +-2.508589f, +-0.084654f, +-2.511209f, +-0.084423f, +-2.513825f, +-0.084193f, +-2.516447f, +-0.083962f, +-2.519076f, +-0.083733f, +-2.521700f, +-0.083504f, +-2.524317f, +-0.083275f, +-2.526954f, +-0.083048f, +-2.529573f, +-0.082820f, +-2.532212f, +-0.082593f, +-2.534845f, +-0.082367f, +-2.537473f, +-0.082140f, +-2.540119f, +-0.081915f, +-2.542748f, +-0.081690f, +-2.545396f, +-0.081465f, +-2.548039f, +-0.081241f, +-2.550675f, +-0.081018f, +-2.553318f, +-0.080795f, +-2.555969f, +-0.080573f, +-2.558613f, +-0.080350f, +-2.561265f, +-0.080128f, +-2.563924f, +-0.079907f, +-2.566576f, +-0.079687f, +-2.569223f, +-0.079468f, +-2.571877f, +-0.079248f, +-2.574538f, +-0.079028f, +-2.577206f, +-0.078809f, +-2.579868f, +-0.078592f, +-2.582524f, +-0.078375f, +-2.585187f, +-0.078157f, +-2.587857f, +-0.077940f, +-2.590534f, +-0.077725f, +-2.593191f, +-0.077509f, +-2.595869f, +-0.077294f, +-2.598541f, +-0.077079f, +-2.601220f, +-0.076865f, +-2.603893f, +-0.076651f, +-2.606573f, +-0.076437f, +-2.609259f, +-0.076225f, +-2.611941f, +-0.076013f, +-2.614615f, +-0.075801f, +-2.617310f, +-0.075589f, +-2.619998f, +-0.075379f, +-2.622680f, +-0.075169f, +-2.625369f, +-0.074958f, +-2.628066f, +-0.074749f, +-2.630756f, +-0.074540f, +-2.633453f, +-0.074331f, +-2.636157f, +-0.074124f, +-2.638855f, +-0.073917f, +-2.641547f, +-0.073709f, +-2.644259f, +-0.073503f, +-2.646950f, +-0.073297f, +-2.649663f, +-0.073091f, +-2.652370f, +-0.072886f, +-2.655083f, +-0.072681f, +-2.657790f, +-0.072477f, +-2.660503f, +-0.072274f, +-2.663210f, +-0.072070f, +-2.665939f, +-0.071868f, +-2.668647f, +-0.071665f, +-2.671376f, +-0.071463f, +-2.674098f, +-0.071262f, +-2.676814f, +-0.071061f, +-2.679536f, +-0.070860f, +-2.682265f, +-0.070661f, +-2.684988f, +-0.070461f, +-2.687718f, +-0.070262f, +-2.690456f, +-0.070063f, +-2.693187f, +-0.069865f, +-2.695924f, +-0.069667f, +-2.698654f, +-0.069470f, +-2.701392f, +-0.069273f, +-2.704137f, +-0.069077f, +-2.706876f, +-0.068881f, +-2.709621f, +-0.068686f, +-2.712359f, +-0.068491f, +-2.715105f, +-0.068296f, +-2.717858f, +-0.068102f, +-2.720604f, +-0.067908f, +-2.723357f, +-0.067715f, +-2.726117f, +-0.067522f, +-2.728870f, +-0.067330f, +-2.731631f, +-0.067138f, +-2.734384f, +-0.066947f, +-2.737144f, +-0.066755f, +-2.739912f, +-0.066565f, +-2.742673f, +-0.066375f, +-2.745440f, +-0.066186f, +-2.748201f, +-0.065997f, +-2.750968f, +-0.065808f, +-2.753744f, +-0.065620f, +-2.756511f, +-0.065432f, +-2.759285f, +-0.065244f, +-2.762068f, +-0.065057f, +-2.764843f, +-0.064870f, +-2.767625f, +-0.064685f, +-2.770400f, +-0.064499f, +-2.773181f, +-0.064313f, +-2.775970f, +-0.064129f, +-2.778751f, +-0.063945f, +-2.781541f, +-0.063761f, +-2.784322f, +-0.063577f, +-2.787126f, +-0.063395f, +-2.789906f, +-0.063211f, +-2.792710f, +-0.063029f, +-2.795506f, +-0.062848f, +-2.798293f, +-0.062666f, +-2.801104f, +-0.062485f, +-2.803906f, +-0.062305f, +-2.806700f, +-0.062125f, +-2.809501f, +-0.061946f, +-2.812312f, +-0.061766f, +-2.815129f, +-0.061587f, +-2.817938f, +-0.061410f, +-2.820737f, +-0.061231f, +-2.823562f, +-0.061053f, +-2.826378f, +-0.060877f, +-2.829185f, +-0.060701f, +-2.831999f, +-0.060524f, +-2.834822f, +-0.060348f, +-2.837652f, +-0.060173f, +-2.840473f, +-0.059997f, +-2.843303f, +-0.059823f, +-2.846123f, +-0.059649f, +-2.848951f, +-0.059475f, +-2.851788f, +-0.059302f, +-2.854614f, +-0.059129f, +-2.857450f, +-0.058957f, +-2.860275f, +-0.058784f, +-2.863127f, +-0.058614f, +-2.865951f, +-0.058442f, +-2.868800f, +-0.058271f, +-2.871640f, +-0.058101f, +-2.874489f, +-0.057931f, +-2.877327f, +-0.057762f, +-2.880174f, +-0.057592f, +-2.883029f, +-0.057424f, +-2.885874f, +-0.057255f, +-2.888727f, +-0.057087f, +-2.891589f, +-0.056920f, +-2.894440f, +-0.056752f, +-2.897299f, +-0.056586f, +-2.900149f, +-0.056419f, +-2.903025f, +-0.056254f, +-2.905874f, +-0.056088f, +-2.908748f, +-0.055923f, +-2.911612f, +-0.055758f, +-2.914484f, +-0.055594f, +-2.917346f, +-0.055430f, +-2.920217f, +-0.055266f, +-2.923095f, +-0.055104f, +-2.925964f, +-0.054941f, +-2.928840f, +-0.054778f, +-2.931726f, +-0.054617f, +-2.934599f, +-0.054455f, +-2.937482f, +-0.054294f, +-2.940373f, +-0.054133f, +-2.943253f, +-0.053973f, +-2.946143f, +-0.053813f, +-2.949021f, +-0.053653f, +-2.951926f, +-0.053495f, +-2.954802f, +-0.053335f, +-2.957705f, +-0.053177f, +-2.960597f, +-0.053019f, +-2.963497f, +-0.052862f, +-2.966387f, +-0.052704f, +-2.969305f, +-0.052548f, +-2.972192f, +-0.052391f, +-2.975106f, +-0.052235f, +-2.978010f, +-0.052079f, +-2.980922f, +-0.051924f, +-2.983824f, +-0.051769f, +-2.986733f, +-0.051614f, +-2.989651f, +-0.051461f, +-2.992558f, +-0.051307f, +-2.995472f, +-0.051153f, +-2.998396f, +-0.051001f, +-3.001307f, +-0.050848f, +-3.004228f, +-0.050696f, +-3.007158f, +-0.050544f, +-3.010075f, +-0.050392f, +-3.013021f, +-0.050241f, +-3.015934f, +-0.050090f, +-3.018878f, +-0.049940f, +-3.021809f, +-0.049790f, +-3.024729f, +-0.049640f, +-3.027677f, +-0.049491f, +-3.030613f, +-0.049343f, +-3.033538f, +-0.049193f, +-3.036491f, +-0.049045f, +-3.039434f, +-0.048898f, +-3.042363f, +-0.048750f, +-3.045321f, +-0.048603f, +-3.048268f, +-0.048457f, +-3.051203f, +-0.048310f, +-3.054167f, +-0.048165f, +-3.057118f, +-0.048019f, +-3.060079f, +-0.047874f, +-3.063026f, +-0.047729f, +-3.065984f, +-0.047584f, +-3.068949f, +-0.047441f, +-3.071901f, +-0.047297f, +-3.074862f, +-0.047153f, +-3.077832f, +-0.047011f, +-3.080789f, +-0.046868f, +-3.083756f, +-0.046726f, +-3.086729f, +-0.046583f, +-3.089713f, +-0.046442f, +-3.092684f, +-0.046301f, +-3.095663f, +-0.046160f, +-3.098629f, +-0.046020f, +-3.101604f, +-0.045880f, +-3.104587f, +-0.045740f, +-3.107559f, +-0.045600f, +-3.110560f, +-0.045461f, +-3.113548f, +-0.045323f, +-3.116523f, +-0.045185f, +-3.119505f, +-0.045047f, +-3.122498f, +-0.044908f, +-3.125500f, +-0.044771f, +-3.128486f, +-0.044634f, +-3.131483f, +-0.044497f, +-3.134489f, +-0.044362f, +-3.137480f, +-0.044226f, +-3.140481f, +-0.044090f, +-3.143490f, +-0.043955f, +-3.146485f, +-0.043820f, +-3.149490f, +-0.043685f, +-3.152503f, +-0.043552f, +-3.155502f, +-0.043417f, +-3.158534f, +-0.043284f, +-3.161527f, +-0.043151f, +-3.164554f, +-0.043018f, +-3.167566f, +-0.042886f, +-3.170585f, +-0.042753f, +-3.173616f, +-0.042622f, +-3.176631f, +-0.042490f, +-3.179655f, +-0.042359f, +-3.182689f, +-0.042228f, +-3.185707f, +-0.042098f, +-3.188735f, +-0.041967f, +-3.191771f, +-0.041838f, +-3.194794f, +-0.041709f, +-3.197824f, +-0.041580f, +-3.200864f, +-0.041450f, +-3.203914f, +-0.041322f, +-3.206947f, +-0.041194f, +-3.209991f, +-0.041067f, +-3.213018f, +-0.040939f, +-3.216079f, +-0.040812f, +-3.219126f, +-0.040686f, +-3.222156f, +-0.040558f, +-3.225221f, +-0.040432f, +-3.228270f, +-0.040308f, +-3.231302f, +-0.040182f, +-3.234370f, +-0.040057f, +-3.237422f, +-0.039932f, +-3.240483f, +-0.039807f, +-3.243553f, +-0.039683f, +-3.246607f, +-0.039559f, +-3.249670f, +-0.039435f, +-3.252743f, +-0.039313f, +-3.255799f, +-0.039190f, +-3.258865f, +-0.039067f, +-3.261940f, +-0.038945f, +-3.265024f, +-0.038823f, +-3.268092f, +-0.038701f, +-3.271169f, +-0.038581f, +-3.274229f, +-0.038459f, +-3.277326f, +-0.038339f, +-3.280406f, +-0.038218f, +-3.283495f, +-0.038099f, +-3.286566f, +-0.037979f, +-3.289646f, +-0.037860f, +-3.292738f, +-0.037740f, +-3.295837f, +-0.037622f, +-3.298921f, +-0.037504f, +-3.302012f, +-0.037385f, +-3.305115f, +-0.037268f, +-3.308199f, +-0.037151f, +-3.311293f, +-0.037033f, +-3.314397f, +-0.036916f, +-3.317508f, +-0.036800f, +-3.320603f, +-0.036684f, +-3.323708f, +-0.036567f, +-3.326824f, +-0.036452f, +-3.329919f, +-0.036336f, +-3.333053f, +-0.036222f, +-3.336140f, +-0.036107f, +-3.339266f, +-0.035993f, +-3.342372f, +-0.035879f, +-3.345489f, +-0.035765f, +-3.348614f, +-0.035651f, +-3.351751f, +-0.035538f, +-3.354867f, +-0.035425f, +-3.357994f, +-0.035313f, +-3.361102f, +-0.035200f, +-3.364249f, +-0.035088f, +-3.367377f, +-0.034977f, +-3.370514f, +-0.034866f, +-3.373631f, +-0.034755f, +-3.376759f, +-0.034644f, +-3.379896f, +-0.034533f, +-3.383043f, +-0.034424f, +-3.386172f, +-0.034313f, +-3.389338f, +-0.034204f, +-3.392455f, +-0.034095f, +-3.395614f, +-0.033986f, +-3.398750f, +-0.033877f, +-3.401898f, +-0.033769f, +-3.405056f, +-0.033660f, +-3.408222f, +-0.033553f, +-3.411369f, +-0.033445f, +-3.414526f, +-0.033338f, +-3.417693f, +-0.033231f, +-3.420840f, +-0.033125f, +-3.423996f, +-0.033018f, +-3.427162f, +-0.032912f, +-3.430338f, +-0.032806f, +-3.433493f, +-0.032701f, +-3.436658f, +-0.032595f, +-3.439835f, +-0.032490f, +-3.443020f, +-0.032386f, +-3.446183f, +-0.032281f, +-3.449359f, +-0.032177f, +-3.452542f, +-0.032074f, +-3.455706f, +-0.031971f, +-3.458880f, +-0.031867f, +-3.462063f, +-0.031764f, +-3.465255f, +-0.031662f, +-3.468427f, +-0.031559f, +-3.471641f, +-0.031457f, +-3.474833f, +-0.031355f, +-3.478003f, +-0.031253f, +-3.481215f, +-0.031152f, +-3.484405f, +-0.031051f, +-3.487605f, +-0.030951f, +-3.490783f, +-0.030850f, +-3.494004f, +-0.030750f, +-3.497201f, +-0.030650f, +-3.500411f, +-0.030551f, +-3.503595f, +-0.030451f, +-3.506825f, +-0.030352f, +-3.510030f, +-0.030254f, +-3.513213f, +-0.030155f, +-3.516440f, +-0.030057f, +-3.519644f, +-0.029959f, +-3.522856f, +-0.029861f, +-3.526080f, +-0.029764f, +-3.529315f, +-0.029667f, +-3.532525f, +-0.029570f, +-3.535746f, +-0.029473f, +-3.538977f, +-0.029377f, +-3.542186f, +-0.029280f, +-3.545438f, +-0.029185f, +-3.548666f, +-0.029089f, +-3.551904f, +-0.028994f, +-3.555119f, +-0.028900f, +-3.558342f, +-0.028805f, +-3.561578f, +-0.028710f, +-3.564822f, +-0.028616f, +-3.568079f, +-0.028522f, +-3.571309f, +-0.028428f, +-3.574551f, +-0.028335f, +-3.577803f, +-0.028241f, +-3.581067f, +-0.028148f, +-3.584304f, +-0.028056f, +-3.587552f, +-0.027963f, +-3.590808f, +-0.027872f, +-3.594043f, +-0.027779f, +-3.597323f, +-0.027688f, +-3.600576f, +-0.027596f, +-3.603840f, +-0.027506f, +-3.607078f, +-0.027414f, +-3.610365f, +-0.027324f, +-3.613624f, +-0.027234f, +-3.616893f, +-0.027144f, +-3.620137f, +-0.027054f, +-3.623428f, +-0.026964f, +-3.626694f, +-0.026875f, +-3.629970f, +-0.026786f, +-3.633255f, +-0.026697f, +-3.636515f, +-0.026609f, +-3.639785f, +-0.026521f, +-3.643066f, +-0.026432f, +-3.646358f, +-0.026344f, +-3.649658f, +-0.026257f, +-3.652932f, +-0.026169f, +-3.656220f, +-0.026082f, +-3.659516f, +-0.025995f, +-3.662823f, +-0.025909f, +-3.666101f, +-0.025823f, +-3.669390f, +-0.025736f, +-3.672690f, +-0.025650f, +-3.676003f, +-0.025565f, +-3.679285f, +-0.025480f, +-3.682580f, +-0.025395f, +-3.685883f, +-0.025310f, +-3.689200f, +-0.025225f, +-3.692487f, +-0.025140f, +-3.695823f, +-0.025056f, +-3.699132f, +-0.024972f, +-3.702452f, +-0.024889f, +-3.705740f, +-0.024805f, +-3.709082f, +-0.024722f, +-3.712393f, +-0.024639f, +-3.715716f, +-0.024557f, +-3.719008f, +-0.024474f, +-3.722353f, +-0.024392f, +-3.725667f, +-0.024310f, +-3.728994f, +-0.024228f, +-3.732330f, +-0.024146f, +-3.735678f, +-0.024065f, +-3.738994f, +-0.023984f, +-3.742323f, +-0.023903f, +-3.745661f, +-0.023822f, +-3.749013f, +-0.023743f, +-3.752330f, +-0.023663f, +-3.755661f, +-0.023583f, +-3.759000f, +-0.023503f, +-3.762354f, +-0.023423f, +-3.765718f, +-0.023344f, +-3.769050f, +-0.023266f, +-3.772391f, +-0.023187f, +-3.775745f, +-0.023108f, +-3.779110f, +-0.023029f, +-3.782487f, +-0.022951f, +-3.785831f, +-0.022874f, +-3.789186f, +-0.022796f, +-3.792552f, +-0.022719f, +-3.795885f, +-0.022641f, +-3.799274f, +-0.022565f, +-3.802631f, +-0.022488f, +-3.805998f, +-0.022411f, +-3.809375f, +-0.022336f, +-3.812721f, +-0.022259f, +-3.816122f, +-0.022183f, +-3.819490f, +-0.022108f, +-3.822868f, +-0.022032f, +-3.826259f, +-0.021957f, +-3.829613f, +-0.021882f, +-3.833027f, +-0.021807f, +-3.836406f, +-0.021732f, +-3.839794f, +-0.021659f, +-3.843149f, +-0.021584f, +-3.846563f, +-0.021511f, +-3.849940f, +-0.021437f, +-3.853330f, +-0.021364f, +-3.856730f, +-0.021290f, +-3.860143f, +-0.021218f, +-3.863518f, +-0.021145f, +-3.866905f, +-0.021073f, +-3.870304f, +-0.021000f, +-3.873717f, +-0.020927f, +-3.877139f, +-0.020856f, +-3.880524f, +-0.020784f, +-3.883923f, +-0.020713f, +-3.887330f, +-0.020642f, +-3.890749f, +-0.020570f, +-3.894183f, +-0.020500f, +-3.897579f, +-0.020429f, +-3.900984f, +-0.020358f, +-3.904453f, +-0.020288f, +-3.907831f, +-0.020218f, +-3.911273f, +-0.020149f, +-3.914677f, +-0.020078f, +-3.918143f, +-0.020009f, +-3.921567f, +-0.019941f, +-3.924955f, +-0.019871f, +-3.928406f, +-0.019803f, +-3.931817f, +-0.019733f, +-3.935291f, +-0.019665f, +-3.938726f, +-0.019597f, +-3.942172f, +-0.019529f, +-3.945581f, +-0.019461f, +-3.949051f, +-0.019394f, +-3.952480f, +-0.019327f, +-3.955922f, +-0.019259f, +-3.959378f, +-0.019192f, +-3.962843f, +-0.019126f, +-3.966267f, +-0.019059f, +-3.969705f, +-0.018993f, +-3.973153f, +-0.018927f, +-3.976615f, +-0.018861f, +-3.980086f, +-0.018795f, +-3.983573f, +-0.018729f, +-3.987017f, +-0.018664f, +-3.990470f, +-0.018599f, +-3.993938f, +-0.018534f, +-3.997418f, +-0.018470f, +-4.000854f, +-0.018404f, +-4.004359f, +-0.018340f, +-4.007819f, +-0.018276f, +-4.011292f, +-0.018212f, +-4.014777f, +-0.018148f, +-4.018274f, +-0.018085f, +-4.021727f, +-0.018021f, +-4.025192f, +-0.017958f, +-4.028669f, +-0.017895f, +-4.032158f, +-0.017832f, +-4.035659f, +-0.017769f, +-4.039176f, +-0.017707f, +-4.042644f, +-0.017645f, +-4.046124f, +-0.017583f, +-4.049620f, +-0.017521f, +-4.053125f, +-0.017459f, +-4.056645f, +-0.017397f, +-4.060116f, +-0.017336f, +-4.063602f, +-0.017275f, +-4.067100f, +-0.017214f, +-4.070608f, +-0.017153f, +-4.074131f, +-0.017092f, +-4.077666f, +-0.017032f, +-4.081151f, +-0.016972f, +-4.084651f, +-0.016912f, +-4.088163f, +-0.016852f, +-4.091688f, +-0.016792f, +-4.095226f, +-0.016733f, +-4.098715f, +-0.016674f, +-4.102216f, +-0.016614f, +-4.105790f, +-0.016555f, +-4.109316f, +-0.016497f, +-4.112793f, +-0.016438f, +-4.116344f, +-0.016380f, +-4.119849f, +-0.016321f, +-4.123425f, +-0.016264f, +-4.126951f, +-0.016206f, +-4.130489f, +-0.016149f, +-4.133981f, +-0.016091f, +-4.137544f, +-0.016034f, +-4.141060f, +-0.015976f, +-4.144649f, +-0.015919f, +-4.148187f, +-0.015862f, +-4.151741f, +-0.015806f, +-4.155243f, +-0.015749f, +-4.158818f, +-0.015693f, +-4.162345f, +-0.015637f, +-4.165946f, +-0.015581f, +-4.169498f, +-0.015526f, +-4.172997f, +-0.015470f, +-4.176575f, +-0.015414f, +-4.180165f, +-0.015359f, +-4.183702f, +-0.015304f, +-4.187251f, +-0.015250f, +-4.190813f, +-0.015195f, +-4.194388f, +-0.015140f, +-4.197975f, +-0.015085f, +-4.201575f, +-0.015031f, +-4.205121f, +-0.014978f, +-4.208679f, +-0.014924f, +-4.212250f, +-0.014870f, +-4.215833f, +-0.014816f, +-4.219430f, +-0.014763f, +-4.222974f, +-0.014710f, +-4.226596f, +-0.014657f, +-4.230166f, +-0.014604f, +-4.233745f, +-0.014551f, +-4.237336f, +-0.014499f, +-4.240945f, +-0.014447f, +-4.244492f, +-0.014394f, +-4.248126f, +-0.014342f, +-4.251699f, +-0.014291f, +-4.255288f, +-0.014239f, +-4.258890f, +-0.014187f, +-4.262501f, +-0.014135f, +-4.266130f, +-0.014085f, +-4.269699f, +-0.014033f, +-4.273350f, +-0.013982f, +-4.276945f, +-0.013932f, +-4.280553f, +-0.013881f, +-4.284174f, +-0.013831f, +-4.287734f, +-0.013781f, +-4.291382f, +-0.013731f, +-4.294968f, +-0.013680f, +-4.298642f, +-0.013630f, +-4.302255f, +-0.013581f, +-4.305880f, +-0.013531f, +-4.309519f, +-0.013482f, +-4.313100f, +-0.013433f, +-4.316765f, +-0.013384f, +-4.320368f, +-0.013336f, +-4.323983f, +-0.013287f, +-4.327616f, +-0.013238f, +-4.331258f, +-0.013190f, +-4.334913f, +-0.013141f, +-4.338582f, +-0.013093f, +-4.342191f, +-0.013046f, +-4.345813f, +-0.012998f, +-4.349443f, +-0.012950f, +-4.353091f, +-0.012903f, +-4.356748f, +-0.012855f, +-4.360423f, +-0.012808f, +-4.364107f, +-0.012761f, +-4.367730f, +-0.012714f, +-4.371365f, +-0.012668f, +-4.375009f, +-0.012621f, +-4.378672f, +-0.012575f, +-4.382347f, +-0.012528f, +-4.386036f, +-0.012483f, +-4.389657f, +-0.012436f, +-4.393369f, +-0.012390f, +-4.397017f, +-0.012345f, +-4.400678f, +-0.012299f, +-4.404353f, +-0.012254f, +-4.408041f, +-0.012209f, +-4.411659f, +-0.012164f, +-4.415374f, +-0.012119f, +-4.419024f, +-0.012074f, +-4.422767f, +-0.012029f, +-4.426439f, +-0.011985f, +-4.430125f, +-0.011940f, +-4.433824f, +-0.011896f, +-4.437457f, +-0.011852f, +-4.441183f, +-0.011808f, +-4.444837f, +-0.011765f, +-4.448510f, +-0.011720f, +-4.452278f, +-0.011677f, +-4.455973f, +-0.011634f, +-4.459599f, +-0.011591f, +-4.463322f, +-0.011547f, +-4.467063f, +-0.011505f, +-4.470724f, +-0.011462f, +-4.474405f, +-0.011419f, +-4.478183f, +-0.011376f, +-4.481890f, +-0.011334f, +-4.485612f, +-0.011292f, +-4.489257f, +-0.011250f, +-4.493001f, +-0.011209f, +-4.496674f, +-0.011166f, +-4.500451f, +-0.011125f, +-4.504151f, +-0.011083f, +-4.507865f, +-0.011042f, +-4.511587f, +-0.011000f, +-4.515328f, +-0.010959f, +-4.519084f, +-0.010918f, +-4.522760f, +-0.010877f, +-4.526543f, +-0.010837f, +-4.530247f, +-0.010796f, +-4.533965f, +-0.010756f, +-4.537697f, +-0.010715f, +-4.541442f, +-0.010675f, +-4.545207f, +-0.010635f, +-4.548885f, +-0.010595f, +-4.552673f, +-0.010556f, +-4.556379f, +-0.010515f, +-4.560195f, +-0.010476f, +-4.563934f, +-0.010436f, +-4.567682f, +-0.010397f, +-4.571444f, +-0.010358f, +-4.575127f, +-0.010319f, +-4.578917f, +-0.010280f, +-4.582722f, +-0.010241f, +-4.586447f, +-0.010203f, +-4.590180f, +-0.010164f, +-4.593933f, +-0.010126f, +-4.597701f, +-0.010088f, +-4.601477f, +-0.010049f, +-4.605272f, +-0.010011f, +-4.609077f, +-0.009974f, +-4.612800f, +-0.009936f, +-4.616537f, +-0.009898f, +-4.620384f, +-0.009860f, +-4.624149f, +-0.009823f, +-4.627929f, +-0.009786f, +-4.631717f, +-0.009749f, +-4.635420f, +-0.009712f, +-4.639243f, +-0.009675f, +-4.643080f, +-0.009638f, +-4.646826f, +-0.009602f, +-4.650587f, +-0.009566f, +-4.654361f, +-0.009528f, +-4.658257f, +-0.009493f, +-4.661953f, +-0.009457f, +-4.665771f, +-0.009420f, +-4.669603f, +-0.009384f, +-4.673450f, +-0.009349f, +-4.677203f, +-0.009313f, +-4.680971f, +-0.009277f, +-4.684862f, +-0.009242f, +-4.688658f, +-0.009206f, +-4.692475f, +-0.009172f, +-4.696189f, +-0.009137f, +-4.700029f, +-0.009101f, +-4.703883f, +-0.009067f, +-4.707647f, +-0.009032f, +-4.711531f, +-0.008997f, +-4.715317f, +-0.008963f, +-4.719124f, +-0.008929f, +-4.722939f, +-0.008894f, +-4.726775f, +-0.008860f, +-4.730619f, +-0.008826f, +-4.734485f, +-0.008793f, +-4.738243f, +-0.008758f, +-4.742138f, +-0.008725f, +-4.745925f, +-0.008691f, +-4.749851f, +-0.008657f, +-4.753667f, +-0.008624f, +-4.757506f, +-0.008591f, +-4.761358f, +-0.008558f, +-4.765219f, +-0.008525f, +-4.768983f, +-0.008492f, +-4.772880f, +-0.008460f, +-4.776672f, +-0.008426f, +-4.780593f, +-0.008394f, +-4.784415f, +-0.008362f, +-4.788251f, +-0.008330f, +-4.792102f, +-0.008297f, +-4.795969f, +-0.008265f, +-4.799850f, +-0.008233f, +-4.803746f, +-0.008202f, +-4.807533f, +-0.008169f, +-4.811460f, +-0.008138f, +-4.815277f, +-0.008106f, +-4.819234f, +-0.008074f, +-4.823080f, +-0.008043f, +-4.826942f, +-0.008012f, +-4.830818f, +-0.007981f, +-4.834710f, +-0.007951f, +-4.838489f, +-0.007919f, +-4.842410f, +-0.007888f, +-4.846347f, +-0.007858f, +-4.850178f, +-0.007827f, +-4.854146f, +-0.007796f, +-4.857999f, +-0.007766f, +-4.861867f, +-0.007736f, +-4.865758f, +-0.007706f, +-4.869656f, +-0.007675f, +-4.873569f, +-0.007646f, +-4.877373f, +-0.007616f, +-4.881317f, +-0.007586f, +-4.885284f, +-0.007556f, +-4.889125f, +-0.007527f, +-4.892988f, +-0.007497f, +-4.896994f, +-0.007468f, +-4.900888f, +-0.007439f, +-4.904789f, +-0.007409f, +-4.908714f, +-0.007380f, +-4.912646f, +-0.007352f, +-4.916463f, +-0.007323f, +-4.920425f, +-0.007295f, +-4.924273f, +-0.007265f, +-4.928274f, +-0.007237f, +-4.932144f, +-0.007209f, +-4.936036f, +-0.007180f, +-4.940085f, +-0.007151f, +-4.944009f, +-0.007123f, +-4.947940f, +-0.007096f, +-4.951751f, +-0.007068f, +-4.955720f, +-0.007040f, +-4.959706f, +-0.007013f, +-4.963562f, +-0.006984f, +-4.967579f, +-0.006957f, +-4.971466f, +-0.006929f, +-4.975507f, +-0.006902f, +-4.979425f, +-0.006875f, +-4.983358f, +-0.006847f, +-4.987307f, +-0.006820f, +-4.991272f, +-0.006793f, +-4.995252f, +-0.006767f, +-4.999098f, +-0.006740f, +-5.003110f, +-0.006713f, +-5.006995f, +-0.006686f, +-5.011039f, +-0.006660f, +-5.014946f, +-0.006634f, +-5.018869f, +-0.006607f, +-5.022961f, +-0.006581f, +-5.026915f, +-0.006554f, +-5.030885f, +-0.006528f, +-5.034880f, +-0.006503f, +-5.038725f, +-0.006477f, +-5.042743f, +-0.006451f, +-5.046785f, +-0.006426f, +-5.050677f, +-0.006399f, +-5.054743f, +-0.006374f, +-5.058675f, +-0.006349f, +-5.062613f, +-0.006324f, +-5.066567f, +-0.006299f, +-5.070546f, +-0.006274f, +-5.074531f, +-0.006248f, +-5.078542f, +-0.006223f, +-5.082560f, +-0.006198f, +-5.086603f, +-0.006174f, +-5.090488f, +-0.006149f, +-5.094564f, +-0.006125f, +-5.098480f, +-0.006100f, +-5.102589f, +-0.006075f, +-5.106537f, +-0.006051f, +-5.110510f, +-0.006027f, +-5.114500f, +-0.006002f, +-5.118665f, +-0.005979f, +-5.122517f, +-0.005955f, +-5.126555f, +-0.005931f, +-5.130599f, +-0.005906f, +-5.134669f, +-0.005883f, +-5.138584f, +-0.005859f, +-5.142687f, +-0.005836f, +-5.146623f, +-0.005812f, +-5.150759f, +-0.005789f, +-5.154738f, +-0.005766f, +-5.158732f, +-0.005742f, +-5.162742f, +-0.005719f, +-5.166768f, +-0.005696f, +-5.170800f, +-0.005673f, +-5.174859f, +-0.005650f, +-5.178934f, +-0.005627f, +-5.183026f, +-0.005605f, +-5.186953f, +-0.005582f, +-5.191078f, +-0.005559f, +-5.195038f, +-0.005536f, +-5.199196f, +-0.005514f, +-5.203188f, +-0.005492f, +-5.207196f, +-0.005470f, +-5.211220f, +-0.005448f, +-5.215260f, +-0.005426f, +-5.219316f, +-0.005404f, +-5.223400f, +-0.005381f, +-5.227490f, +-0.005359f, +-5.231596f, +-0.005338f, +-5.235529f, +-0.005316f, +-5.239669f, +-0.005294f, +-5.243826f, +-0.005273f, +-5.247819f, +-0.005252f, +-5.251816f, +-0.005230f, +-5.256024f, +-0.005209f, +-5.260054f, +-0.005187f, +-5.264113f, +-0.005166f, +-5.268176f, +-0.005145f, +-5.272256f, +-0.005124f, +-5.276364f, +-0.005103f, +-5.280478f, +-0.005083f, +-5.284420f, +-0.005062f, +-5.288567f, +-0.005041f, +-5.292731f, +-0.005021f, +-5.296722f, +-0.004999f, +-5.300920f, +-0.004979f, +-5.304944f, +-0.004959f, +-5.308973f, +-0.004939f, +-5.313029f, +-0.004918f, +-5.317297f, +-0.004898f, +-5.321387f, +-0.004878f, +-5.325482f, +-0.004858f, +-5.329606f, +-0.004839f, +-5.333525f, +-0.004819f, +-5.337683f, +-0.004799f, +-5.341846f, +-0.004778f, +-5.346038f, +-0.004759f, +-5.350035f, +-0.004739f, +-5.354249f, +-0.004720f, +-5.358279f, +-0.004701f, +-5.362325f, +-0.004681f, +-5.366591f, +-0.004662f, +-5.370671f, +-0.004643f, +-5.374767f, +-0.004624f, +-5.378881f, +-0.004605f, +-5.382998f, +-0.004586f, +-5.387145f, +-0.004566f, +-5.391310f, +-0.004547f, +-5.395492f, +-0.004529f, +-5.399468f, +-0.004510f, +-5.403684f, +-0.004491f, +-5.407905f, +-0.004473f, +-5.411930f, +-0.004454f, +-5.416200f, +-0.004436f, +-5.420258f, +-0.004418f, +-5.424334f, +-0.004400f, +-5.428426f, +-0.004381f, +-5.432766f, +-0.004362f, +-5.436893f, +-0.004344f, +-5.441037f, +-0.004326f, +-5.445198f, +-0.004308f, +-5.449376f, +-0.004291f, +-5.453336f, +-0.004273f, +-5.457548f, +-0.004255f, +-5.461779f, +-0.004237f, +-5.466027f, +-0.004220f, +-5.470053f, +-0.004202f, +-5.474337f, +-0.004185f, +-5.478396f, +-0.004167f, +-5.482716f, +-0.004150f, +-5.486824f, +-0.004133f, +-5.490935f, +-0.004115f, +-5.495063f, +-0.004098f, +-5.499208f, +-0.004081f, +-5.503370f, +-0.004064f, +-5.507564f, +-0.004047f, +-5.511761f, +-0.004030f, +-5.515975f, +-0.004013f, +-5.520208f, +-0.003996f, +-5.524459f, +-0.003980f, +-5.528487f, +-0.003963f, +-5.532773f, +-0.003946f, +-5.537077f, +-0.003930f, +-5.541157f, +-0.003913f, +-5.545498f, +-0.003897f, +-5.549597f, +-0.003881f, +-5.553728f, +-0.003864f, +-5.557861f, +-0.003847f, +-5.562275f, +-0.003831f, +-5.566459f, +-0.003815f, +-5.570646f, +-0.003799f, +-5.574865f, +-0.003783f, +-5.579086f, +-0.003767f, +-5.583342f, +-0.003752f, +-5.587328f, +-0.003736f, +-5.591619f, +-0.003720f, +-5.595912f, +-0.003704f, +-5.600240f, +-0.003689f, +-5.604294f, +-0.003673f, +-5.608659f, +-0.003658f, +-5.612748f, +-0.003642f, +-5.617149f, +-0.003627f, +-5.621273f, +-0.003612f, +-5.625431f, +-0.003596f, +-5.629606f, +-0.003580f, +-5.634066f, +-0.003565f, +-5.638278f, +-0.003550f, +-5.642507f, +-0.003535f, +-5.646737f, +-0.003520f, +-5.651003f, +-0.003505f, +-5.655286f, +-0.003491f, +-5.659280f, +-0.003476f, +-5.663600f, +-0.003461f, +-5.667938f, +-0.003446f, +-5.672277f, +-0.003432f, +-5.676357f, +-0.003417f, +-5.680751f, +-0.003403f, +-5.684866f, +-0.003388f, +-5.689280f, +-0.003374f, +-5.693430f, +-0.003360f, +-5.697598f, +-0.003345f, +-5.702086f, +-0.003331f, +-5.706290f, +-0.003316f, +-5.710512f, +-0.003302f, +-5.714751f, +-0.003288f, +-5.718990f, +-0.003274f, +-5.723266f, +-0.003260f, +-5.727560f, +-0.003246f, +-5.731873f, +-0.003232f, +-5.736204f, +-0.003218f, +-5.740554f, +-0.003204f, +-5.744923f, +-0.003191f, +-5.748993f, +-0.003177f, +-5.753399f, +-0.003164f, +-5.757504f, +-0.003150f, +-5.761948f, +-0.003137f, +-5.766088f, +-0.003123f, +-5.770570f, +-0.003110f, +-5.774746f, +-0.003096f, +-5.779268f, +-0.003083f, +-5.783480f, +-0.003070f, +-5.787711f, +-0.003057f, +-5.791959f, +-0.003044f, +-5.796226f, +-0.003031f, +-5.800511f, +-0.003018f, +-5.804814f, +-0.003005f, +-5.809136f, +-0.002991f, +-5.813477f, +-0.002978f, +-5.817856f, +-0.002965f, +-5.822235f, +-0.002952f, +-5.826633f, +-0.002940f, +-5.830705f, +-0.002927f, +-5.835141f, +-0.002914f, +-5.839596f, +-0.002902f, +-5.843742f, +-0.002889f, +-5.848236f, +-0.002877f, +-5.852397f, +-0.002864f, +-5.856930f, +-0.002852f, +-5.861128f, +-0.002840f, +-5.865365f, +-0.002827f, +-5.869957f, +-0.002815f, +-5.874210f, +-0.002803f, +-5.878502f, +-0.002791f, +-5.882792f, +-0.002779f, +-5.887100f, +-0.002767f, +-5.891448f, +-0.002755f, +-5.895793f, +-0.002743f, +-5.900158f, +-0.002731f, +-5.904563f, +-0.002719f, +-5.908966f, +-0.002707f, +-5.913389f, +-0.002696f, +-5.917477f, +-0.002684f, +-5.921937f, +-0.002672f, +-5.926417f, +-0.002661f, +-5.930559f, +-0.002649f, +-5.935078f, +-0.002636f, +-5.939641f, +-0.002625f, +-5.943815f, +-0.002614f, +-5.948029f, +-0.002602f, +-5.952628f, +-0.002591f, +-5.956880f, +-0.002579f, +-5.961520f, +-0.002568f, +-5.965787f, +-0.002557f, +-5.970095f, +-0.002546f, +-5.974422f, +-0.002535f, +-5.978744f, +-0.002524f, +-5.983108f, +-0.002513f, +-5.987468f, +-0.002502f, +-5.991871f, +-0.002491f, +-5.996269f, +-0.002480f, +-6.000711f, +-0.002469f, +-6.005149f, +-0.002458f, +-6.009630f, +-0.002447f, +-6.014107f, +-0.002437f, +-6.018213f, +-0.002426f, +-6.022754f, +-0.002415f, +-6.027290f, +-0.002405f, +-6.031450f, +-0.002394f, +-6.036052f, +-0.002384f, +-6.040223f, +-0.002373f, +-6.044865f, +-0.002363f, +-6.049099f, +-0.002352f, +-6.053757f, +-0.002342f, +-6.058029f, +-0.002332f, +-6.062320f, +-0.002321f, +-6.067040f, +-0.002311f, +-6.071369f, +-0.002301f, +-6.075717f, +-0.002291f, +-6.080084f, +-0.002281f, +-6.084470f, +-0.002271f, +-6.088850f, +-0.002260f, +-6.093723f, +-0.002251f, +-6.097719f, +-0.002240f, +-6.102184f, +-0.002231f, +-6.106641f, +-0.002220f, +-6.111146f, +-0.002210f, +-6.115671f, +-0.002200f, +-6.120216f, +-0.002190f, +-6.124755f, +-0.002181f, +-6.128877f, +-0.002171f, +-6.133483f, +-0.002161f, +-6.138110f, +-0.002152f, +-6.142288f, +-0.002142f, +-6.146956f, +-0.002133f, +-6.151171f, +-0.002123f, +-6.155881f, +-0.002114f, +-6.160133f, +-0.002104f, +-6.164858f, +-0.002095f, +-6.169149f, +-0.002086f, +-6.173458f, +-0.002076f, +-6.178275f, +-0.002067f, +-6.182624f, +-0.002058f, +-6.186992f, +-0.002049f, +-6.191379f, +-0.002040f, +-6.195785f, +-0.002031f, +-6.200211f, +-0.002022f, +-6.204657f, +-0.002012f, +-6.209627f, +-0.002003f, +-6.214114f, +-0.001995f, +-6.218114f, +-0.001986f, +-6.222640f, +-0.001977f, +-6.227187f, +-0.001968f, +-6.231754f, +-0.001959f, +-6.236343f, +-0.001950f, +-6.240953f, +-0.001942f, +-6.245061f, +-0.001933f, +-6.249711f, +-0.001924f, +-6.254383f, +-0.001916f, +-6.258547f, +-0.001907f, +-6.263261f, +-0.001898f, +-6.267996f, +-0.001890f, +-6.272249f, +-0.001881f, +-6.277028f, +-0.001873f, +-6.281288f, +-0.001865f, +-6.285566f, +-0.001856f, +-6.290408f, +-0.001848f, +-6.294726f, +-0.001839f, +-6.299613f, +-0.001831f, +-6.303971f, +-0.001823f, +-6.308380f, +-0.001815f, +-6.312775f, +-0.001807f, +-6.317191f, +-0.001798f, +-6.322189f, +-0.001790f, +-6.326646f, +-0.001782f, +-6.331157f, +-0.001774f, +-6.335654f, +-0.001766f, +-6.340172f, +-0.001758f, +-6.344710f, +-0.001750f, +-6.349268f, +-0.001741f, +-6.353882f, +-0.001733f, +-6.358483f, +-0.001727f, +-6.362518f, +-0.001718f, +-6.367193f, +-0.001710f, +-6.371856f, +-0.001702f, +-6.376541f, +-0.001694f, +-6.381247f, +-0.001687f, +-6.385410f, +-0.001679f, +-6.390159f, +-0.001671f, +-6.394930f, +-0.001664f, +-6.399115f, +-0.001656f, +-6.403965f, +-0.001649f, +-6.408187f, +-0.001641f, +-6.413046f, +-0.001634f, +-6.417344f, +-0.001626f, +-6.422247f, +-0.001619f, +-6.426547f, +-0.001612f, +-6.430904f, +-0.001604f, +-6.435874f, +-0.001597f, +-6.440271f, +-0.001590f, +-6.444650f, +-0.001582f, +-6.449689f, +-0.001575f, +-6.454148f, +-0.001568f, +-6.458588f, +-0.001561f, +-6.463087f, +-0.001554f, +-6.467567f, +-0.001547f, +-6.472068f, +-0.001539f, +-6.477286f, +-0.001532f, +-6.481831f, +-0.001525f, +-6.486435f, +-0.001518f, +-6.491022f, +-0.001511f, +-6.495630f, +-0.001504f, +-6.500298f, +-0.001498f, +-6.504312f, +-0.001491f, +-6.508981f, +-0.001484f, +-6.513673f, +-0.001477f, +-6.518426f, +-0.001470f, +-6.523162f, +-0.001464f, +-6.527269f, +-0.001457f, +-6.532047f, +-0.001450f, +-6.536889f, +-0.001443f, +-6.541714f, +-0.001437f, +-6.545897f, +-0.001430f, +-6.550765f, +-0.001424f, +-6.554987f, +-0.001417f, +-6.559900f, +-0.001410f, +-6.564879f, +-0.001404f, +-6.569161f, +-0.001398f, +-6.573418f, +-0.001391f, +-6.578466f, +-0.001385f, +-6.582763f, +-0.001378f, +-6.587858f, +-0.001372f, +-6.592196f, +-0.001365f, +-6.597339f, +-0.001359f, +-6.601762f, +-0.001353f, +-6.606161f, +-0.001347f, +-6.610624f, +-0.001340f, +-6.615819f, +-0.001334f, +-6.620325f, +-0.001328f, +-6.624851f, +-0.001322f, +-6.629353f, +-0.001316f, +-6.633920f, +-0.001310f, +-6.638509f, +-0.001304f, +-6.643073f, +-0.001297f, +-6.648485f, +-0.001291f, +-6.653095f, +-0.001285f, +-6.657773f, +-0.001279f, +-6.662472f, +-0.001274f, +-6.666397f, +-0.001268f, +-6.671091f, +-0.001262f, +-6.675854f, +-0.001256f, +-6.680639f, +-0.001250f, +-6.685400f, +-0.001244f, +-6.690231f, +-0.001238f, +-6.695086f, +-0.001233f, +-6.699094f, +-0.001227f, +-6.703992f, +-0.001221f, +-6.708914f, +-0.001215f, +-6.713812f, +-0.001210f, +-6.717945f, +-0.001204f, +-6.722936f, +-0.001198f, +-6.727953f, +-0.001193f, +-6.732145f, +-0.001187f, +-6.737158f, +-0.001182f, +-6.741388f, +-0.001176f, +-6.746499f, +-0.001171f, +-6.750769f, +-0.001165f, +-6.755877f, +-0.001160f, +-6.760187f, +-0.001154f, +-6.765395f, +-0.001149f, +-6.769747f, +-0.001143f, +-6.774952f, +-0.001138f, +-6.779346f, +-0.001133f, +-6.783759f, +-0.001127f, +-6.789091f, +-0.001122f, +-6.793548f, +-0.001117f, +-6.798024f, +-0.001112f, +-6.802521f, +-0.001106f, +-6.807900f, +-0.001101f, +-6.812442f, +-0.001096f, +-6.817004f, +-0.001091f, +-6.821587f, +-0.001086f, +-6.826191f, +-0.001081f, +-6.830816f, +-0.001075f, +-6.836350f, +-0.001070f, +-6.841023f, +-0.001065f, +-6.845718f, +-0.001060f, +-6.850434f, +-0.001055f, +-6.855173f, +-0.001050f, +-6.859935f, +-0.001045f, +-6.864719f, +-0.001040f, +-6.869469f, +-0.001035f, +-6.874300f, +-0.001031f, +-6.878169f, +-0.001026f, +-6.883042f, +-0.001021f, +-6.887939f, +-0.001016f, +-6.892859f, +-0.001011f, +-6.897804f, +-0.001005f, +-6.902774f, +-0.001002f, +-6.906755f, +-0.000996f, +-6.911770f, +-0.000991f, +-6.916809f, +-0.000986f, +-6.921874f, +-0.000982f, +-6.925933f, +-0.000977f, +-6.931045f, +-0.000972f, +-6.936183f, +-0.000968f, +-6.940300f, +-0.000963f, +-6.945486f, +-0.000959f, +-6.949641f, +-0.000954f, +-6.954876f, +-0.000949f, +-6.960075f, +-0.000945f, +-6.964355f, +-0.000940f, +-6.969604f, +-0.000936f, +-6.973925f, +-0.000931f, +-6.979225f, +-0.000927f, +-6.983588f, +-0.000923f, +-6.987905f, +-0.000918f, +-6.993345f, +-0.000914f, +-6.997704f, +-0.000909f, +-7.003198f, +-0.000905f, +-7.007601f, +-0.000901f, +-7.012023f, +-0.000896f, +-7.017596f, +-0.000892f, +-7.022063f, +-0.000888f, +-7.026550f, +-0.000884f, +-7.031057f, +-0.000879f, +-7.036737f, +-0.000875f, +-7.041291f, +-0.000871f, +-7.045866f, +-0.000867f, +-7.050461f, +-0.000863f, +-7.055078f, +-0.000858f, +-7.060896f, +-0.000854f, +-7.065561f, +-0.000850f, +-7.070249f, +-0.000846f, +-7.074958f, +-0.000842f, +-7.079760f, +-0.000838f, +-7.084514f, +-0.000834f, +-7.089291f, +-0.000830f, +-7.094091f, +-0.000826f, +-7.098914f, +-0.000822f, +-7.103761f, +-0.000818f, +-7.108631f, +-0.000814f, +-7.113525f, +-0.000810f, +-7.118443f, +-0.000806f, +-7.123459f, +-0.000802f, +-7.128426f, +-0.000798f, +-7.133418f, +-0.000794f, +-7.138435f, +-0.000791f, +-7.142196f, +-0.000787f, +-7.147257f, +-0.000783f, +-7.152344f, +-0.000779f, +-7.157534f, +-0.000775f, +-7.162674f, +-0.000772f, +-7.166527f, +-0.000768f, +-7.171713f, +-0.000764f, +-7.176927f, +-0.000760f, +-7.182167f, +-0.000757f, +-7.186175f, +-0.000753f, +-7.191465f, +-0.000749f, +-7.196782f, +-0.000746f, +-7.200769f, +-0.000742f, +-7.206137f, +-0.000739f, +-7.210242f, +-0.000735f, +-7.215661f, +-0.000731f, +-7.221109f, +-0.000728f, +-7.225194f, +-0.000724f, +-7.230695f, +-0.000721f, +-7.234902f, +-0.000717f, +-7.240457f, +-0.000714f, +-7.244622f, +-0.000710f, +-7.250231f, +-0.000707f, +-7.254521f, +-0.000703f, +-7.260186f, +-0.000700f, +-7.264435f, +-0.000696f, +-7.270156f, +-0.000693f, +-7.274447f, +-0.000690f, +-7.278843f, +-0.000686f, +-7.284648f, +-0.000683f, +-7.289002f, +-0.000680f, +-7.293375f, +-0.000676f, +-7.299353f, +-0.000673f, +-7.303771f, +-0.000670f, +-7.308209f, +-0.000666f, +-7.314187f, +-0.000663f, +-7.318762f, +-0.000660f, +-7.323267f, +-0.000657f, +-7.327793f, +-0.000653f, +-7.333890f, +-0.000650f, +-7.338556f, +-0.000647f, +-7.343151f, +-0.000644f, +-7.347768f, +-0.000641f, +-7.352499f, +-0.000637f, +-7.358749f, +-0.000634f, +-7.363439f, +-0.000631f, +-7.368245f, +-0.000628f, +-7.372979f, +-0.000625f, +-7.377736f, +-0.000622f, +-7.382612f, +-0.000619f, +-7.387415f, +-0.000616f, +-7.392241f, +-0.000613f, +-7.397188f, +-0.000610f, +-7.402062f, +-0.000607f, +-7.406959f, +-0.000604f, +-7.411980f, +-0.000601f, +-7.416926f, +-0.000598f, +-7.421897f, +-0.000595f, +-7.426994f, +-0.000592f, +-7.432015f, +-0.000589f, +-7.437062f, +-0.000586f, +-7.442236f, +-0.000583f, +-7.447335f, +-0.000580f, +-7.452460f, +-0.000577f, +-7.457715f, +-0.000574f, +-7.462894f, +-0.000572f, +-7.466327f, +-0.000569f, +-7.471655f, +-0.000566f, +-7.476906f, +-0.000563f, +-7.482186f, +-0.000560f, +-7.487599f, +-0.000558f, +-7.491118f, +-0.000555f, +-7.496581f, +-0.000552f, +-7.501965f, +-0.000549f, +-7.507379f, +-0.000547f, +-7.511077f, +-0.000544f, +-7.516540f, +-0.000541f, +-7.522143f, +-0.000538f, +-7.527668f, +-0.000536f, +-7.531331f, +-0.000533f, +-7.537018f, +-0.000530f, +-7.542625f, +-0.000528f, +-7.546456f, +-0.000525f, +-7.552117f, +-0.000522f, +-7.557809f, +-0.000520f, +-7.561699f, +-0.000517f, +-7.567447f, +-0.000515f, +-7.571374f, +-0.000512f, +-7.577178f, +-0.000510f, +-7.581144f, +-0.000507f, +-7.587005f, +-0.000504f, +-7.592901f, +-0.000502f, +-7.596930f, +-0.000499f, +-7.602884f, +-0.000497f, +-7.606954f, +-0.000494f, +-7.612968f, +-0.000492f, +-7.617079f, +-0.000489f, +-7.623155f, +-0.000487f, +-7.627186f, +-0.000485f, +-7.631355f, +-0.000482f, +-7.637519f, +-0.000480f, +-7.641732f, +-0.000477f, +-7.647961f, +-0.000475f, +-7.652218f, +-0.000472f, +-7.658512f, +-0.000470f, +-7.662815f, +-0.000468f, +-7.667009f, +-0.000465f, +-7.673525f, +-0.000463f, +-7.677764f, +-0.000461f, +-7.682151f, +-0.000458f, +-7.688637f, +-0.000456f, +-7.693071f, +-0.000454f, +-7.697394f, +-0.000451f, +-7.703980f, +-0.000449f, +-7.708484f, +-0.000447f, +-7.713007f, +-0.000445f, +-7.717418f, +-0.000442f, +-7.724137f, +-0.000440f, +-7.728732f, +-0.000438f, +-7.733349f, +-0.000436f, +-7.737850f, +-0.000434f, +-7.742509f, +-0.000431f, +-7.749400f, +-0.000429f, +-7.754113f, +-0.000427f, +-7.758709f, +-0.000425f, +-7.763466f, +-0.000423f, +-7.768105f, +-0.000420f, +-7.775317f, +-0.000418f, +-7.780011f, +-0.000416f, +-7.784871f, +-0.000414f, +-7.789611f, +-0.000412f, +-7.794518f, +-0.000410f, +-7.799304f, +-0.000408f, +-7.804259f, +-0.000406f, +-7.809091f, +-0.000404f, +-7.814095f, +-0.000402f, +-7.819124f, +-0.000400f, +-7.824029f, +-0.000398f, +-7.829108f, +-0.000396f, +-7.834063f, +-0.000393f, +-7.841769f, +-0.000391f, +-7.846786f, +-0.000389f, +-7.851983f, +-0.000387f, +-7.857052f, +-0.000385f, +-7.862303f, +-0.000384f, +-7.864938f, +-0.000382f, +-7.870074f, +-0.000380f, +-7.875393f, +-0.000378f, +-7.880583f, +-0.000376f, +-7.885958f, +-0.000374f, +-7.891204f, +-0.000372f, +-7.896637f, +-0.000370f, +-7.901938f, +-0.000368f, +-7.907430f, +-0.000366f, +-7.912952f, +-0.000364f, +-7.918341f, +-0.000362f, +-7.923924f, +-0.000361f, +-7.926562f, +-0.000359f, +-7.932192f, +-0.000357f, +-7.937853f, +-0.000355f, +-7.943378f, +-0.000353f, +-7.949103f, +-0.000351f, +-7.954691f, +-0.000350f, +-7.957582f, +-0.000348f, +-7.963389f, +-0.000346f, +-7.969057f, +-0.000344f, +-7.974932f, +-0.000342f, +-7.980666f, +-0.000341f, +-7.983633f, +-0.000339f, +-7.989594f, +-0.000337f, +-7.995414f, +-0.000335f, +-8.001445f, +-0.000334f, +-8.004296f, +-0.000332f, +-8.010382f, +-0.000330f, +-8.016505f, +-0.000329f, +-8.019399f, +-0.000327f, +-8.025578f, +-0.000325f, +-8.031611f, +-0.000324f, +-8.034734f, +-0.000322f, +-8.041008f, +-0.000320f, +-8.047135f, +-0.000319f, +-8.050307f, +-0.000317f, +-8.056680f, +-0.000315f, +-8.062904f, +-0.000314f, +-8.066126f, +-0.000312f, +-8.072601f, +-0.000310f, +-8.078926f, +-0.000309f, +-8.082200f, +-0.000307f, +-8.088586f, +-0.000306f, +-8.091892f, +-0.000304f, +-8.098537f, +-0.000302f, +-8.105028f, +-0.000301f, +-8.108389f, +-0.000299f, +-8.115144f, +-0.000298f, +-8.118339f, +-0.000296f, +-8.125162f, +-0.000295f, +-8.128592f, +-0.000293f, +-8.135282f, +-0.000292f, +-8.138746f, +-0.000290f, +-8.145710f, +-0.000289f, +-8.149005f, +-0.000287f, +-8.156041f, +-0.000286f, +-8.159578f, +-0.000284f, +-8.166480f, +-0.000283f, +-8.170054f, +-0.000281f, +-8.177240f, +-0.000280f, +-8.180640f, +-0.000278f, +-8.187904f, +-0.000277f, +-8.191555f, +-0.000275f, +-8.198682f, +-0.000274f, +-8.202373f, +-0.000272f, +-8.209797f, +-0.000271f, +-8.213309f, +-0.000270f, +-8.217055f, +-0.000268f, +-8.224589f, +-0.000267f, +-8.228154f, +-0.000265f, +-8.235772f, +-0.000264f, +-8.239603f, +-0.000262f, +-8.247082f, +-0.000261f, +-8.250957f, +-0.000260f, +-8.254846f, +-0.000258f, +-8.262440f, +-0.000257f, +-8.266375f, +-0.000256f, +-8.270325f, +-0.000254f, +-8.278273f, +-0.000253f, +-8.282035f, +-0.000252f, +-8.286048f, +-0.000250f, +-8.294122f, +-0.000249f, +-8.297944f, +-0.000248f, +-8.302022f, +-0.000246f, +-8.310226f, +-0.000245f, +-8.314354f, +-0.000244f, +-8.318255f, +-0.000243f, +-8.322416f, +-0.000241f, +-8.330790f, +-0.000240f, +-8.334755f, +-0.000239f, +-8.338986f, +-0.000237f, +-8.347501f, +-0.000236f, +-8.351786f, +-0.000235f, +-8.355835f, +-0.000234f, +-8.360156f, +-0.000232f, +-8.368854f, +-0.000231f, +-8.372973f, +-0.000230f, +-8.377369f, +-0.000229f, +-8.381784f, +-0.000228f, +-8.386219f, +-0.000226f, +-8.394883f, +-0.000225f, +-8.399377f, +-0.000224f, +-8.403890f, +-0.000223f, +-8.408424f, +-0.000222f, +-8.412710f, +-0.000220f, +-8.421880f, +-0.000219f, +-8.426496f, +-0.000218f, +-8.431134f, +-0.000217f, +-8.435519f, +-0.000216f, +-8.440199f, +-0.000215f, +-8.444901f, +-0.000214f, +-8.449625f, +-0.000212f, +-8.458860f, +-0.000211f, +-8.463650f, +-0.000210f, +-8.468464f, +-0.000209f, +-8.473301f, +-0.000208f, +-8.477875f, +-0.000207f, +-8.482758f, +-0.000206f, +-8.487665f, +-0.000205f, +-8.492596f, +-0.000203f, +-8.502238f, +-0.000202f, +-8.507242f, +-0.000201f, +-8.512271f, +-0.000200f, +-8.517325f, +-0.000199f, +-8.522106f, +-0.000198f, +-8.527210f, +-0.000197f, +-8.532341f, +-0.000196f, +-8.537498f, +-0.000195f, +-8.542376f, +-0.000194f, +-8.547585f, +-0.000193f, +-8.552821f, +-0.000192f, +-8.558085f, +-0.000191f, +-8.563377f, +-0.000190f, +-8.568383f, +-0.000189f, +-8.573730f, +-0.000188f, +-8.579106f, +-0.000187f, +-8.584510f, +-0.000186f, +-8.589624f, +-0.000185f, +-8.595085f, +-0.000184f, +-8.600577f, +-0.000183f, +-8.606099f, +-0.000182f, +-8.611652f, +-0.000181f, +-8.616907f, +-0.000180f, +-8.622520f, +-0.000179f, +-8.628165f, +-0.000178f, +-8.633842f, +-0.000177f, +-8.639215f, +-0.000176f, +-8.644955f, +-0.000175f, +-8.650729f, +-0.000174f, +-8.656536f, +-0.000173f, +-8.662377f, +-0.000172f, +-8.667906f, +-0.000171f, +-8.673814f, +-0.000170f, +-8.679757f, +-0.000169f, +-8.685735f, +-0.000169f, +-8.685735f, +-0.000168f, +-8.691395f, +-0.000167f, +-8.697444f, +-0.000166f, +-8.703529f, +-0.000165f, +-8.709652f, +-0.000164f, +-8.715813f, +-0.000163f, +-8.721646f, +-0.000162f, +-8.727881f, +-0.000161f, +-8.734155f, +-0.000160f, +-8.740469f, +-0.000160f, +-8.740469f, +-0.000159f, +-8.746448f, +-0.000158f, +-8.752840f, +-0.000157f, +-8.759273f, +-0.000156f, +-8.765748f, +-0.000155f, +-8.772266f, +-0.000154f, +-8.778438f, +-0.000154f, +-8.778438f, +-0.000153f, +-8.785039f, +-0.000152f, +-8.791684f, +-0.000151f, +-8.798373f, +-0.000150f, +-8.804709f, +-0.000150f, +-8.804709f, +-0.000149f, +-8.811486f, +-0.000148f, +-8.818310f, +-0.000147f, +-8.825180f, +-0.000146f, +-8.832097f, +-0.000145f, +-8.838652f, +-0.000145f, +-8.838652f, +-0.000144f, +-8.845664f, +-0.000143f, +-8.852725f, +-0.000142f, +-8.859837f, +-0.000142f, +-8.859837f, +-0.000141f, +-8.866576f, +-0.000140f, +-8.873787f, +-0.000139f, +-8.881051f, +-0.000138f, +-8.888367f, +-0.000138f, +-8.888367f, +-0.000137f, +-8.895738f, +-0.000136f, +-8.902725f, +-0.000135f, +-8.910202f, +-0.000135f, +-8.910202f, +-0.000134f, +-8.917736f, +-0.000133f, +-8.925327f, +-0.000133f, +-8.925327f, +-0.000132f, +-8.932525f, +-0.000131f, +-8.940229f, +-0.000130f, +-8.947994f, +-0.000130f, +-8.947994f, +-0.000129f, +-8.955819f, +-0.000128f, +-8.963706f, +-0.000128f, +-8.963706f, +-0.000127f, +-8.971186f, +-0.000126f, +-8.979195f, +-0.000125f, +-8.987269f, +-0.000125f, +-8.987269f, +-0.000124f, +-8.995409f, +-0.000123f, +-9.003131f, +-0.000123f, +-9.003131f, +-0.000122f, +-9.011402f, +-0.000121f, +-9.019741f, +-0.000121f, +-9.019741f, +-0.000120f, +-9.028151f, +-0.000119f, +-9.036632f, +-0.000119f, +-9.036632f, +-0.000118f, +-9.044680f, +-0.000117f, +-9.053303f, +-0.000117f, +-9.053303f, +-0.000116f, +-9.062001f, +-0.000115f, +-9.070775f, +-0.000115f, +-9.070775f, +-0.000114f, +-9.079104f, +-0.000114f, +-9.079104f, +-0.000113f, +-9.088031f, +-0.000112f, +-9.097037f, +-0.000112f, +-9.097037f, +-0.000111f, +-9.106126f, +-0.000110f, +-9.115298f, +-0.000110f, +-9.115298f, +-0.000109f, +-9.124008f, +-0.000109f, +-9.124008f, +-0.000108f, +-9.133346f, +-0.000107f, +-9.142772f, +-0.000107f, +-9.142772f, +-0.000106f, +-9.152288f, +-0.000106f, +-9.152288f, +-0.000105f, +-9.161328f, +-0.000104f, +-9.171022f, +-0.000104f, +-9.171022f, +-0.000103f, +-9.180812f, +-0.000103f, +-9.180812f, +-0.000102f, +-9.190699f, +-0.000102f, +-9.190699f, +-0.000101f, +-9.200684f, +-0.000100f, +-9.210174f, +-0.000100f, +-9.210174f, +-0.000099f, +-9.220357f, +-0.000099f, +-9.220357f, +-0.000098f, +-9.230645f, +-0.000098f, +-9.230645f, +-0.000097f, +-9.241039f, +-0.000097f, +-9.241039f, +-0.000096f, +-9.250922f, +-0.000095f, +-9.261530f, +-0.000095f, +-9.261530f, +-0.000094f, +-9.272253f, +-0.000094f, +-9.272253f, +-0.000093f, +-9.283091f, +-0.000093f, +-9.283091f, +-0.000092f, +-9.293401f, +-0.000092f, +-9.293401f, +-0.000091f, +-9.304472f, +-0.000091f, +-9.304472f, +-0.000090f, +-9.315667f, +-0.000090f, +-9.315667f, +-0.000089f, +-9.326990f, +-0.000089f, +-9.326990f, +-0.000088f, +-9.338441f, +-0.000088f, +-9.338441f, +-0.000087f, +-9.349341f, +-0.000087f, +-9.349341f, +-0.000086f, +-9.361053f, +-0.000086f, +-9.361053f, +-0.000085f, +-9.372904f, +-0.000085f, +-9.372904f, +-0.000084f, +-9.384897f, +-0.000084f, +-9.384897f, +-0.000083f, +-9.396317f, +-0.000083f, +-9.396317f, +-0.000082f, +-9.408596f, +-0.000082f, +-9.408596f, +-0.000082f, +-9.408596f, +-0.000081f, +-9.421028f, +-0.000081f, +-9.421028f, +-0.000080f, +-9.433616f, +-0.000080f, +-9.433616f, +-0.000079f, +-9.446365f, +-0.000079f, +-9.446365f, +-0.000078f, +-9.458514f, +-0.000078f, +-9.458514f, +-0.000077f, +-9.471586f, +-0.000077f, +-9.471586f, +-0.000077f, +-9.471586f, +-0.000076f, +-9.484831f, +-0.000076f, +-9.484831f, +-0.000075f, +-9.498254f, +-0.000075f, +-9.498254f, +-0.000074f, +-9.511054f, +-0.000074f, +-9.511054f, +-0.000074f, +-9.511054f, +-0.000073f, +-9.524836f, +-0.000073f, +-9.524836f, +-0.000072f, +-9.538811f, +-0.000072f, +-9.538811f, +-0.000072f, +-9.538811f, +-0.000071f, +-9.552984f, +-0.000071f, +-9.552984f, +-0.000070f, +-9.567360f, +-0.000070f, +-9.567360f, +-0.000070f, +-9.567360f, +-0.000069f, +-9.581083f, +-0.000069f, +-9.581083f, +-0.000068f, +-9.595872f, +-0.000068f, +-9.595872f, +-0.000068f, +-9.595872f, +-0.000067f, +-9.610883f, +-0.000067f, +-9.610883f, +-0.000066f, +-9.626123f, +-0.000066f, +-9.626123f, +-0.000066f, +-9.626123f, +-0.000065f, +-9.640682f, +-0.000065f, +-9.640682f, +-0.000065f, +-9.640682f, +-0.000064f, +-9.656387f, +-0.000064f, +-9.656387f, +-0.000063f, +-9.672342f, +-0.000063f, +-9.672342f, +-0.000063f, +-9.672342f, +-0.000062f, +-9.688556f, +-0.000062f, +-9.688556f, +-0.000062f, +-9.688556f, +-0.000061f, +-9.705038f, +-0.000061f, +-9.705038f, +-0.000061f, +-9.705038f, +-0.000060f, +-9.720801f, +-0.000060f, +-9.720801f, +-0.000060f, +-9.720801f, +-0.000059f, +-9.737827f, +-0.000059f, +-9.737827f, +-0.000059f, +-9.737827f, +-0.000058f, +-9.755148f, +-0.000058f, +-9.755148f, +-0.000057f, +-9.772774f, +-0.000057f, +-9.772774f, +-0.000057f, +-9.772774f, +-0.000057f, +-9.772774f, +-0.000056f, +-9.789652f, +-0.000056f, +-9.789652f, +-0.000056f, +-9.789652f, +-0.000055f, +-9.807903f, +-0.000055f, +-9.807903f, +-0.000055f, +-9.807903f, +-0.000054f, +-9.826493f, +-0.000054f, +-9.826493f, +-0.000054f, +-9.826493f, +-0.000053f, +-9.845435f, +-0.000053f, +-9.845435f, +-0.000053f, +-9.845435f, +-0.000052f, +-9.864743f, +-0.000052f, +-9.864743f, +-0.000052f, +-9.864743f, +-0.000051f, +-9.883262f, +-0.000051f, +-9.883262f, +-0.000051f, +-9.883262f, +-0.000051f, +-9.883262f, +-0.000050f, +-9.903322f, +-0.000050f, +-9.903322f, +-0.000050f, +-9.903322f, +-0.000049f, +-9.923792f, +-0.000049f, +-9.923792f, +-0.000049f, +-9.923792f, +-0.000049f, +-9.923792f, +-0.000048f, +-9.944690f, +-0.000048f, +-9.944690f, +-0.000048f, +-9.944690f, +-0.000047f, +-9.964766f, +-0.000047f, +-9.964766f, +-0.000047f, +-9.964766f, +-0.000047f, +-9.964766f, +-0.000046f, +-9.986548f, +-0.000046f, +-9.986548f, +-0.000046f, +-9.986548f, +-0.000046f, +-9.986548f, +-0.000045f, +-10.008815f, +-0.000045f, +-10.008815f, +-0.000045f, +-10.008815f, +-0.000044f, +-10.031589f, +-0.000044f, +-10.031589f, +-0.000044f, +-10.031589f, +-0.000044f, +-10.031589f, +-0.000043f, +-10.054893f, +-0.000043f, +-10.054893f, +-0.000043f, +-10.054893f, +-0.000043f, +-10.054893f, +-0.000042f, +-10.077335f, +-0.000042f, +-10.077335f, +-0.000042f, +-10.077335f, +-0.000042f, +-10.077335f, +-0.000041f, +-10.101743f, +-0.000041f, +-10.101743f, +-0.000041f, +-10.101743f, +-0.000041f, +-10.101743f, +-0.000041f, +-10.101743f, +-0.000040f, +-10.126763f, +-0.000040f, +-10.126763f, +-0.000040f, +-10.126763f, +-0.000040f, +-10.126763f, +-0.000039f, +-10.152425f, +-0.000039f, +-10.152425f, +-0.000039f, +-10.152425f, +-0.000039f, +-10.152425f, +-0.000038f, +-10.177194f, +-0.000038f, +-10.177194f, +-0.000038f, +-10.177194f, +-0.000038f, +-10.177194f, +-0.000038f, +-10.177194f, +-0.000037f, +-10.204201f, +-0.000037f, +-10.204201f, +-0.000037f, +-10.204201f, +-0.000037f, +-10.204201f, +-0.000036f, +-10.231958f, +-0.000036f, +-10.231958f, +-0.000036f, +-10.231958f, +-0.000036f, +-10.231958f, +-0.000036f, +-10.231958f, +-0.000035f, +-10.260508f, +-0.000035f, +-10.260508f, +-0.000035f, +-10.260508f, +-0.000035f, +-10.260508f, +-0.000035f, +-10.260508f, +-0.000034f, +-10.289896f, +-0.000034f, +-10.289896f, +-0.000034f, +-10.289896f, +-0.000034f, +-10.289896f, +-0.000033f, +-10.318368f, +-0.000033f, +-10.318368f, +-0.000033f, +-10.318368f, +-0.000033f, +-10.318368f, +-0.000033f, +-10.318368f, +-0.000033f, +-10.318368f, +-0.000032f, +-10.349534f, +-0.000032f, +-10.349534f, +-0.000032f, +-10.349534f, +-0.000032f, +-10.349534f, +-0.000032f, +-10.349534f, +-0.000031f, +-10.381704f, +-0.000031f, +-10.381704f, +-0.000031f, +-10.381704f, +-0.000031f, +-10.381704f, +-0.000031f, +-10.381704f, +-0.000030f, +-10.414942f, +-0.000030f, +-10.414942f, +-0.000030f, +-10.414942f, +-0.000030f, +-10.414942f, +-0.000030f, +-10.414942f, +-0.000030f, +-10.414942f, +-0.000029f, +-10.447268f, +-0.000029f, +-10.447268f, +-0.000029f, +-10.447268f, +-0.000029f, +-10.447268f, +-0.000029f, +-10.447268f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000028f, +-10.482800f, +-0.000027f, +-10.519640f, +-0.000027f, +-10.519640f, +-0.000027f, +-10.519640f, +-0.000027f, +-10.519640f, +-0.000027f, +-10.519640f, +-0.000027f, +-10.519640f, +-0.000026f, +-10.557890f, +-0.000026f, +-10.557890f, +-0.000026f, +-10.557890f, +-0.000026f, +-10.557890f, +-0.000026f, +-10.557890f, +-0.000026f, +-10.557890f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000025f, +-10.597661f, +-0.000024f, +-10.636596f, +-0.000024f, +-10.636596f, +-0.000024f, +-10.636596f, +-0.000024f, +-10.636596f, +-0.000024f, +-10.636596f, +-0.000024f, +-10.636596f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000023f, +-10.679695f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000022f, +-10.724736f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000021f, +-10.771901f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000020f, +-10.818421f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000019f, +-10.870341f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000018f, +-10.925105f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000017f, +-10.983043f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000016f, +-11.044545f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000015f, +-11.106103f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000014f, +-11.175947f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000013f, +-11.251037f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000012f, +-11.332227f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000011f, +-11.415177f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000010f, +-11.511568f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000009f, +-11.618252f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000008f, +-11.737693f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000007f, +-11.873358f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000006f, +-12.020412f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000005f, +-12.204716f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000004f, +-12.430840f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000003f, +-12.723509f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000002f, +-13.109172f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.802319f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f, +-0.000001f, +-13.815511f diff --git a/rce/rcecalib/dataproc/fit/logx_ext_fastint.dat b/rce/rcecalib/dataproc/fit/logx_ext_fastint.dat new file mode 100644 index 0000000000000000000000000000000000000000..370ec323c12647176f8c36455abf80c671a937db --- /dev/null +++ b/rce/rcecalib/dataproc/fit/logx_ext_fastint.dat @@ -0,0 +1,16382 @@ +-159447, +0, +-159378, +0, +-159309, +0, +-159240, +0, +-159171, +0, +-159102, +0, +-159033, +0, +-158964, +0, +-158895, +0, +-158826, +0, +-158758, +0, +-158689, +0, +-158620, +0, +-158551, +0, +-158482, +0, +-158414, +0, +-158345, +0, +-158276, +0, +-158208, +0, +-158139, +0, +-158070, +0, +-158002, +0, +-157933, +0, +-157864, +0, +-157796, +0, +-157727, +0, +-157659, +0, +-157590, +0, +-157522, +0, +-157453, +0, +-157385, +0, +-157316, +0, +-157248, +0, +-157179, +0, +-157111, +0, +-157042, +0, +-156974, +0, +-156905, +0, +-156837, +0, +-156769, +0, +-156700, +0, +-156632, +0, +-156564, +0, +-156495, +0, +-156427, +0, +-156359, +0, +-156291, +0, +-156222, +0, +-156154, +0, +-156086, +0, +-156018, +0, +-155950, +0, +-155882, +0, +-155813, +0, +-155745, +0, +-155677, +0, +-155609, +0, +-155541, +0, +-155473, +0, +-155405, +0, +-155337, +0, +-155269, +0, +-155201, +0, +-155133, +0, +-155065, +0, +-154997, +0, +-154929, +0, +-154861, +0, +-154793, +0, +-154725, +0, +-154658, +0, +-154590, +0, +-154522, +0, +-154454, +0, +-154386, +0, +-154319, +0, +-154251, +0, +-154183, +0, +-154115, +0, +-154048, +0, +-153980, +0, +-153912, +0, +-153844, +0, +-153777, +0, +-153709, +0, +-153642, +0, +-153574, +0, +-153506, +0, +-153439, +0, +-153371, +0, +-153304, +0, +-153236, +0, +-153169, +0, +-153101, +0, +-153034, +0, +-152966, +0, +-152899, +0, +-152831, +0, +-152764, +0, +-152696, +0, +-152629, +0, +-152562, +0, +-152494, +0, +-152427, +0, +-152360, +0, +-152292, +0, +-152225, +0, +-152158, +0, +-152091, +0, +-152023, +0, +-151956, +0, +-151889, +0, +-151822, +0, +-151755, +0, +-151687, +0, +-151620, +0, +-151553, +0, +-151486, +0, +-151419, +0, +-151352, +0, +-151285, +0, +-151218, +0, +-151151, +0, +-151084, +0, +-151017, +0, +-150950, +0, +-150883, +0, +-150816, +0, +-150749, +0, +-150682, +0, +-150615, +0, +-150548, +0, +-150481, +0, +-150414, +0, +-150348, +0, +-150281, +0, +-150214, +0, +-150147, +0, +-150080, +0, +-150014, +0, +-149947, +0, +-149880, +0, +-149813, +0, +-149747, +0, +-149680, +0, +-149613, +0, +-149547, +0, +-149480, +0, +-149413, +0, +-149347, +0, +-149280, +0, +-149214, +0, +-149147, +0, +-149081, +0, +-149014, +0, +-148948, +0, +-148881, +0, +-148815, +0, +-148748, +0, +-148682, +0, +-148615, +0, +-148549, +0, +-148482, +0, +-148416, +0, +-148350, +0, +-148283, +0, +-148217, +0, +-148151, +0, +-148084, +0, +-148018, +0, +-147952, +0, +-147886, +0, +-147819, +0, +-147753, +0, +-147687, +0, +-147621, +0, +-147555, +0, +-147488, +0, +-147422, +0, +-147356, +0, +-147290, +0, +-147224, +0, +-147158, +0, +-147092, +0, +-147026, +0, +-146960, +0, +-146894, +0, +-146828, +0, +-146762, +0, +-146696, +0, +-146630, +0, +-146564, +0, +-146498, +0, +-146432, +0, +-146366, +0, +-146300, +0, +-146234, +0, +-146169, +0, +-146103, +0, +-146037, +0, +-145971, +0, +-145905, +0, +-145840, +0, +-145774, +0, +-145708, +0, +-145642, +0, +-145577, +0, +-145511, +0, +-145445, +0, +-145380, +0, +-145314, +0, +-145248, +0, +-145183, +0, +-145117, +0, +-145052, +0, +-144986, +0, +-144921, +0, +-144855, +0, +-144790, +0, +-144724, +0, +-144659, +0, +-144593, +0, +-144528, +0, +-144462, +0, +-144397, +0, +-144332, +0, +-144266, +0, +-144201, +0, +-144135, +0, +-144070, +0, +-144005, +0, +-143940, +0, +-143874, +0, +-143809, +0, +-143744, +0, +-143678, +0, +-143613, +0, +-143548, +0, +-143483, +0, +-143418, +0, +-143353, +0, +-143287, +0, +-143222, +0, +-143157, +0, +-143092, +0, +-143027, +0, +-142962, +0, +-142897, +0, +-142832, +0, +-142767, +0, +-142702, +0, +-142637, +0, +-142572, +0, +-142507, +0, +-142442, +0, +-142377, +0, +-142312, +0, +-142247, +0, +-142183, +0, +-142118, +0, +-142053, +0, +-141988, +0, +-141923, +0, +-141858, +0, +-141794, +0, +-141729, +0, +-141664, +0, +-141599, +0, +-141535, +0, +-141470, +0, +-141405, +0, +-141341, +0, +-141276, +0, +-141211, +0, +-141147, +0, +-141082, +0, +-141018, +0, +-140953, +0, +-140889, +0, +-140824, +0, +-140759, +0, +-140695, +0, +-140630, +0, +-140566, +0, +-140502, +0, +-140437, +0, +-140373, +0, +-140308, +0, +-140244, +0, +-140180, +0, +-140115, +0, +-140051, +0, +-139986, +0, +-139922, +0, +-139858, +0, +-139794, +0, +-139729, +0, +-139665, +0, +-139601, +0, +-139537, +0, +-139472, +0, +-139408, +0, +-139344, +0, +-139280, +0, +-139216, +0, +-139152, +0, +-139088, +0, +-139024, +0, +-138959, +0, +-138895, +0, +-138831, +0, +-138767, +0, +-138703, +0, +-138639, +0, +-138575, +0, +-138511, +0, +-138447, +0, +-138384, +0, +-138320, +0, +-138256, +0, +-138192, +0, +-138128, +0, +-138064, +0, +-138000, +0, +-137936, +0, +-137873, +0, +-137809, +0, +-137745, +0, +-137681, +0, +-137618, +0, +-137554, +0, +-137490, +0, +-137426, +0, +-137363, +0, +-137299, +0, +-137236, +0, +-137172, +0, +-137108, +0, +-137045, +0, +-136981, +0, +-136918, +0, +-136854, +0, +-136790, +0, +-136727, +0, +-136663, +0, +-136600, +0, +-136536, +0, +-136473, +0, +-136410, +0, +-136346, +0, +-136283, +0, +-136219, +0, +-136156, +0, +-136093, +0, +-136029, +0, +-135966, +0, +-135903, +0, +-135839, +0, +-135776, +0, +-135713, +0, +-135650, +0, +-135586, +0, +-135523, +0, +-135460, +0, +-135397, +0, +-135334, +0, +-135270, +0, +-135207, +0, +-135144, +0, +-135081, +0, +-135018, +0, +-134955, +0, +-134892, +0, +-134829, +0, +-134766, +0, +-134703, +0, +-134640, +0, +-134577, +0, +-134514, +0, +-134451, +0, +-134388, +0, +-134325, +0, +-134262, +0, +-134199, +0, +-134137, +0, +-134074, +0, +-134011, +0, +-133948, +0, +-133885, +0, +-133822, +0, +-133760, +0, +-133697, +0, +-133634, +0, +-133571, +0, +-133509, +0, +-133446, +0, +-133383, +0, +-133321, +0, +-133258, +0, +-133195, +0, +-133133, +0, +-133070, +0, +-133008, +0, +-132945, +0, +-132883, +0, +-132820, +0, +-132758, +0, +-132695, +0, +-132633, +0, +-132570, +0, +-132508, +0, +-132445, +0, +-132383, +0, +-132320, +0, +-132258, +0, +-132196, +0, +-132133, +0, +-132071, +0, +-132009, +0, +-131946, +0, +-131884, +0, +-131822, +0, +-131759, +0, +-131697, +0, +-131635, +0, +-131573, +0, +-131511, +0, +-131448, +0, +-131386, +0, +-131324, +0, +-131262, +0, +-131200, +0, +-131138, +0, +-131076, +0, +-131014, +0, +-130952, +0, +-130889, +0, +-130827, +0, +-130765, +0, +-130703, +0, +-130642, +0, +-130580, +0, +-130518, +0, +-130456, +0, +-130394, +0, +-130332, +0, +-130270, +0, +-130208, +0, +-130146, +0, +-130084, +0, +-130023, +0, +-129961, +0, +-129899, +0, +-129837, +0, +-129776, +0, +-129714, +0, +-129652, +0, +-129590, +0, +-129529, +0, +-129467, +0, +-129405, +0, +-129344, +0, +-129282, +0, +-129220, +0, +-129159, +0, +-129097, +0, +-129036, +0, +-128974, +0, +-128913, +0, +-128851, +0, +-128790, +0, +-128728, +0, +-128667, +0, +-128605, +0, +-128544, +0, +-128482, +0, +-128421, +0, +-128360, +0, +-128298, +0, +-128237, +0, +-128176, +0, +-128114, +0, +-128053, +0, +-127992, +0, +-127930, +0, +-127869, +0, +-127808, +0, +-127747, +0, +-127685, +0, +-127624, +0, +-127563, +0, +-127502, +0, +-127441, +0, +-127380, +0, +-127318, +0, +-127257, +0, +-127196, +0, +-127135, +0, +-127074, +0, +-127013, +0, +-126952, +0, +-126891, +0, +-126830, +0, +-126769, +0, +-126708, +0, +-126647, +0, +-126586, +0, +-126525, +0, +-126465, +0, +-126404, +0, +-126343, +0, +-126282, +0, +-126221, +0, +-126160, +0, +-126099, +0, +-126039, +0, +-125978, +0, +-125917, +0, +-125856, +0, +-125796, +0, +-125735, +0, +-125674, +0, +-125614, +0, +-125553, +0, +-125492, +0, +-125432, +0, +-125371, +0, +-125311, +0, +-125250, +0, +-125189, +0, +-125129, +0, +-125068, +0, +-125008, +0, +-124947, +0, +-124887, +0, +-124826, +0, +-124766, +0, +-124705, +0, +-124645, +0, +-124585, +0, +-124524, +0, +-124464, +0, +-124404, +0, +-124343, +0, +-124283, +0, +-124223, +0, +-124162, +0, +-124102, +0, +-124042, +0, +-123981, +0, +-123921, +0, +-123861, +0, +-123801, +0, +-123741, +0, +-123680, +0, +-123620, +0, +-123560, +0, +-123500, +0, +-123440, +0, +-123380, +0, +-123320, +0, +-123260, +0, +-123200, +0, +-123140, +0, +-123080, +0, +-123020, +0, +-122960, +0, +-122900, +0, +-122840, +0, +-122780, +0, +-122720, +0, +-122660, +0, +-122600, +0, +-122540, +0, +-122480, +0, +-122421, +0, +-122361, +0, +-122301, +0, +-122241, +0, +-122181, +0, +-122122, +0, +-122062, +0, +-122002, +0, +-121943, +0, +-121883, +0, +-121823, +0, +-121764, +0, +-121704, +0, +-121644, +0, +-121585, +0, +-121525, +0, +-121465, +0, +-121406, +0, +-121346, +0, +-121287, +0, +-121227, +0, +-121168, +0, +-121108, +0, +-121049, +0, +-120989, +0, +-120930, +0, +-120871, +0, +-120811, +0, +-120752, +0, +-120692, +0, +-120633, +0, +-120574, +0, +-120514, +0, +-120455, +0, +-120396, +0, +-120336, +0, +-120277, +0, +-120218, +0, +-120159, +0, +-120100, +0, +-120040, +0, +-119981, +0, +-119922, +0, +-119863, +0, +-119804, +0, +-119745, +0, +-119685, +0, +-119626, +0, +-119567, +0, +-119508, +0, +-119449, +0, +-119390, +0, +-119331, +0, +-119272, +0, +-119213, +0, +-119154, +0, +-119095, +0, +-119036, +0, +-118977, +0, +-118919, +0, +-118860, +0, +-118801, +0, +-118742, +0, +-118683, +0, +-118624, +0, +-118566, +0, +-118507, +0, +-118448, +0, +-118389, +0, +-118330, +0, +-118272, +0, +-118213, +0, +-118154, +0, +-118096, +0, +-118037, +0, +-117978, +0, +-117920, +0, +-117861, +0, +-117803, +0, +-117744, +0, +-117685, +0, +-117627, +0, +-117568, +0, +-117510, +0, +-117451, +0, +-117393, +0, +-117334, +0, +-117276, +0, +-117217, +0, +-117159, +0, +-117101, +0, +-117042, +0, +-116984, +0, +-116925, +0, +-116867, +0, +-116809, +0, +-116750, +0, +-116692, +0, +-116634, +0, +-116576, +0, +-116517, +0, +-116459, +0, +-116401, +0, +-116343, +0, +-116285, +0, +-116226, +0, +-116168, +0, +-116110, +0, +-116052, +0, +-115994, +0, +-115936, +0, +-115878, +0, +-115820, +0, +-115762, +0, +-115704, +0, +-115646, +0, +-115588, +0, +-115530, +0, +-115472, +0, +-115414, +0, +-115356, +0, +-115298, +0, +-115240, +0, +-115182, +0, +-115124, +0, +-115066, +0, +-115008, +0, +-114951, +0, +-114893, +0, +-114835, +0, +-114777, +0, +-114719, +0, +-114662, +0, +-114604, +0, +-114546, +0, +-114489, +0, +-114431, +0, +-114373, +0, +-114316, +0, +-114258, +0, +-114200, +0, +-114143, +0, +-114085, +0, +-114028, +0, +-113970, +0, +-113912, +0, +-113855, +0, +-113797, +0, +-113740, +0, +-113682, +0, +-113625, +0, +-113568, +0, +-113510, +0, +-113453, +0, +-113395, +0, +-113338, +0, +-113281, +0, +-113223, +0, +-113166, +0, +-113109, +0, +-113051, +0, +-112994, +0, +-112937, +0, +-112880, +0, +-112822, +0, +-112765, +0, +-112708, +0, +-112651, +0, +-112593, +0, +-112536, +0, +-112479, +0, +-112422, +0, +-112365, +0, +-112308, +0, +-112251, +0, +-112194, +0, +-112137, +0, +-112080, +0, +-112023, +0, +-111966, +0, +-111909, +0, +-111852, +0, +-111795, +0, +-111738, +0, +-111681, +0, +-111624, +0, +-111567, +0, +-111510, +0, +-111453, +0, +-111396, +0, +-111340, +0, +-111283, +0, +-111226, +0, +-111169, +0, +-111112, +0, +-111056, +0, +-110999, +0, +-110942, +0, +-110886, +0, +-110829, +0, +-110772, +0, +-110716, +0, +-110659, +0, +-110602, +0, +-110546, +0, +-110489, +0, +-110433, +0, +-110376, +0, +-110319, +0, +-110263, +0, +-110206, +0, +-110150, +0, +-110093, +0, +-110037, +0, +-109981, +0, +-109924, +0, +-109868, +0, +-109811, +0, +-109755, +0, +-109699, +0, +-109642, +0, +-109586, +0, +-109529, +0, +-109473, +0, +-109417, +0, +-109361, +0, +-109304, +0, +-109248, +0, +-109192, +0, +-109136, +0, +-109079, +0, +-109023, +0, +-108967, +0, +-108911, +0, +-108855, +0, +-108799, +0, +-108743, +0, +-108687, +0, +-108630, +0, +-108574, +0, +-108518, +0, +-108462, +0, +-108406, +0, +-108350, +0, +-108294, +0, +-108238, +0, +-108182, +0, +-108127, +0, +-108071, +0, +-108015, +0, +-107959, +0, +-107903, +0, +-107847, +0, +-107791, +0, +-107736, +0, +-107680, +0, +-107624, +0, +-107568, +0, +-107512, +0, +-107457, +0, +-107401, +0, +-107345, +0, +-107290, +0, +-107234, +0, +-107178, +0, +-107123, +0, +-107067, +0, +-107011, +0, +-106956, +0, +-106900, +0, +-106845, +0, +-106789, +0, +-106734, +0, +-106678, +0, +-106622, +0, +-106567, +0, +-106512, +0, +-106456, +0, +-106401, +0, +-106345, +0, +-106290, +0, +-106234, +0, +-106179, +0, +-106124, +0, +-106068, +0, +-106013, +0, +-105958, +0, +-105902, +0, +-105847, +0, +-105792, +0, +-105737, +0, +-105681, +0, +-105626, +0, +-105571, +0, +-105516, +0, +-105461, +0, +-105405, +0, +-105350, +0, +-105295, +0, +-105240, +0, +-105185, +0, +-105130, +0, +-105075, +0, +-105020, +0, +-104965, +0, +-104910, +0, +-104855, +0, +-104800, +0, +-104745, +0, +-104690, +0, +-104635, +0, +-104580, +0, +-104525, +0, +-104470, +0, +-104415, +0, +-104361, +0, +-104306, +0, +-104251, +0, +-104196, +0, +-104141, +0, +-104086, +0, +-104032, +0, +-103977, +0, +-103922, +0, +-103868, +0, +-103813, +0, +-103758, +0, +-103703, +0, +-103649, +0, +-103594, +0, +-103540, +0, +-103485, +0, +-103430, +0, +-103376, +0, +-103321, +0, +-103267, +0, +-103212, +0, +-103158, +0, +-103103, +0, +-103049, +0, +-102994, +0, +-102940, +0, +-102885, +0, +-102831, +0, +-102777, +0, +-102722, +0, +-102668, +0, +-102613, +0, +-102559, +0, +-102505, +0, +-102450, +0, +-102396, +0, +-102342, +0, +-102288, +0, +-102233, +0, +-102179, +0, +-102125, +0, +-102071, +0, +-102017, +0, +-101962, +0, +-101908, +0, +-101854, +0, +-101800, +0, +-101746, +0, +-101692, +0, +-101638, +0, +-101584, +0, +-101530, +0, +-101476, +0, +-101422, +0, +-101368, +0, +-101314, +0, +-101260, +0, +-101206, +0, +-101152, +0, +-101098, +0, +-101044, +0, +-100990, +0, +-100936, +0, +-100883, +0, +-100829, +0, +-100775, +0, +-100721, +0, +-100667, +0, +-100614, +0, +-100560, +0, +-100506, +0, +-100452, +0, +-100399, +0, +-100345, +0, +-100291, +0, +-100238, +0, +-100184, +0, +-100130, +0, +-100077, +0, +-100023, +0, +-99970, +0, +-99916, +0, +-99862, +0, +-99809, +0, +-99755, +0, +-99702, +0, +-99648, +0, +-99595, +0, +-99541, +0, +-99488, +0, +-99435, +0, +-99381, +0, +-99328, +0, +-99274, +0, +-99221, +0, +-99168, +0, +-99114, +0, +-99061, +0, +-99008, +0, +-98954, +0, +-98901, +0, +-98848, +0, +-98795, +0, +-98742, +0, +-98688, +0, +-98635, +0, +-98582, +0, +-98529, +0, +-98476, +0, +-98423, +0, +-98369, +0, +-98316, +0, +-98263, +0, +-98210, +0, +-98157, +0, +-98104, +0, +-98051, +0, +-97998, +0, +-97945, +0, +-97892, +0, +-97839, +0, +-97786, +0, +-97733, +0, +-97680, +0, +-97628, +0, +-97575, +0, +-97522, +0, +-97469, +0, +-97416, +0, +-97363, +0, +-97311, +0, +-97258, +0, +-97205, +0, +-97152, +0, +-97100, +0, +-97047, +0, +-96994, +0, +-96941, +0, +-96889, +0, +-96836, +0, +-96783, +0, +-96731, +0, +-96678, +0, +-96626, +0, +-96573, +0, +-96521, +0, +-96468, +0, +-96415, +0, +-96363, +0, +-96310, +0, +-96258, +0, +-96205, +0, +-96153, +0, +-96101, +0, +-96048, +0, +-95996, +0, +-95943, +0, +-95891, +0, +-95839, +0, +-95786, +0, +-95734, +0, +-95682, +0, +-95629, +0, +-95577, +0, +-95525, +0, +-95473, +0, +-95420, +0, +-95368, +0, +-95316, +0, +-95264, +0, +-95212, +0, +-95160, +0, +-95107, +0, +-95055, +0, +-95003, +0, +-94951, +0, +-94899, +0, +-94847, +0, +-94795, +0, +-94743, +0, +-94691, +0, +-94639, +0, +-94587, +0, +-94535, +0, +-94483, +0, +-94431, +0, +-94379, +0, +-94327, +0, +-94275, +0, +-94223, +0, +-94172, +0, +-94120, +0, +-94068, +0, +-94016, +0, +-93964, +0, +-93913, +0, +-93861, +0, +-93809, +0, +-93757, +0, +-93706, +0, +-93654, +0, +-93602, +0, +-93551, +0, +-93499, +0, +-93447, +0, +-93396, +0, +-93344, +0, +-93293, +0, +-93241, +0, +-93189, +0, +-93138, +0, +-93086, +0, +-93035, +0, +-92983, +0, +-92932, +0, +-92880, +0, +-92829, +0, +-92778, +0, +-92726, +0, +-92675, +0, +-92623, +0, +-92572, +0, +-92521, +0, +-92469, +0, +-92418, +0, +-92367, +0, +-92315, +0, +-92264, +0, +-92213, +0, +-92162, +0, +-92110, +0, +-92059, +0, +-92008, +0, +-91957, +0, +-91906, +0, +-91855, +0, +-91803, +0, +-91752, +0, +-91701, +0, +-91650, +0, +-91599, +0, +-91548, +0, +-91497, +0, +-91446, +0, +-91395, +0, +-91344, +0, +-91293, +0, +-91242, +0, +-91191, +0, +-91140, +0, +-91089, +0, +-91038, +0, +-90987, +0, +-90937, +0, +-90886, +0, +-90835, +0, +-90784, +0, +-90733, +0, +-90682, +0, +-90632, +0, +-90581, +0, +-90530, +0, +-90479, +0, +-90429, +0, +-90378, +0, +-90327, +0, +-90277, +0, +-90226, +0, +-90175, +0, +-90125, +0, +-90074, +0, +-90024, +0, +-89973, +0, +-89923, +0, +-89872, +0, +-89822, +0, +-89771, +0, +-89721, +0, +-89670, +0, +-89620, +0, +-89569, +0, +-89519, +0, +-89468, +0, +-89418, +0, +-89368, +0, +-89317, +0, +-89267, +0, +-89216, +0, +-89166, +0, +-89116, +0, +-89066, +0, +-89015, +0, +-88965, +0, +-88915, +0, +-88865, +0, +-88814, +0, +-88764, +0, +-88714, +0, +-88664, +0, +-88614, +0, +-88564, +0, +-88513, +0, +-88463, +0, +-88413, +0, +-88363, +0, +-88313, +0, +-88263, +0, +-88213, +0, +-88163, +0, +-88113, +0, +-88063, +0, +-88013, +0, +-87963, +0, +-87913, +0, +-87863, +0, +-87814, +0, +-87764, +0, +-87714, +0, +-87664, +0, +-87614, +0, +-87564, +0, +-87515, +0, +-87465, +0, +-87415, +0, +-87365, +0, +-87315, +0, +-87266, +0, +-87216, +0, +-87166, +0, +-87117, +0, +-87067, +0, +-87017, +0, +-86968, +0, +-86918, +0, +-86869, +0, +-86819, +0, +-86769, +0, +-86720, +0, +-86670, +0, +-86621, +0, +-86571, +0, +-86522, +0, +-86472, +0, +-86423, +0, +-86373, +0, +-86324, +0, +-86275, +0, +-86225, +0, +-86176, +0, +-86126, +0, +-86077, +0, +-86028, +0, +-85978, +0, +-85929, +0, +-85880, +0, +-85831, +0, +-85781, +0, +-85732, +0, +-85683, +0, +-85634, +0, +-85585, +0, +-85535, +0, +-85486, +0, +-85437, +0, +-85388, +0, +-85339, +0, +-85290, +0, +-85241, +0, +-85192, +0, +-85143, +0, +-85093, +0, +-85044, +0, +-84995, +0, +-84946, +0, +-84898, +0, +-84849, +0, +-84800, +0, +-84751, +0, +-84702, +0, +-84653, +0, +-84604, +0, +-84555, +0, +-84506, +0, +-84457, +0, +-84409, +0, +-84360, +0, +-84311, +0, +-84262, +0, +-84214, +0, +-84165, +0, +-84116, +0, +-84067, +0, +-84019, +0, +-83970, +0, +-83921, +0, +-83873, +0, +-83824, +0, +-83775, +0, +-83727, +0, +-83678, +0, +-83630, +0, +-83581, +0, +-83533, +0, +-83484, +0, +-83436, +0, +-83387, +0, +-83339, +0, +-83290, +0, +-83242, +0, +-83193, +0, +-83145, +0, +-83097, +0, +-83048, +0, +-83000, +0, +-82951, +0, +-82903, +0, +-82855, +0, +-82807, +0, +-82758, +0, +-82710, +0, +-82662, +0, +-82613, +0, +-82565, +0, +-82517, +0, +-82469, +0, +-82421, +0, +-82373, +0, +-82324, +0, +-82276, +0, +-82228, +0, +-82180, +0, +-82132, +0, +-82084, +0, +-82036, +0, +-81988, +0, +-81940, +0, +-81892, +0, +-81844, +0, +-81796, +0, +-81748, +0, +-81700, +0, +-81652, +0, +-81604, +0, +-81556, +0, +-81508, +0, +-81460, +0, +-81413, +0, +-81365, +0, +-81317, +0, +-81269, +0, +-81221, +0, +-81174, +0, +-81126, +0, +-81078, +0, +-81030, +0, +-80983, +0, +-80935, +0, +-80887, +0, +-80840, +0, +-80792, +0, +-80744, +0, +-80697, +0, +-80649, +0, +-80602, +0, +-80554, +0, +-80506, +0, +-80459, +0, +-80411, +0, +-80364, +0, +-80316, +0, +-80269, +0, +-80221, +0, +-80174, +0, +-80127, +0, +-80079, +0, +-80032, +0, +-79984, +0, +-79937, +0, +-79890, +0, +-79842, +0, +-79795, +0, +-79748, +0, +-79700, +0, +-79653, +0, +-79606, +0, +-79559, +0, +-79511, +0, +-79464, +0, +-79417, +0, +-79370, +0, +-79323, +0, +-79276, +0, +-79228, +0, +-79181, +0, +-79134, +0, +-79087, +0, +-79040, +0, +-78993, +0, +-78946, +0, +-78899, +0, +-78852, +0, +-78805, +0, +-78758, +0, +-78711, +0, +-78664, +0, +-78617, +0, +-78570, +0, +-78523, +0, +-78476, +0, +-78430, +0, +-78383, +0, +-78336, +0, +-78289, +0, +-78242, +0, +-78195, +0, +-78149, +0, +-78102, +0, +-78055, +0, +-78008, +0, +-77962, +0, +-77915, +0, +-77868, +0, +-77822, +0, +-77775, +0, +-77728, +0, +-77682, +0, +-77635, +0, +-77589, +0, +-77542, +0, +-77496, +0, +-77449, +0, +-77402, +0, +-77356, +0, +-77309, +0, +-77263, +0, +-77217, +0, +-77170, +0, +-77124, +0, +-77077, +0, +-77031, +0, +-76984, +0, +-76938, +0, +-76892, +0, +-76845, +0, +-76799, +0, +-76753, +0, +-76706, +0, +-76660, +0, +-76614, +0, +-76568, +0, +-76521, +0, +-76475, +0, +-76429, +0, +-76383, +0, +-76337, +0, +-76291, +0, +-76244, +0, +-76198, +0, +-76152, +0, +-76106, +0, +-76060, +0, +-76014, +0, +-75968, +0, +-75922, +0, +-75876, +0, +-75830, +0, +-75784, +0, +-75738, +0, +-75692, +0, +-75646, +0, +-75600, +0, +-75554, +0, +-75508, +0, +-75462, +0, +-75417, +0, +-75371, +0, +-75325, +0, +-75279, +0, +-75233, +0, +-75188, +0, +-75142, +0, +-75096, +0, +-75050, +0, +-75005, +0, +-74959, +0, +-74913, +0, +-74868, +0, +-74822, +0, +-74776, +0, +-74731, +0, +-74685, +0, +-74639, +0, +-74594, +0, +-74548, +0, +-74503, +0, +-74457, +0, +-74412, +0, +-74366, +0, +-74321, +0, +-74275, +0, +-74230, +0, +-74184, +0, +-74139, +0, +-74094, +0, +-74048, +0, +-74003, +0, +-73957, +0, +-73912, +0, +-73867, +0, +-73821, +0, +-73776, +-1, +-73731, +-1, +-73686, +-1, +-73640, +-1, +-73595, +-1, +-73550, +-1, +-73505, +-1, +-73459, +-1, +-73414, +-1, +-73369, +-1, +-73324, +-1, +-73279, +-1, +-73234, +-1, +-73189, +-1, +-73144, +-1, +-73099, +-1, +-73053, +-1, +-73008, +-1, +-72963, +-1, +-72918, +-1, +-72873, +-1, +-72828, +-1, +-72783, +-1, +-72739, +-1, +-72694, +-1, +-72649, +-1, +-72604, +-1, +-72559, +-1, +-72514, +-1, +-72469, +-1, +-72424, +-1, +-72380, +-1, +-72335, +-1, +-72290, +-1, +-72245, +-1, +-72200, +-1, +-72156, +-1, +-72111, +-1, +-72066, +-1, +-72022, +-1, +-71977, +-1, +-71932, +-1, +-71888, +-1, +-71843, +-1, +-71798, +-1, +-71754, +-1, +-71709, +-1, +-71665, +-1, +-71620, +-1, +-71576, +-1, +-71531, +-1, +-71487, +-1, +-71442, +-1, +-71398, +-1, +-71353, +-1, +-71309, +-1, +-71264, +-1, +-71220, +-1, +-71175, +-1, +-71131, +-1, +-71087, +-1, +-71042, +-1, +-70998, +-1, +-70954, +-1, +-70909, +-1, +-70865, +-1, +-70821, +-1, +-70776, +-1, +-70732, +-1, +-70688, +-1, +-70644, +-1, +-70600, +-1, +-70555, +-1, +-70511, +-1, +-70467, +-1, +-70423, +-1, +-70379, +-1, +-70335, +-1, +-70291, +-1, +-70247, +-1, +-70203, +-1, +-70159, +-1, +-70114, +-1, +-70070, +-1, +-70026, +-1, +-69982, +-1, +-69939, +-1, +-69895, +-1, +-69851, +-1, +-69807, +-1, +-69763, +-1, +-69719, +-1, +-69675, +-1, +-69631, +-1, +-69587, +-1, +-69544, +-1, +-69500, +-1, +-69456, +-1, +-69412, +-1, +-69368, +-1, +-69325, +-1, +-69281, +-1, +-69237, +-1, +-69193, +-1, +-69150, +-1, +-69106, +-1, +-69062, +-1, +-69019, +-1, +-68975, +-1, +-68932, +-1, +-68888, +-1, +-68844, +-1, +-68801, +-1, +-68757, +-1, +-68714, +-1, +-68670, +-1, +-68627, +-1, +-68583, +-1, +-68540, +-1, +-68496, +-1, +-68453, +-1, +-68409, +-1, +-68366, +-1, +-68323, +-1, +-68279, +-1, +-68236, +-1, +-68193, +-1, +-68149, +-1, +-68106, +-2, +-68063, +-2, +-68019, +-2, +-67976, +-2, +-67933, +-2, +-67890, +-2, +-67846, +-2, +-67803, +-2, +-67760, +-2, +-67717, +-2, +-67674, +-2, +-67630, +-2, +-67587, +-2, +-67544, +-2, +-67501, +-2, +-67458, +-2, +-67415, +-2, +-67372, +-2, +-67329, +-2, +-67286, +-2, +-67243, +-2, +-67200, +-2, +-67157, +-2, +-67114, +-2, +-67071, +-2, +-67028, +-2, +-66985, +-2, +-66942, +-2, +-66899, +-2, +-66856, +-2, +-66814, +-2, +-66771, +-2, +-66728, +-2, +-66685, +-2, +-66642, +-2, +-66600, +-2, +-66557, +-2, +-66514, +-2, +-66471, +-2, +-66429, +-2, +-66386, +-2, +-66343, +-2, +-66301, +-2, +-66258, +-2, +-66215, +-2, +-66173, +-2, +-66130, +-2, +-66088, +-2, +-66045, +-2, +-66002, +-2, +-65960, +-2, +-65917, +-2, +-65875, +-2, +-65832, +-2, +-65790, +-2, +-65747, +-2, +-65705, +-2, +-65662, +-2, +-65620, +-2, +-65578, +-2, +-65535, +-2, +-65493, +-2, +-65450, +-2, +-65408, +-2, +-65366, +-2, +-65324, +-2, +-65281, +-2, +-65239, +-2, +-65197, +-2, +-65154, +-2, +-65112, +-2, +-65070, +-2, +-65028, +-2, +-64986, +-2, +-64943, +-2, +-64901, +-2, +-64859, +-2, +-64817, +-2, +-64775, +-3, +-64733, +-3, +-64691, +-3, +-64649, +-3, +-64607, +-3, +-64565, +-3, +-64522, +-3, +-64480, +-3, +-64438, +-3, +-64397, +-3, +-64355, +-3, +-64313, +-3, +-64271, +-3, +-64229, +-3, +-64187, +-3, +-64145, +-3, +-64103, +-3, +-64061, +-3, +-64019, +-3, +-63978, +-3, +-63936, +-3, +-63894, +-3, +-63852, +-3, +-63810, +-3, +-63769, +-3, +-63727, +-3, +-63685, +-3, +-63644, +-3, +-63602, +-3, +-63560, +-3, +-63519, +-3, +-63477, +-3, +-63435, +-3, +-63394, +-3, +-63352, +-3, +-63311, +-3, +-63269, +-3, +-63227, +-3, +-63186, +-3, +-63144, +-3, +-63103, +-3, +-63061, +-3, +-63020, +-3, +-62979, +-3, +-62937, +-3, +-62896, +-3, +-62854, +-3, +-62813, +-3, +-62772, +-3, +-62730, +-3, +-62689, +-3, +-62647, +-3, +-62606, +-3, +-62565, +-3, +-62524, +-3, +-62482, +-3, +-62441, +-4, +-62400, +-4, +-62359, +-4, +-62317, +-4, +-62276, +-4, +-62235, +-4, +-62194, +-4, +-62153, +-4, +-62112, +-4, +-62071, +-4, +-62029, +-4, +-61988, +-4, +-61947, +-4, +-61906, +-4, +-61865, +-4, +-61824, +-4, +-61783, +-4, +-61742, +-4, +-61701, +-4, +-61660, +-4, +-61619, +-4, +-61578, +-4, +-61537, +-4, +-61497, +-4, +-61456, +-4, +-61415, +-4, +-61374, +-4, +-61333, +-4, +-61292, +-4, +-61251, +-4, +-61211, +-4, +-61170, +-4, +-61129, +-4, +-61088, +-4, +-61048, +-4, +-61007, +-4, +-60966, +-4, +-60926, +-4, +-60885, +-4, +-60844, +-4, +-60804, +-4, +-60763, +-4, +-60722, +-4, +-60682, +-4, +-60641, +-4, +-60601, +-5, +-60560, +-5, +-60520, +-5, +-60479, +-5, +-60439, +-5, +-60398, +-5, +-60358, +-5, +-60317, +-5, +-60277, +-5, +-60236, +-5, +-60196, +-5, +-60156, +-5, +-60115, +-5, +-60075, +-5, +-60034, +-5, +-59994, +-5, +-59954, +-5, +-59913, +-5, +-59873, +-5, +-59833, +-5, +-59793, +-5, +-59752, +-5, +-59712, +-5, +-59672, +-5, +-59632, +-5, +-59592, +-5, +-59551, +-5, +-59511, +-5, +-59471, +-5, +-59431, +-5, +-59391, +-5, +-59351, +-5, +-59311, +-5, +-59271, +-5, +-59231, +-5, +-59191, +-5, +-59151, +-5, +-59111, +-6, +-59071, +-6, +-59031, +-6, +-58991, +-6, +-58951, +-6, +-58911, +-6, +-58871, +-6, +-58831, +-6, +-58791, +-6, +-58751, +-6, +-58712, +-6, +-58672, +-6, +-58632, +-6, +-58592, +-6, +-58552, +-6, +-58513, +-6, +-58473, +-6, +-58433, +-6, +-58393, +-6, +-58354, +-6, +-58314, +-6, +-58274, +-6, +-58235, +-6, +-58195, +-6, +-58155, +-6, +-58116, +-6, +-58076, +-6, +-58037, +-6, +-57997, +-6, +-57958, +-6, +-57918, +-6, +-57879, +-7, +-57839, +-7, +-57800, +-7, +-57760, +-7, +-57721, +-7, +-57681, +-7, +-57642, +-7, +-57602, +-7, +-57563, +-7, +-57524, +-7, +-57484, +-7, +-57445, +-7, +-57405, +-7, +-57366, +-7, +-57327, +-7, +-57288, +-7, +-57248, +-7, +-57209, +-7, +-57170, +-7, +-57131, +-7, +-57091, +-7, +-57052, +-7, +-57013, +-7, +-56974, +-7, +-56935, +-7, +-56896, +-7, +-56856, +-7, +-56817, +-7, +-56778, +-8, +-56739, +-8, +-56700, +-8, +-56661, +-8, +-56622, +-8, +-56583, +-8, +-56544, +-8, +-56505, +-8, +-56466, +-8, +-56427, +-8, +-56388, +-8, +-56349, +-8, +-56310, +-8, +-56271, +-8, +-56233, +-8, +-56194, +-8, +-56155, +-8, +-56116, +-8, +-56077, +-8, +-56038, +-8, +-56000, +-8, +-55961, +-8, +-55922, +-8, +-55883, +-8, +-55845, +-8, +-55806, +-9, +-55767, +-9, +-55729, +-9, +-55690, +-9, +-55651, +-9, +-55613, +-9, +-55574, +-9, +-55535, +-9, +-55497, +-9, +-55458, +-9, +-55420, +-9, +-55381, +-9, +-55343, +-9, +-55304, +-9, +-55266, +-9, +-55227, +-9, +-55189, +-9, +-55150, +-9, +-55112, +-9, +-55073, +-9, +-55035, +-9, +-54997, +-9, +-54958, +-10, +-54920, +-10, +-54881, +-10, +-54843, +-10, +-54805, +-10, +-54767, +-10, +-54728, +-10, +-54690, +-10, +-54652, +-10, +-54613, +-10, +-54575, +-10, +-54537, +-10, +-54499, +-10, +-54461, +-10, +-54423, +-10, +-54384, +-10, +-54346, +-10, +-54308, +-10, +-54270, +-10, +-54232, +-10, +-54194, +-10, +-54156, +-11, +-54118, +-11, +-54080, +-11, +-54042, +-11, +-54004, +-11, +-53966, +-11, +-53928, +-11, +-53890, +-11, +-53852, +-11, +-53814, +-11, +-53776, +-11, +-53738, +-11, +-53700, +-11, +-53663, +-11, +-53625, +-11, +-53587, +-11, +-53549, +-11, +-53511, +-11, +-53473, +-11, +-53436, +-12, +-53398, +-12, +-53360, +-12, +-53323, +-12, +-53285, +-12, +-53247, +-12, +-53209, +-12, +-53172, +-12, +-53134, +-12, +-53097, +-12, +-53059, +-12, +-53021, +-12, +-52984, +-12, +-52946, +-12, +-52909, +-12, +-52871, +-12, +-52834, +-12, +-52796, +-13, +-52759, +-13, +-52721, +-13, +-52684, +-13, +-52646, +-13, +-52609, +-13, +-52571, +-13, +-52534, +-13, +-52497, +-13, +-52459, +-13, +-52422, +-13, +-52384, +-13, +-52347, +-13, +-52310, +-13, +-52273, +-13, +-52235, +-13, +-52198, +-14, +-52161, +-14, +-52124, +-14, +-52086, +-14, +-52049, +-14, +-52012, +-14, +-51975, +-14, +-51938, +-14, +-51900, +-14, +-51863, +-14, +-51826, +-14, +-51789, +-14, +-51752, +-14, +-51715, +-14, +-51678, +-14, +-51641, +-14, +-51604, +-15, +-51567, +-15, +-51530, +-15, +-51493, +-15, +-51456, +-15, +-51419, +-15, +-51382, +-15, +-51345, +-15, +-51308, +-15, +-51271, +-15, +-51235, +-15, +-51198, +-15, +-51161, +-15, +-51124, +-15, +-51087, +-16, +-51050, +-16, +-51014, +-16, +-50977, +-16, +-50940, +-16, +-50903, +-16, +-50867, +-16, +-50830, +-16, +-50793, +-16, +-50757, +-16, +-50720, +-16, +-50683, +-16, +-50647, +-16, +-50610, +-17, +-50574, +-17, +-50537, +-17, +-50500, +-17, +-50464, +-17, +-50427, +-17, +-50391, +-17, +-50354, +-17, +-50318, +-17, +-50281, +-17, +-50245, +-17, +-50208, +-17, +-50172, +-17, +-50136, +-18, +-50099, +-18, +-50063, +-18, +-50026, +-18, +-49990, +-18, +-49954, +-18, +-49917, +-18, +-49881, +-18, +-49845, +-18, +-49809, +-18, +-49772, +-18, +-49736, +-18, +-49700, +-19, +-49664, +-19, +-49627, +-19, +-49591, +-19, +-49555, +-19, +-49519, +-19, +-49483, +-19, +-49447, +-19, +-49410, +-19, +-49374, +-19, +-49338, +-19, +-49302, +-19, +-49266, +-20, +-49230, +-20, +-49194, +-20, +-49158, +-20, +-49122, +-20, +-49086, +-20, +-49050, +-20, +-49014, +-20, +-48978, +-20, +-48942, +-20, +-48907, +-20, +-48871, +-21, +-48835, +-21, +-48799, +-21, +-48763, +-21, +-48727, +-21, +-48691, +-21, +-48656, +-21, +-48620, +-21, +-48584, +-21, +-48548, +-21, +-48513, +-21, +-48477, +-22, +-48441, +-22, +-48406, +-22, +-48370, +-22, +-48334, +-22, +-48299, +-22, +-48263, +-22, +-48227, +-22, +-48192, +-22, +-48156, +-22, +-48121, +-23, +-48085, +-23, +-48049, +-23, +-48014, +-23, +-47978, +-23, +-47943, +-23, +-47907, +-23, +-47872, +-23, +-47837, +-23, +-47801, +-23, +-47766, +-24, +-47730, +-24, +-47695, +-24, +-47660, +-24, +-47624, +-24, +-47589, +-24, +-47554, +-24, +-47518, +-24, +-47483, +-24, +-47448, +-25, +-47412, +-25, +-47377, +-25, +-47342, +-25, +-47307, +-25, +-47272, +-25, +-47236, +-25, +-47201, +-25, +-47166, +-25, +-47131, +-26, +-47096, +-26, +-47061, +-26, +-47026, +-26, +-46990, +-26, +-46955, +-26, +-46920, +-26, +-46885, +-26, +-46850, +-26, +-46815, +-27, +-46780, +-27, +-46745, +-27, +-46710, +-27, +-46675, +-27, +-46640, +-27, +-46606, +-27, +-46571, +-27, +-46536, +-27, +-46501, +-28, +-46466, +-28, +-46431, +-28, +-46396, +-28, +-46361, +-28, +-46327, +-28, +-46292, +-28, +-46257, +-28, +-46222, +-29, +-46188, +-29, +-46153, +-29, +-46118, +-29, +-46084, +-29, +-46049, +-29, +-46014, +-29, +-45980, +-29, +-45945, +-30, +-45910, +-30, +-45876, +-30, +-45841, +-30, +-45807, +-30, +-45772, +-30, +-45737, +-30, +-45703, +-30, +-45668, +-31, +-45634, +-31, +-45599, +-31, +-45565, +-31, +-45531, +-31, +-45496, +-31, +-45462, +-31, +-45427, +-32, +-45393, +-32, +-45358, +-32, +-45324, +-32, +-45290, +-32, +-45255, +-32, +-45221, +-32, +-45187, +-33, +-45153, +-33, +-45118, +-33, +-45084, +-33, +-45050, +-33, +-45016, +-33, +-44981, +-33, +-44947, +-33, +-44913, +-34, +-44879, +-34, +-44845, +-34, +-44811, +-34, +-44776, +-34, +-44742, +-34, +-44708, +-35, +-44674, +-35, +-44640, +-35, +-44606, +-35, +-44572, +-35, +-44538, +-35, +-44504, +-35, +-44470, +-36, +-44436, +-36, +-44402, +-36, +-44368, +-36, +-44334, +-36, +-44300, +-36, +-44266, +-36, +-44233, +-37, +-44199, +-37, +-44165, +-37, +-44131, +-37, +-44097, +-37, +-44063, +-37, +-44030, +-38, +-43996, +-38, +-43962, +-38, +-43928, +-38, +-43895, +-38, +-43861, +-38, +-43827, +-38, +-43793, +-39, +-43760, +-39, +-43726, +-39, +-43692, +-39, +-43659, +-39, +-43625, +-39, +-43592, +-40, +-43558, +-40, +-43524, +-40, +-43491, +-40, +-43457, +-40, +-43424, +-40, +-43390, +-41, +-43357, +-41, +-43323, +-41, +-43290, +-41, +-43256, +-41, +-43223, +-41, +-43190, +-42, +-43156, +-42, +-43123, +-42, +-43089, +-42, +-43056, +-42, +-43023, +-43, +-42989, +-43, +-42956, +-43, +-42923, +-43, +-42890, +-43, +-42856, +-43, +-42823, +-44, +-42790, +-44, +-42757, +-44, +-42723, +-44, +-42690, +-44, +-42657, +-44, +-42624, +-45, +-42591, +-45, +-42558, +-45, +-42524, +-45, +-42491, +-45, +-42458, +-46, +-42425, +-46, +-42392, +-46, +-42359, +-46, +-42326, +-46, +-42293, +-47, +-42260, +-47, +-42227, +-47, +-42194, +-47, +-42161, +-47, +-42128, +-47, +-42095, +-48, +-42062, +-48, +-42030, +-48, +-41997, +-48, +-41964, +-48, +-41931, +-49, +-41898, +-49, +-41865, +-49, +-41832, +-49, +-41800, +-49, +-41767, +-50, +-41734, +-50, +-41701, +-50, +-41669, +-50, +-41636, +-50, +-41603, +-51, +-41571, +-51, +-41538, +-51, +-41505, +-51, +-41473, +-52, +-41440, +-52, +-41407, +-52, +-41375, +-52, +-41342, +-52, +-41310, +-53, +-41277, +-53, +-41245, +-53, +-41212, +-53, +-41180, +-53, +-41147, +-54, +-41115, +-54, +-41082, +-54, +-41050, +-54, +-41017, +-54, +-40985, +-55, +-40952, +-55, +-40920, +-55, +-40888, +-55, +-40855, +-56, +-40823, +-56, +-40791, +-56, +-40758, +-56, +-40726, +-56, +-40694, +-57, +-40662, +-57, +-40629, +-57, +-40597, +-57, +-40565, +-58, +-40533, +-58, +-40500, +-58, +-40468, +-58, +-40436, +-59, +-40404, +-59, +-40372, +-59, +-40340, +-59, +-40308, +-59, +-40276, +-60, +-40243, +-60, +-40211, +-60, +-40179, +-60, +-40147, +-61, +-40115, +-61, +-40083, +-61, +-40051, +-61, +-40019, +-62, +-39987, +-62, +-39955, +-62, +-39924, +-62, +-39892, +-63, +-39860, +-63, +-39828, +-63, +-39796, +-63, +-39764, +-64, +-39732, +-64, +-39700, +-64, +-39669, +-64, +-39637, +-65, +-39605, +-65, +-39573, +-65, +-39542, +-65, +-39510, +-66, +-39478, +-66, +-39446, +-66, +-39415, +-66, +-39383, +-67, +-39351, +-67, +-39320, +-67, +-39288, +-67, +-39257, +-68, +-39225, +-68, +-39193, +-68, +-39162, +-69, +-39130, +-69, +-39099, +-69, +-39067, +-69, +-39036, +-70, +-39004, +-70, +-38973, +-70, +-38941, +-70, +-38910, +-71, +-38878, +-71, +-38847, +-71, +-38816, +-72, +-38784, +-72, +-38753, +-72, +-38721, +-72, +-38690, +-73, +-38659, +-73, +-38627, +-73, +-38596, +-73, +-38565, +-74, +-38534, +-74, +-38502, +-74, +-38471, +-75, +-38440, +-75, +-38409, +-75, +-38377, +-75, +-38346, +-76, +-38315, +-76, +-38284, +-76, +-38253, +-77, +-38222, +-77, +-38191, +-77, +-38160, +-78, +-38128, +-78, +-38097, +-78, +-38066, +-78, +-38035, +-79, +-38004, +-79, +-37973, +-79, +-37942, +-80, +-37911, +-80, +-37880, +-80, +-37849, +-81, +-37818, +-81, +-37788, +-81, +-37757, +-82, +-37726, +-82, +-37695, +-82, +-37664, +-82, +-37633, +-83, +-37602, +-83, +-37572, +-83, +-37541, +-84, +-37510, +-84, +-37479, +-84, +-37448, +-85, +-37418, +-85, +-37387, +-85, +-37356, +-86, +-37326, +-86, +-37295, +-86, +-37264, +-87, +-37234, +-87, +-37203, +-87, +-37172, +-88, +-37142, +-88, +-37111, +-88, +-37081, +-89, +-37050, +-89, +-37020, +-89, +-36989, +-90, +-36958, +-90, +-36928, +-90, +-36897, +-91, +-36867, +-91, +-36837, +-91, +-36806, +-92, +-36776, +-92, +-36745, +-92, +-36715, +-93, +-36684, +-93, +-36654, +-93, +-36624, +-94, +-36593, +-94, +-36563, +-94, +-36533, +-95, +-36503, +-95, +-36472, +-96, +-36442, +-96, +-36412, +-96, +-36381, +-97, +-36351, +-97, +-36321, +-97, +-36291, +-98, +-36261, +-98, +-36231, +-98, +-36200, +-99, +-36170, +-99, +-36140, +-100, +-36110, +-100, +-36080, +-100, +-36050, +-101, +-36020, +-101, +-35990, +-101, +-35960, +-102, +-35930, +-102, +-35900, +-103, +-35870, +-103, +-35840, +-103, +-35810, +-104, +-35780, +-104, +-35750, +-104, +-35720, +-105, +-35690, +-105, +-35660, +-106, +-35630, +-106, +-35601, +-106, +-35571, +-107, +-35541, +-107, +-35511, +-108, +-35481, +-108, +-35452, +-108, +-35422, +-109, +-35392, +-109, +-35362, +-110, +-35333, +-110, +-35303, +-110, +-35273, +-111, +-35243, +-111, +-35214, +-112, +-35184, +-112, +-35155, +-112, +-35125, +-113, +-35095, +-113, +-35066, +-114, +-35036, +-114, +-35007, +-114, +-34977, +-115, +-34948, +-115, +-34918, +-116, +-34889, +-116, +-34859, +-117, +-34830, +-117, +-34800, +-117, +-34771, +-118, +-34741, +-118, +-34712, +-119, +-34682, +-119, +-34653, +-120, +-34624, +-120, +-34594, +-120, +-34565, +-121, +-34536, +-121, +-34506, +-122, +-34477, +-122, +-34448, +-123, +-34419, +-123, +-34389, +-124, +-34360, +-124, +-34331, +-124, +-34302, +-125, +-34272, +-125, +-34243, +-126, +-34214, +-126, +-34185, +-127, +-34156, +-127, +-34127, +-128, +-34098, +-128, +-34069, +-129, +-34039, +-129, +-34010, +-129, +-33981, +-130, +-33952, +-130, +-33923, +-131, +-33894, +-131, +-33865, +-132, +-33836, +-132, +-33807, +-133, +-33778, +-133, +-33750, +-134, +-33721, +-134, +-33692, +-135, +-33663, +-135, +-33634, +-136, +-33605, +-136, +-33576, +-137, +-33547, +-137, +-33519, +-138, +-33490, +-138, +-33461, +-139, +-33432, +-139, +-33404, +-140, +-33375, +-140, +-33346, +-141, +-33317, +-141, +-33289, +-142, +-33260, +-142, +-33231, +-143, +-33203, +-143, +-33174, +-144, +-33145, +-144, +-33117, +-145, +-33088, +-145, +-33060, +-146, +-33031, +-146, +-33003, +-147, +-32974, +-147, +-32945, +-148, +-32917, +-148, +-32888, +-149, +-32860, +-149, +-32832, +-150, +-32803, +-150, +-32775, +-151, +-32746, +-151, +-32718, +-152, +-32689, +-152, +-32661, +-153, +-32633, +-153, +-32604, +-154, +-32576, +-155, +-32548, +-155, +-32519, +-156, +-32491, +-156, +-32463, +-157, +-32435, +-157, +-32406, +-158, +-32378, +-158, +-32350, +-159, +-32322, +-159, +-32294, +-160, +-32265, +-161, +-32237, +-161, +-32209, +-162, +-32181, +-162, +-32153, +-163, +-32125, +-163, +-32097, +-164, +-32069, +-165, +-32041, +-165, +-32013, +-166, +-31985, +-166, +-31957, +-167, +-31929, +-167, +-31901, +-168, +-31873, +-169, +-31845, +-169, +-31817, +-170, +-31789, +-170, +-31761, +-171, +-31733, +-172, +-31705, +-172, +-31677, +-173, +-31649, +-173, +-31622, +-174, +-31594, +-175, +-31566, +-175, +-31538, +-176, +-31510, +-176, +-31483, +-177, +-31455, +-178, +-31427, +-178, +-31399, +-179, +-31372, +-179, +-31344, +-180, +-31316, +-181, +-31289, +-181, +-31261, +-182, +-31233, +-182, +-31206, +-183, +-31178, +-184, +-31151, +-184, +-31123, +-185, +-31096, +-186, +-31068, +-186, +-31040, +-187, +-31013, +-188, +-30985, +-188, +-30958, +-189, +-30931, +-189, +-30903, +-190, +-30876, +-191, +-30848, +-191, +-30821, +-192, +-30793, +-193, +-30766, +-193, +-30739, +-194, +-30711, +-195, +-30684, +-195, +-30657, +-196, +-30629, +-197, +-30602, +-197, +-30575, +-198, +-30547, +-199, +-30520, +-199, +-30493, +-200, +-30466, +-201, +-30439, +-201, +-30411, +-202, +-30384, +-203, +-30357, +-203, +-30330, +-204, +-30303, +-205, +-30276, +-205, +-30249, +-206, +-30221, +-207, +-30194, +-208, +-30167, +-208, +-30140, +-209, +-30113, +-210, +-30086, +-210, +-30059, +-211, +-30032, +-212, +-30005, +-212, +-29978, +-213, +-29951, +-214, +-29924, +-215, +-29897, +-215, +-29871, +-216, +-29844, +-217, +-29817, +-217, +-29790, +-218, +-29763, +-219, +-29736, +-220, +-29709, +-220, +-29683, +-221, +-29656, +-222, +-29629, +-223, +-29602, +-223, +-29576, +-224, +-29549, +-225, +-29522, +-226, +-29495, +-226, +-29469, +-227, +-29442, +-228, +-29415, +-229, +-29389, +-229, +-29362, +-230, +-29335, +-231, +-29309, +-232, +-29282, +-232, +-29256, +-233, +-29229, +-234, +-29203, +-235, +-29176, +-235, +-29150, +-236, +-29123, +-237, +-29097, +-238, +-29070, +-239, +-29044, +-239, +-29017, +-240, +-28991, +-241, +-28964, +-242, +-28938, +-243, +-28912, +-243, +-28885, +-244, +-28859, +-245, +-28832, +-246, +-28806, +-247, +-28780, +-247, +-28754, +-248, +-28727, +-249, +-28701, +-250, +-28675, +-251, +-28649, +-251, +-28622, +-252, +-28596, +-253, +-28570, +-254, +-28544, +-255, +-28518, +-256, +-28491, +-256, +-28465, +-257, +-28439, +-258, +-28413, +-259, +-28387, +-260, +-28361, +-261, +-28335, +-261, +-28309, +-262, +-28283, +-263, +-28257, +-264, +-28231, +-265, +-28205, +-266, +-28179, +-267, +-28153, +-267, +-28127, +-268, +-28101, +-269, +-28075, +-270, +-28049, +-271, +-28023, +-272, +-27997, +-273, +-27971, +-273, +-27945, +-274, +-27920, +-275, +-27894, +-276, +-27868, +-277, +-27842, +-278, +-27816, +-279, +-27791, +-280, +-27765, +-281, +-27739, +-281, +-27713, +-282, +-27688, +-283, +-27662, +-284, +-27636, +-285, +-27611, +-286, +-27585, +-287, +-27559, +-288, +-27534, +-289, +-27508, +-290, +-27483, +-291, +-27457, +-292, +-27431, +-292, +-27406, +-293, +-27380, +-294, +-27355, +-295, +-27329, +-296, +-27304, +-297, +-27278, +-298, +-27253, +-299, +-27227, +-300, +-27202, +-301, +-27176, +-302, +-27151, +-303, +-27126, +-304, +-27100, +-305, +-27075, +-306, +-27050, +-307, +-27024, +-308, +-26999, +-309, +-26974, +-310, +-26948, +-311, +-26923, +-312, +-26898, +-313, +-26873, +-314, +-26847, +-315, +-26822, +-316, +-26797, +-317, +-26772, +-318, +-26746, +-319, +-26721, +-320, +-26696, +-321, +-26671, +-322, +-26646, +-323, +-26621, +-324, +-26596, +-325, +-26571, +-326, +-26546, +-327, +-26520, +-328, +-26495, +-329, +-26470, +-330, +-26445, +-331, +-26420, +-332, +-26395, +-333, +-26370, +-334, +-26346, +-335, +-26321, +-336, +-26296, +-337, +-26271, +-338, +-26246, +-339, +-26221, +-340, +-26196, +-341, +-26171, +-342, +-26146, +-343, +-26122, +-344, +-26097, +-345, +-26072, +-347, +-26047, +-348, +-26022, +-349, +-25998, +-350, +-25973, +-351, +-25948, +-352, +-25924, +-353, +-25899, +-354, +-25874, +-355, +-25849, +-356, +-25825, +-357, +-25800, +-358, +-25776, +-360, +-25751, +-361, +-25726, +-362, +-25702, +-363, +-25677, +-364, +-25653, +-365, +-25628, +-366, +-25604, +-367, +-25579, +-369, +-25555, +-370, +-25530, +-371, +-25506, +-372, +-25481, +-373, +-25457, +-374, +-25432, +-375, +-25408, +-376, +-25383, +-378, +-25359, +-379, +-25335, +-380, +-25310, +-381, +-25286, +-382, +-25262, +-383, +-25237, +-385, +-25213, +-386, +-25189, +-387, +-25165, +-388, +-25140, +-389, +-25116, +-390, +-25092, +-392, +-25068, +-393, +-25043, +-394, +-25019, +-395, +-24995, +-396, +-24971, +-398, +-24947, +-399, +-24923, +-400, +-24898, +-401, +-24874, +-402, +-24850, +-404, +-24826, +-405, +-24802, +-406, +-24778, +-407, +-24754, +-409, +-24730, +-410, +-24706, +-411, +-24682, +-412, +-24658, +-414, +-24634, +-415, +-24610, +-416, +-24586, +-417, +-24562, +-419, +-24538, +-420, +-24515, +-421, +-24491, +-422, +-24467, +-424, +-24443, +-425, +-24419, +-426, +-24395, +-427, +-24372, +-429, +-24348, +-430, +-24324, +-431, +-24300, +-433, +-24276, +-434, +-24253, +-435, +-24229, +-436, +-24205, +-438, +-24182, +-439, +-24158, +-440, +-24134, +-442, +-24111, +-443, +-24087, +-444, +-24063, +-446, +-24040, +-447, +-24016, +-448, +-23993, +-450, +-23969, +-451, +-23945, +-452, +-23922, +-454, +-23898, +-455, +-23875, +-456, +-23851, +-458, +-23828, +-459, +-23804, +-460, +-23781, +-462, +-23758, +-463, +-23734, +-464, +-23711, +-466, +-23687, +-467, +-23664, +-469, +-23641, +-470, +-23617, +-471, +-23594, +-473, +-23571, +-474, +-23547, +-475, +-23524, +-477, +-23501, +-478, +-23477, +-480, +-23454, +-481, +-23431, +-482, +-23408, +-484, +-23384, +-485, +-23361, +-487, +-23338, +-488, +-23315, +-490, +-23292, +-491, +-23269, +-492, +-23245, +-494, +-23222, +-495, +-23199, +-497, +-23176, +-498, +-23153, +-500, +-23130, +-501, +-23107, +-503, +-23084, +-504, +-23061, +-505, +-23038, +-507, +-23015, +-508, +-22992, +-510, +-22969, +-511, +-22946, +-513, +-22923, +-514, +-22900, +-516, +-22877, +-517, +-22854, +-519, +-22832, +-520, +-22809, +-522, +-22786, +-523, +-22763, +-525, +-22740, +-526, +-22717, +-528, +-22695, +-529, +-22672, +-531, +-22649, +-532, +-22626, +-534, +-22604, +-536, +-22581, +-537, +-22558, +-539, +-22535, +-540, +-22513, +-542, +-22490, +-543, +-22467, +-545, +-22445, +-546, +-22422, +-548, +-22400, +-549, +-22377, +-551, +-22354, +-553, +-22332, +-554, +-22309, +-556, +-22287, +-557, +-22264, +-559, +-22242, +-561, +-22219, +-562, +-22197, +-564, +-22174, +-565, +-22152, +-567, +-22129, +-569, +-22107, +-570, +-22084, +-572, +-22062, +-573, +-22040, +-575, +-22017, +-577, +-21995, +-578, +-21973, +-580, +-21950, +-582, +-21928, +-583, +-21906, +-585, +-21883, +-587, +-21861, +-588, +-21839, +-590, +-21817, +-592, +-21794, +-593, +-21772, +-595, +-21750, +-597, +-21728, +-598, +-21706, +-600, +-21683, +-602, +-21661, +-603, +-21639, +-605, +-21617, +-607, +-21595, +-608, +-21573, +-610, +-21551, +-612, +-21529, +-614, +-21507, +-615, +-21485, +-617, +-21462, +-619, +-21440, +-620, +-21418, +-622, +-21396, +-624, +-21375, +-626, +-21353, +-627, +-21331, +-629, +-21309, +-631, +-21287, +-633, +-21265, +-634, +-21243, +-636, +-21221, +-638, +-21199, +-640, +-21177, +-642, +-21156, +-643, +-21134, +-645, +-21112, +-647, +-21090, +-649, +-21068, +-650, +-21047, +-652, +-21025, +-654, +-21003, +-656, +-20981, +-658, +-20960, +-660, +-20938, +-661, +-20916, +-663, +-20895, +-665, +-20873, +-667, +-20851, +-669, +-20830, +-671, +-20808, +-672, +-20787, +-674, +-20765, +-676, +-20743, +-678, +-20722, +-680, +-20700, +-682, +-20679, +-684, +-20657, +-685, +-20636, +-687, +-20614, +-689, +-20593, +-691, +-20571, +-693, +-20550, +-695, +-20528, +-697, +-20507, +-699, +-20486, +-701, +-20464, +-703, +-20443, +-704, +-20421, +-706, +-20400, +-708, +-20379, +-710, +-20357, +-712, +-20336, +-714, +-20315, +-716, +-20294, +-718, +-20272, +-720, +-20251, +-722, +-20230, +-724, +-20209, +-726, +-20187, +-728, +-20166, +-730, +-20145, +-732, +-20124, +-734, +-20103, +-736, +-20082, +-738, +-20060, +-740, +-20039, +-742, +-20018, +-744, +-19997, +-746, +-19976, +-748, +-19955, +-750, +-19934, +-752, +-19913, +-754, +-19892, +-756, +-19871, +-758, +-19850, +-760, +-19829, +-762, +-19808, +-764, +-19787, +-766, +-19766, +-768, +-19745, +-770, +-19724, +-772, +-19703, +-774, +-19682, +-776, +-19662, +-778, +-19641, +-781, +-19620, +-783, +-19599, +-785, +-19578, +-787, +-19557, +-789, +-19537, +-791, +-19516, +-793, +-19495, +-795, +-19474, +-797, +-19454, +-799, +-19433, +-802, +-19412, +-804, +-19392, +-806, +-19371, +-808, +-19350, +-810, +-19330, +-812, +-19309, +-814, +-19288, +-817, +-19268, +-819, +-19247, +-821, +-19226, +-823, +-19206, +-825, +-19185, +-827, +-19165, +-830, +-19144, +-832, +-19124, +-834, +-19103, +-836, +-19083, +-838, +-19062, +-841, +-19042, +-843, +-19021, +-845, +-19001, +-847, +-18981, +-850, +-18960, +-852, +-18940, +-854, +-18919, +-856, +-18899, +-859, +-18879, +-861, +-18858, +-863, +-18838, +-865, +-18818, +-868, +-18797, +-870, +-18777, +-872, +-18757, +-874, +-18737, +-877, +-18716, +-879, +-18696, +-881, +-18676, +-884, +-18656, +-886, +-18636, +-888, +-18615, +-891, +-18595, +-893, +-18575, +-895, +-18555, +-897, +-18535, +-900, +-18515, +-902, +-18495, +-905, +-18475, +-907, +-18454, +-909, +-18434, +-912, +-18414, +-914, +-18394, +-916, +-18374, +-919, +-18354, +-921, +-18334, +-923, +-18314, +-926, +-18294, +-928, +-18275, +-931, +-18255, +-933, +-18235, +-935, +-18215, +-938, +-18195, +-940, +-18175, +-943, +-18155, +-945, +-18135, +-948, +-18115, +-950, +-18096, +-952, +-18076, +-955, +-18056, +-957, +-18036, +-960, +-18016, +-962, +-17997, +-965, +-17977, +-967, +-17957, +-970, +-17938, +-972, +-17918, +-975, +-17898, +-977, +-17879, +-980, +-17859, +-982, +-17839, +-985, +-17820, +-987, +-17800, +-990, +-17780, +-992, +-17761, +-995, +-17741, +-997, +-17722, +-1000, +-17702, +-1002, +-17683, +-1005, +-17663, +-1007, +-17643, +-1010, +-17624, +-1013, +-17605, +-1015, +-17585, +-1018, +-17566, +-1020, +-17546, +-1023, +-17527, +-1025, +-17507, +-1028, +-17488, +-1031, +-17469, +-1033, +-17449, +-1036, +-17430, +-1038, +-17410, +-1041, +-17391, +-1044, +-17372, +-1046, +-17352, +-1049, +-17333, +-1052, +-17314, +-1054, +-17295, +-1057, +-17275, +-1060, +-17256, +-1062, +-17237, +-1065, +-17218, +-1068, +-17198, +-1070, +-17179, +-1073, +-17160, +-1076, +-17141, +-1078, +-17122, +-1081, +-17103, +-1084, +-17084, +-1086, +-17064, +-1089, +-17045, +-1092, +-17026, +-1095, +-17007, +-1097, +-16988, +-1100, +-16969, +-1103, +-16950, +-1105, +-16931, +-1108, +-16912, +-1111, +-16893, +-1114, +-16874, +-1117, +-16855, +-1119, +-16836, +-1122, +-16817, +-1125, +-16798, +-1128, +-16779, +-1130, +-16761, +-1133, +-16742, +-1136, +-16723, +-1139, +-16704, +-1142, +-16685, +-1145, +-16666, +-1147, +-16647, +-1150, +-16629, +-1153, +-16610, +-1156, +-16591, +-1159, +-16572, +-1162, +-16554, +-1164, +-16535, +-1167, +-16516, +-1170, +-16497, +-1173, +-16479, +-1176, +-16460, +-1179, +-16441, +-1182, +-16423, +-1185, +-16404, +-1188, +-16386, +-1190, +-16367, +-1193, +-16348, +-1196, +-16330, +-1199, +-16311, +-1202, +-16293, +-1205, +-16274, +-1208, +-16256, +-1211, +-16237, +-1214, +-16218, +-1217, +-16200, +-1220, +-16182, +-1223, +-16163, +-1226, +-16145, +-1229, +-16126, +-1232, +-16108, +-1235, +-16089, +-1238, +-16071, +-1241, +-16053, +-1244, +-16034, +-1247, +-16016, +-1250, +-15997, +-1253, +-15979, +-1256, +-15961, +-1259, +-15942, +-1262, +-15924, +-1265, +-15906, +-1268, +-15888, +-1271, +-15869, +-1274, +-15851, +-1277, +-15833, +-1280, +-15815, +-1283, +-15796, +-1287, +-15778, +-1290, +-15760, +-1293, +-15742, +-1296, +-15724, +-1299, +-15706, +-1302, +-15688, +-1305, +-15669, +-1308, +-15651, +-1311, +-15633, +-1315, +-15615, +-1318, +-15597, +-1321, +-15579, +-1324, +-15561, +-1327, +-15543, +-1330, +-15525, +-1334, +-15507, +-1337, +-15489, +-1340, +-15471, +-1343, +-15453, +-1346, +-15435, +-1350, +-15417, +-1353, +-15399, +-1356, +-15382, +-1359, +-15364, +-1363, +-15346, +-1366, +-15328, +-1369, +-15310, +-1372, +-15292, +-1376, +-15274, +-1379, +-15257, +-1382, +-15239, +-1385, +-15221, +-1389, +-15203, +-1392, +-15186, +-1395, +-15168, +-1398, +-15150, +-1402, +-15132, +-1405, +-15115, +-1408, +-15097, +-1412, +-15079, +-1415, +-15062, +-1418, +-15044, +-1422, +-15026, +-1425, +-15009, +-1428, +-14991, +-1432, +-14973, +-1435, +-14956, +-1439, +-14938, +-1442, +-14921, +-1445, +-14903, +-1449, +-14886, +-1452, +-14868, +-1455, +-14851, +-1459, +-14833, +-1462, +-14816, +-1466, +-14798, +-1469, +-14781, +-1473, +-14763, +-1476, +-14746, +-1479, +-14729, +-1483, +-14711, +-1486, +-14694, +-1490, +-14676, +-1493, +-14659, +-1497, +-14642, +-1500, +-14624, +-1504, +-14607, +-1507, +-14590, +-1511, +-14572, +-1514, +-14555, +-1518, +-14538, +-1521, +-14521, +-1525, +-14503, +-1528, +-14486, +-1532, +-14469, +-1535, +-14452, +-1539, +-14435, +-1543, +-14417, +-1546, +-14400, +-1550, +-14383, +-1553, +-14366, +-1557, +-14349, +-1560, +-14332, +-1564, +-14315, +-1568, +-14297, +-1571, +-14280, +-1575, +-14263, +-1579, +-14246, +-1582, +-14229, +-1586, +-14212, +-1589, +-14195, +-1593, +-14178, +-1597, +-14161, +-1600, +-14144, +-1604, +-14127, +-1608, +-14110, +-1611, +-14093, +-1615, +-14077, +-1619, +-14060, +-1622, +-14043, +-1626, +-14026, +-1630, +-14009, +-1634, +-13992, +-1637, +-13975, +-1641, +-13958, +-1645, +-13942, +-1649, +-13925, +-1652, +-13908, +-1656, +-13891, +-1660, +-13875, +-1664, +-13858, +-1667, +-13841, +-1671, +-13824, +-1675, +-13808, +-1679, +-13791, +-1683, +-13774, +-1686, +-13758, +-1690, +-13741, +-1694, +-13724, +-1698, +-13708, +-1702, +-13691, +-1706, +-13674, +-1709, +-13658, +-1713, +-13641, +-1717, +-13625, +-1721, +-13608, +-1725, +-13592, +-1729, +-13575, +-1733, +-13558, +-1736, +-13542, +-1740, +-13525, +-1744, +-13509, +-1748, +-13493, +-1752, +-13476, +-1756, +-13460, +-1760, +-13443, +-1764, +-13427, +-1768, +-13410, +-1772, +-13394, +-1776, +-13378, +-1780, +-13361, +-1784, +-13345, +-1788, +-13329, +-1792, +-13312, +-1796, +-13296, +-1800, +-13280, +-1804, +-13263, +-1808, +-13247, +-1812, +-13231, +-1816, +-13215, +-1820, +-13198, +-1824, +-13182, +-1828, +-13166, +-1832, +-13150, +-1836, +-13134, +-1840, +-13117, +-1844, +-13101, +-1848, +-13085, +-1852, +-13069, +-1857, +-13053, +-1861, +-13037, +-1865, +-13021, +-1869, +-13005, +-1873, +-12988, +-1877, +-12972, +-1881, +-12956, +-1885, +-12940, +-1890, +-12924, +-1894, +-12908, +-1898, +-12892, +-1902, +-12876, +-1906, +-12860, +-1910, +-12844, +-1915, +-12828, +-1919, +-12813, +-1923, +-12797, +-1927, +-12781, +-1931, +-12765, +-1936, +-12749, +-1940, +-12733, +-1944, +-12717, +-1948, +-12701, +-1953, +-12686, +-1957, +-12670, +-1961, +-12654, +-1966, +-12638, +-1970, +-12622, +-1974, +-12607, +-1978, +-12591, +-1983, +-12575, +-1987, +-12559, +-1991, +-12544, +-1996, +-12528, +-2000, +-12512, +-2004, +-12497, +-2009, +-12481, +-2013, +-12465, +-2017, +-12450, +-2022, +-12434, +-2026, +-12418, +-2031, +-12403, +-2035, +-12387, +-2039, +-12372, +-2044, +-12356, +-2048, +-12341, +-2053, +-12325, +-2057, +-12310, +-2062, +-12294, +-2066, +-12279, +-2070, +-12263, +-2075, +-12248, +-2079, +-12232, +-2084, +-12217, +-2088, +-12201, +-2093, +-12186, +-2097, +-12170, +-2102, +-12155, +-2106, +-12140, +-2111, +-12124, +-2115, +-12109, +-2120, +-12094, +-2124, +-12078, +-2129, +-12063, +-2133, +-12048, +-2138, +-12032, +-2143, +-12017, +-2147, +-12002, +-2152, +-11986, +-2156, +-11971, +-2161, +-11956, +-2166, +-11941, +-2170, +-11926, +-2175, +-11910, +-2179, +-11895, +-2184, +-11880, +-2189, +-11865, +-2193, +-11850, +-2198, +-11835, +-2203, +-11819, +-2207, +-11804, +-2212, +-11789, +-2217, +-11774, +-2221, +-11759, +-2226, +-11744, +-2231, +-11729, +-2236, +-11714, +-2240, +-11699, +-2245, +-11684, +-2250, +-11669, +-2254, +-11654, +-2259, +-11639, +-2264, +-11624, +-2269, +-11609, +-2274, +-11594, +-2278, +-11579, +-2283, +-11564, +-2288, +-11549, +-2293, +-11535, +-2298, +-11520, +-2302, +-11505, +-2307, +-11490, +-2312, +-11475, +-2317, +-11460, +-2322, +-11446, +-2327, +-11431, +-2331, +-11416, +-2336, +-11401, +-2341, +-11386, +-2346, +-11372, +-2351, +-11357, +-2356, +-11342, +-2361, +-11328, +-2366, +-11313, +-2371, +-11298, +-2376, +-11283, +-2381, +-11269, +-2385, +-11254, +-2390, +-11240, +-2395, +-11225, +-2400, +-11210, +-2405, +-11196, +-2410, +-11181, +-2415, +-11167, +-2420, +-11152, +-2425, +-11137, +-2430, +-11123, +-2435, +-11108, +-2440, +-11094, +-2445, +-11079, +-2451, +-11065, +-2456, +-11050, +-2461, +-11036, +-2466, +-11022, +-2471, +-11007, +-2476, +-10993, +-2481, +-10978, +-2486, +-10964, +-2491, +-10949, +-2496, +-10935, +-2501, +-10921, +-2507, +-10906, +-2512, +-10892, +-2517, +-10878, +-2522, +-10863, +-2527, +-10849, +-2532, +-10835, +-2538, +-10821, +-2543, +-10806, +-2548, +-10792, +-2553, +-10778, +-2558, +-10764, +-2564, +-10749, +-2569, +-10735, +-2574, +-10721, +-2579, +-10707, +-2585, +-10693, +-2590, +-10678, +-2595, +-10664, +-2600, +-10650, +-2606, +-10636, +-2611, +-10622, +-2616, +-10608, +-2622, +-10594, +-2627, +-10580, +-2632, +-10566, +-2638, +-10552, +-2643, +-10538, +-2648, +-10524, +-2654, +-10510, +-2659, +-10496, +-2664, +-10482, +-2670, +-10468, +-2675, +-10454, +-2680, +-10440, +-2686, +-10426, +-2691, +-10412, +-2697, +-10398, +-2702, +-10384, +-2708, +-10370, +-2713, +-10356, +-2719, +-10342, +-2724, +-10329, +-2729, +-10315, +-2735, +-10301, +-2740, +-10287, +-2746, +-10273, +-2751, +-10260, +-2757, +-10246, +-2762, +-10232, +-2768, +-10218, +-2773, +-10205, +-2779, +-10191, +-2785, +-10177, +-2790, +-10163, +-2796, +-10150, +-2801, +-10136, +-2807, +-10122, +-2812, +-10109, +-2818, +-10095, +-2824, +-10081, +-2829, +-10068, +-2835, +-10054, +-2841, +-10041, +-2846, +-10027, +-2852, +-10013, +-2857, +-10000, +-2863, +-9986, +-2869, +-9973, +-2875, +-9959, +-2880, +-9946, +-2886, +-9932, +-2892, +-9919, +-2897, +-9905, +-2903, +-9892, +-2909, +-9878, +-2915, +-9865, +-2920, +-9852, +-2926, +-9838, +-2932, +-9825, +-2938, +-9811, +-2943, +-9798, +-2949, +-9785, +-2955, +-9771, +-2961, +-9758, +-2967, +-9745, +-2972, +-9731, +-2978, +-9718, +-2984, +-9705, +-2990, +-9691, +-2996, +-9678, +-3002, +-9665, +-3008, +-9652, +-3013, +-9638, +-3019, +-9625, +-3025, +-9612, +-3031, +-9599, +-3037, +-9586, +-3043, +-9572, +-3049, +-9559, +-3055, +-9546, +-3061, +-9533, +-3067, +-9520, +-3073, +-9507, +-3079, +-9494, +-3085, +-9481, +-3091, +-9468, +-3097, +-9454, +-3103, +-9441, +-3109, +-9428, +-3115, +-9415, +-3121, +-9402, +-3127, +-9389, +-3133, +-9376, +-3139, +-9363, +-3145, +-9350, +-3151, +-9337, +-3157, +-9325, +-3163, +-9312, +-3169, +-9299, +-3175, +-9286, +-3182, +-9273, +-3188, +-9260, +-3194, +-9247, +-3200, +-9234, +-3206, +-9221, +-3212, +-9209, +-3218, +-9196, +-3225, +-9183, +-3231, +-9170, +-3237, +-9157, +-3243, +-9145, +-3249, +-9132, +-3256, +-9119, +-3262, +-9106, +-3268, +-9094, +-3274, +-9081, +-3281, +-9068, +-3287, +-9055, +-3293, +-9043, +-3299, +-9030, +-3306, +-9017, +-3312, +-9005, +-3318, +-8992, +-3325, +-8980, +-3331, +-8967, +-3337, +-8954, +-3344, +-8942, +-3350, +-8929, +-3356, +-8917, +-3363, +-8904, +-3369, +-8891, +-3376, +-8879, +-3382, +-8866, +-3388, +-8854, +-3395, +-8841, +-3401, +-8829, +-3408, +-8816, +-3414, +-8804, +-3421, +-8792, +-3427, +-8779, +-3433, +-8767, +-3440, +-8754, +-3446, +-8742, +-3453, +-8729, +-3459, +-8717, +-3466, +-8705, +-3472, +-8692, +-3479, +-8680, +-3486, +-8668, +-3492, +-8655, +-3499, +-8643, +-3505, +-8631, +-3512, +-8619, +-3518, +-8606, +-3525, +-8594, +-3532, +-8582, +-3538, +-8569, +-3545, +-8557, +-3551, +-8545, +-3558, +-8533, +-3565, +-8521, +-3571, +-8508, +-3578, +-8496, +-3585, +-8484, +-3591, +-8472, +-3598, +-8460, +-3605, +-8448, +-3611, +-8436, +-3618, +-8424, +-3625, +-8411, +-3632, +-8399, +-3638, +-8387, +-3645, +-8375, +-3652, +-8363, +-3659, +-8351, +-3665, +-8339, +-3672, +-8327, +-3679, +-8315, +-3686, +-8303, +-3693, +-8291, +-3699, +-8279, +-3706, +-8267, +-3713, +-8255, +-3720, +-8243, +-3727, +-8232, +-3734, +-8220, +-3741, +-8208, +-3748, +-8196, +-3754, +-8184, +-3761, +-8172, +-3768, +-8160, +-3775, +-8148, +-3782, +-8137, +-3789, +-8125, +-3796, +-8113, +-3803, +-8101, +-3810, +-8090, +-3817, +-8078, +-3824, +-8066, +-3831, +-8054, +-3838, +-8043, +-3845, +-8031, +-3852, +-8019, +-3859, +-8007, +-3866, +-7996, +-3873, +-7984, +-3880, +-7972, +-3887, +-7961, +-3894, +-7949, +-3901, +-7937, +-3909, +-7926, +-3916, +-7914, +-3923, +-7903, +-3930, +-7891, +-3937, +-7880, +-3944, +-7868, +-3951, +-7856, +-3958, +-7845, +-3966, +-7833, +-3973, +-7822, +-3980, +-7810, +-3987, +-7799, +-3994, +-7787, +-4002, +-7776, +-4009, +-7764, +-4016, +-7753, +-4023, +-7742, +-4031, +-7730, +-4038, +-7719, +-4045, +-7707, +-4052, +-7696, +-4060, +-7685, +-4067, +-7673, +-4074, +-7662, +-4082, +-7651, +-4089, +-7639, +-4096, +-7628, +-4104, +-7617, +-4111, +-7605, +-4118, +-7594, +-4126, +-7583, +-4133, +-7571, +-4141, +-7560, +-4148, +-7549, +-4155, +-7538, +-4163, +-7527, +-4170, +-7515, +-4178, +-7504, +-4185, +-7493, +-4193, +-7482, +-4200, +-7471, +-4208, +-7459, +-4215, +-7448, +-4223, +-7437, +-4230, +-7426, +-4238, +-7415, +-4245, +-7404, +-4253, +-7393, +-4260, +-7382, +-4268, +-7371, +-4275, +-7360, +-4283, +-7349, +-4291, +-7338, +-4298, +-7327, +-4306, +-7316, +-4313, +-7305, +-4321, +-7294, +-4329, +-7283, +-4336, +-7272, +-4344, +-7261, +-4352, +-7250, +-4359, +-7239, +-4367, +-7228, +-4375, +-7217, +-4382, +-7206, +-4390, +-7195, +-4398, +-7184, +-4406, +-7174, +-4413, +-7163, +-4421, +-7152, +-4429, +-7141, +-4437, +-7130, +-4444, +-7119, +-4452, +-7109, +-4460, +-7098, +-4468, +-7087, +-4476, +-7076, +-4483, +-7066, +-4491, +-7055, +-4499, +-7044, +-4507, +-7033, +-4515, +-7023, +-4523, +-7012, +-4531, +-7001, +-4539, +-6991, +-4546, +-6980, +-4554, +-6969, +-4562, +-6959, +-4570, +-6948, +-4578, +-6938, +-4586, +-6927, +-4594, +-6916, +-4602, +-6906, +-4610, +-6895, +-4618, +-6885, +-4626, +-6874, +-4634, +-6864, +-4642, +-6853, +-4650, +-6842, +-4658, +-6832, +-4666, +-6821, +-4674, +-6811, +-4682, +-6801, +-4690, +-6790, +-4699, +-6780, +-4707, +-6769, +-4715, +-6759, +-4723, +-6748, +-4731, +-6738, +-4739, +-6728, +-4747, +-6717, +-4756, +-6707, +-4764, +-6696, +-4772, +-6686, +-4780, +-6676, +-4788, +-6665, +-4796, +-6655, +-4805, +-6645, +-4813, +-6635, +-4821, +-6624, +-4829, +-6614, +-4838, +-6604, +-4846, +-6593, +-4854, +-6583, +-4863, +-6573, +-4871, +-6563, +-4879, +-6553, +-4887, +-6542, +-4896, +-6532, +-4904, +-6522, +-4912, +-6512, +-4921, +-6502, +-4929, +-6492, +-4938, +-6481, +-4946, +-6471, +-4954, +-6461, +-4963, +-6451, +-4971, +-6441, +-4980, +-6431, +-4988, +-6421, +-4997, +-6411, +-5005, +-6401, +-5013, +-6391, +-5022, +-6381, +-5030, +-6371, +-5039, +-6361, +-5047, +-6351, +-5056, +-6341, +-5064, +-6331, +-5073, +-6321, +-5082, +-6311, +-5090, +-6301, +-5099, +-6291, +-5107, +-6281, +-5116, +-6271, +-5124, +-6261, +-5133, +-6251, +-5142, +-6241, +-5150, +-6232, +-5159, +-6222, +-5168, +-6212, +-5176, +-6202, +-5185, +-6192, +-5194, +-6182, +-5202, +-6173, +-5211, +-6163, +-5220, +-6153, +-5229, +-6143, +-5237, +-6134, +-5246, +-6124, +-5255, +-6114, +-5264, +-6104, +-5272, +-6095, +-5281, +-6085, +-5290, +-6075, +-5299, +-6066, +-5307, +-6056, +-5316, +-6046, +-5325, +-6037, +-5334, +-6027, +-5343, +-6017, +-5352, +-6008, +-5361, +-5998, +-5369, +-5989, +-5378, +-5979, +-5387, +-5969, +-5396, +-5960, +-5405, +-5950, +-5414, +-5941, +-5423, +-5931, +-5432, +-5922, +-5441, +-5912, +-5450, +-5903, +-5459, +-5893, +-5468, +-5884, +-5477, +-5874, +-5486, +-5865, +-5495, +-5855, +-5504, +-5846, +-5513, +-5836, +-5522, +-5827, +-5531, +-5818, +-5540, +-5808, +-5549, +-5799, +-5558, +-5789, +-5568, +-5780, +-5577, +-5771, +-5586, +-5761, +-5595, +-5752, +-5604, +-5743, +-5613, +-5733, +-5622, +-5724, +-5632, +-5715, +-5641, +-5706, +-5650, +-5696, +-5659, +-5687, +-5669, +-5678, +-5678, +-5669, +-5687, +-5659, +-5696, +-5650, +-5706, +-5641, +-5715, +-5632, +-5724, +-5622, +-5733, +-5613, +-5743, +-5604, +-5752, +-5595, +-5761, +-5586, +-5771, +-5577, +-5780, +-5568, +-5789, +-5558, +-5799, +-5549, +-5808, +-5540, +-5818, +-5531, +-5827, +-5522, +-5836, +-5513, +-5846, +-5504, +-5855, +-5495, +-5865, +-5486, +-5874, +-5477, +-5884, +-5468, +-5893, +-5459, +-5903, +-5450, +-5912, +-5441, +-5922, +-5432, +-5931, +-5423, +-5941, +-5414, +-5950, +-5405, +-5960, +-5396, +-5969, +-5387, +-5979, +-5378, +-5989, +-5369, +-5998, +-5361, +-6008, +-5352, +-6017, +-5343, +-6027, +-5334, +-6037, +-5325, +-6046, +-5316, +-6056, +-5307, +-6066, +-5299, +-6075, +-5290, +-6085, +-5281, +-6095, +-5272, +-6104, +-5264, +-6114, +-5255, +-6124, +-5246, +-6134, +-5237, +-6143, +-5229, +-6153, +-5220, +-6163, +-5211, +-6173, +-5202, +-6182, +-5194, +-6192, +-5185, +-6202, +-5176, +-6212, +-5168, +-6222, +-5159, +-6232, +-5150, +-6241, +-5142, +-6251, +-5133, +-6261, +-5124, +-6271, +-5116, +-6281, +-5107, +-6291, +-5099, +-6301, +-5090, +-6311, +-5082, +-6321, +-5073, +-6331, +-5064, +-6341, +-5056, +-6351, +-5047, +-6361, +-5039, +-6371, +-5030, +-6381, +-5022, +-6391, +-5013, +-6401, +-5005, +-6411, +-4997, +-6421, +-4988, +-6431, +-4980, +-6441, +-4971, +-6451, +-4963, +-6461, +-4954, +-6471, +-4946, +-6481, +-4938, +-6492, +-4929, +-6502, +-4921, +-6512, +-4912, +-6522, +-4904, +-6532, +-4896, +-6542, +-4887, +-6553, +-4879, +-6563, +-4871, +-6573, +-4863, +-6583, +-4854, +-6593, +-4846, +-6604, +-4838, +-6614, +-4829, +-6624, +-4821, +-6635, +-4813, +-6645, +-4805, +-6655, +-4796, +-6665, +-4788, +-6676, +-4780, +-6686, +-4772, +-6696, +-4764, +-6707, +-4756, +-6717, +-4747, +-6728, +-4739, +-6738, +-4731, +-6748, +-4723, +-6759, +-4715, +-6769, +-4707, +-6780, +-4699, +-6790, +-4690, +-6801, +-4682, +-6811, +-4674, +-6821, +-4666, +-6832, +-4658, +-6842, +-4650, +-6853, +-4642, +-6864, +-4634, +-6874, +-4626, +-6885, +-4618, +-6895, +-4610, +-6906, +-4602, +-6916, +-4594, +-6927, +-4586, +-6938, +-4578, +-6948, +-4570, +-6959, +-4562, +-6969, +-4554, +-6980, +-4546, +-6991, +-4539, +-7001, +-4531, +-7012, +-4523, +-7023, +-4515, +-7033, +-4507, +-7044, +-4499, +-7055, +-4491, +-7066, +-4483, +-7076, +-4476, +-7087, +-4468, +-7098, +-4460, +-7109, +-4452, +-7119, +-4444, +-7130, +-4437, +-7141, +-4429, +-7152, +-4421, +-7163, +-4413, +-7174, +-4406, +-7184, +-4398, +-7195, +-4390, +-7206, +-4382, +-7217, +-4375, +-7228, +-4367, +-7239, +-4359, +-7250, +-4352, +-7261, +-4344, +-7272, +-4336, +-7283, +-4329, +-7294, +-4321, +-7305, +-4313, +-7316, +-4306, +-7327, +-4298, +-7338, +-4291, +-7349, +-4283, +-7360, +-4275, +-7371, +-4268, +-7382, +-4260, +-7393, +-4253, +-7404, +-4245, +-7415, +-4238, +-7426, +-4230, +-7437, +-4223, +-7448, +-4215, +-7459, +-4208, +-7471, +-4200, +-7482, +-4193, +-7493, +-4185, +-7504, +-4178, +-7515, +-4170, +-7527, +-4163, +-7538, +-4155, +-7549, +-4148, +-7560, +-4141, +-7571, +-4133, +-7583, +-4126, +-7594, +-4118, +-7605, +-4111, +-7617, +-4104, +-7628, +-4096, +-7639, +-4089, +-7651, +-4082, +-7662, +-4074, +-7673, +-4067, +-7685, +-4060, +-7696, +-4052, +-7707, +-4045, +-7719, +-4038, +-7730, +-4031, +-7742, +-4023, +-7753, +-4016, +-7764, +-4009, +-7776, +-4002, +-7787, +-3994, +-7799, +-3987, +-7810, +-3980, +-7822, +-3973, +-7833, +-3966, +-7845, +-3958, +-7856, +-3951, +-7868, +-3944, +-7880, +-3937, +-7891, +-3930, +-7903, +-3923, +-7914, +-3916, +-7926, +-3909, +-7937, +-3901, +-7949, +-3894, +-7961, +-3887, +-7972, +-3880, +-7984, +-3873, +-7996, +-3866, +-8007, +-3859, +-8019, +-3852, +-8031, +-3845, +-8043, +-3838, +-8054, +-3831, +-8066, +-3824, +-8078, +-3817, +-8090, +-3810, +-8101, +-3803, +-8113, +-3796, +-8125, +-3789, +-8137, +-3782, +-8148, +-3775, +-8160, +-3768, +-8172, +-3761, +-8184, +-3754, +-8196, +-3748, +-8208, +-3741, +-8220, +-3734, +-8232, +-3727, +-8243, +-3720, +-8255, +-3713, +-8267, +-3706, +-8279, +-3699, +-8291, +-3693, +-8303, +-3686, +-8315, +-3679, +-8327, +-3672, +-8339, +-3665, +-8351, +-3659, +-8363, +-3652, +-8375, +-3645, +-8387, +-3638, +-8399, +-3632, +-8411, +-3625, +-8424, +-3618, +-8436, +-3611, +-8448, +-3605, +-8460, +-3598, +-8472, +-3591, +-8484, +-3585, +-8496, +-3578, +-8508, +-3571, +-8521, +-3565, +-8533, +-3558, +-8545, +-3551, +-8557, +-3545, +-8569, +-3538, +-8582, +-3532, +-8594, +-3525, +-8606, +-3518, +-8619, +-3512, +-8631, +-3505, +-8643, +-3499, +-8655, +-3492, +-8668, +-3486, +-8680, +-3479, +-8692, +-3472, +-8705, +-3466, +-8717, +-3459, +-8729, +-3453, +-8742, +-3446, +-8754, +-3440, +-8767, +-3433, +-8779, +-3427, +-8792, +-3421, +-8804, +-3414, +-8816, +-3408, +-8829, +-3401, +-8841, +-3395, +-8854, +-3388, +-8866, +-3382, +-8879, +-3376, +-8891, +-3369, +-8904, +-3363, +-8917, +-3356, +-8929, +-3350, +-8942, +-3344, +-8954, +-3337, +-8967, +-3331, +-8980, +-3325, +-8992, +-3318, +-9005, +-3312, +-9017, +-3306, +-9030, +-3299, +-9043, +-3293, +-9055, +-3287, +-9068, +-3281, +-9081, +-3274, +-9094, +-3268, +-9106, +-3262, +-9119, +-3256, +-9132, +-3249, +-9145, +-3243, +-9157, +-3237, +-9170, +-3231, +-9183, +-3225, +-9196, +-3218, +-9209, +-3212, +-9221, +-3206, +-9234, +-3200, +-9247, +-3194, +-9260, +-3188, +-9273, +-3182, +-9286, +-3175, +-9299, +-3169, +-9312, +-3163, +-9325, +-3157, +-9337, +-3151, +-9350, +-3145, +-9363, +-3139, +-9376, +-3133, +-9389, +-3127, +-9402, +-3121, +-9415, +-3115, +-9428, +-3109, +-9441, +-3103, +-9454, +-3097, +-9468, +-3091, +-9481, +-3085, +-9494, +-3079, +-9507, +-3073, +-9520, +-3067, +-9533, +-3061, +-9546, +-3055, +-9559, +-3049, +-9572, +-3043, +-9586, +-3037, +-9599, +-3031, +-9612, +-3025, +-9625, +-3019, +-9638, +-3013, +-9652, +-3008, +-9665, +-3002, +-9678, +-2996, +-9691, +-2990, +-9705, +-2984, +-9718, +-2978, +-9731, +-2972, +-9745, +-2967, +-9758, +-2961, +-9771, +-2955, +-9785, +-2949, +-9798, +-2943, +-9811, +-2938, +-9825, +-2932, +-9838, +-2926, +-9852, +-2920, +-9865, +-2915, +-9878, +-2909, +-9892, +-2903, +-9905, +-2897, +-9919, +-2892, +-9932, +-2886, +-9946, +-2880, +-9959, +-2875, +-9973, +-2869, +-9986, +-2863, +-10000, +-2857, +-10013, +-2852, +-10027, +-2846, +-10041, +-2841, +-10054, +-2835, +-10068, +-2829, +-10081, +-2824, +-10095, +-2818, +-10109, +-2812, +-10122, +-2807, +-10136, +-2801, +-10150, +-2796, +-10163, +-2790, +-10177, +-2785, +-10191, +-2779, +-10205, +-2773, +-10218, +-2768, +-10232, +-2762, +-10246, +-2757, +-10260, +-2751, +-10273, +-2746, +-10287, +-2740, +-10301, +-2735, +-10315, +-2729, +-10329, +-2724, +-10342, +-2719, +-10356, +-2713, +-10370, +-2708, +-10384, +-2702, +-10398, +-2697, +-10412, +-2691, +-10426, +-2686, +-10440, +-2680, +-10454, +-2675, +-10468, +-2670, +-10482, +-2664, +-10496, +-2659, +-10510, +-2654, +-10524, +-2648, +-10538, +-2643, +-10552, +-2638, +-10566, +-2632, +-10580, +-2627, +-10594, +-2622, +-10608, +-2616, +-10622, +-2611, +-10636, +-2606, +-10650, +-2600, +-10664, +-2595, +-10678, +-2590, +-10693, +-2585, +-10707, +-2579, +-10721, +-2574, +-10735, +-2569, +-10749, +-2564, +-10764, +-2558, +-10778, +-2553, +-10792, +-2548, +-10806, +-2543, +-10821, +-2538, +-10835, +-2532, +-10849, +-2527, +-10863, +-2522, +-10878, +-2517, +-10892, +-2512, +-10906, +-2507, +-10921, +-2501, +-10935, +-2496, +-10949, +-2491, +-10964, +-2486, +-10978, +-2481, +-10993, +-2476, +-11007, +-2471, +-11022, +-2466, +-11036, +-2461, +-11050, +-2456, +-11065, +-2451, +-11079, +-2445, +-11094, +-2440, +-11108, +-2435, +-11123, +-2430, +-11137, +-2425, +-11152, +-2420, +-11167, +-2415, +-11181, +-2410, +-11196, +-2405, +-11210, +-2400, +-11225, +-2395, +-11240, +-2390, +-11254, +-2385, +-11269, +-2381, +-11283, +-2376, +-11298, +-2371, +-11313, +-2366, +-11328, +-2361, +-11342, +-2356, +-11357, +-2351, +-11372, +-2346, +-11386, +-2341, +-11401, +-2336, +-11416, +-2331, +-11431, +-2327, +-11446, +-2322, +-11460, +-2317, +-11475, +-2312, +-11490, +-2307, +-11505, +-2302, +-11520, +-2298, +-11535, +-2293, +-11549, +-2288, +-11564, +-2283, +-11579, +-2278, +-11594, +-2274, +-11609, +-2269, +-11624, +-2264, +-11639, +-2259, +-11654, +-2254, +-11669, +-2250, +-11684, +-2245, +-11699, +-2240, +-11714, +-2236, +-11729, +-2231, +-11744, +-2226, +-11759, +-2221, +-11774, +-2217, +-11789, +-2212, +-11804, +-2207, +-11819, +-2203, +-11835, +-2198, +-11850, +-2193, +-11865, +-2189, +-11880, +-2184, +-11895, +-2179, +-11910, +-2175, +-11926, +-2170, +-11941, +-2166, +-11956, +-2161, +-11971, +-2156, +-11986, +-2152, +-12002, +-2147, +-12017, +-2143, +-12032, +-2138, +-12048, +-2133, +-12063, +-2129, +-12078, +-2124, +-12094, +-2120, +-12109, +-2115, +-12124, +-2111, +-12140, +-2106, +-12155, +-2102, +-12170, +-2097, +-12186, +-2093, +-12201, +-2088, +-12217, +-2084, +-12232, +-2079, +-12248, +-2075, +-12263, +-2070, +-12279, +-2066, +-12294, +-2062, +-12310, +-2057, +-12325, +-2053, +-12341, +-2048, +-12356, +-2044, +-12372, +-2039, +-12387, +-2035, +-12403, +-2031, +-12418, +-2026, +-12434, +-2022, +-12450, +-2017, +-12465, +-2013, +-12481, +-2009, +-12497, +-2004, +-12512, +-2000, +-12528, +-1996, +-12544, +-1991, +-12559, +-1987, +-12575, +-1983, +-12591, +-1978, +-12607, +-1974, +-12622, +-1970, +-12638, +-1966, +-12654, +-1961, +-12670, +-1957, +-12686, +-1953, +-12701, +-1948, +-12717, +-1944, +-12733, +-1940, +-12749, +-1936, +-12765, +-1931, +-12781, +-1927, +-12797, +-1923, +-12813, +-1919, +-12828, +-1915, +-12844, +-1910, +-12860, +-1906, +-12876, +-1902, +-12892, +-1898, +-12908, +-1894, +-12924, +-1890, +-12940, +-1885, +-12956, +-1881, +-12972, +-1877, +-12988, +-1873, +-13005, +-1869, +-13021, +-1865, +-13037, +-1861, +-13053, +-1857, +-13069, +-1852, +-13085, +-1848, +-13101, +-1844, +-13117, +-1840, +-13134, +-1836, +-13150, +-1832, +-13166, +-1828, +-13182, +-1824, +-13198, +-1820, +-13215, +-1816, +-13231, +-1812, +-13247, +-1808, +-13263, +-1804, +-13280, +-1800, +-13296, +-1796, +-13312, +-1792, +-13329, +-1788, +-13345, +-1784, +-13361, +-1780, +-13378, +-1776, +-13394, +-1772, +-13410, +-1768, +-13427, +-1764, +-13443, +-1760, +-13460, +-1756, +-13476, +-1752, +-13493, +-1748, +-13509, +-1744, +-13525, +-1740, +-13542, +-1736, +-13558, +-1733, +-13575, +-1729, +-13592, +-1725, +-13608, +-1721, +-13625, +-1717, +-13641, +-1713, +-13658, +-1709, +-13674, +-1706, +-13691, +-1702, +-13708, +-1698, +-13724, +-1694, +-13741, +-1690, +-13758, +-1686, +-13774, +-1683, +-13791, +-1679, +-13808, +-1675, +-13824, +-1671, +-13841, +-1667, +-13858, +-1664, +-13875, +-1660, +-13891, +-1656, +-13908, +-1652, +-13925, +-1649, +-13942, +-1645, +-13958, +-1641, +-13975, +-1637, +-13992, +-1634, +-14009, +-1630, +-14026, +-1626, +-14043, +-1622, +-14060, +-1619, +-14077, +-1615, +-14093, +-1611, +-14110, +-1608, +-14127, +-1604, +-14144, +-1600, +-14161, +-1597, +-14178, +-1593, +-14195, +-1589, +-14212, +-1586, +-14229, +-1582, +-14246, +-1579, +-14263, +-1575, +-14280, +-1571, +-14297, +-1568, +-14315, +-1564, +-14332, +-1560, +-14349, +-1557, +-14366, +-1553, +-14383, +-1550, +-14400, +-1546, +-14417, +-1543, +-14435, +-1539, +-14452, +-1535, +-14469, +-1532, +-14486, +-1528, +-14503, +-1525, +-14521, +-1521, +-14538, +-1518, +-14555, +-1514, +-14572, +-1511, +-14590, +-1507, +-14607, +-1504, +-14624, +-1500, +-14642, +-1497, +-14659, +-1493, +-14676, +-1490, +-14694, +-1486, +-14711, +-1483, +-14729, +-1479, +-14746, +-1476, +-14763, +-1473, +-14781, +-1469, +-14798, +-1466, +-14816, +-1462, +-14833, +-1459, +-14851, +-1455, +-14868, +-1452, +-14886, +-1449, +-14903, +-1445, +-14921, +-1442, +-14938, +-1439, +-14956, +-1435, +-14973, +-1432, +-14991, +-1428, +-15009, +-1425, +-15026, +-1422, +-15044, +-1418, +-15062, +-1415, +-15079, +-1412, +-15097, +-1408, +-15115, +-1405, +-15132, +-1402, +-15150, +-1398, +-15168, +-1395, +-15186, +-1392, +-15203, +-1389, +-15221, +-1385, +-15239, +-1382, +-15257, +-1379, +-15274, +-1376, +-15292, +-1372, +-15310, +-1369, +-15328, +-1366, +-15346, +-1363, +-15364, +-1359, +-15382, +-1356, +-15399, +-1353, +-15417, +-1350, +-15435, +-1346, +-15453, +-1343, +-15471, +-1340, +-15489, +-1337, +-15507, +-1334, +-15525, +-1330, +-15543, +-1327, +-15561, +-1324, +-15579, +-1321, +-15597, +-1318, +-15615, +-1315, +-15633, +-1311, +-15651, +-1308, +-15669, +-1305, +-15688, +-1302, +-15706, +-1299, +-15724, +-1296, +-15742, +-1293, +-15760, +-1290, +-15778, +-1287, +-15796, +-1283, +-15815, +-1280, +-15833, +-1277, +-15851, +-1274, +-15869, +-1271, +-15888, +-1268, +-15906, +-1265, +-15924, +-1262, +-15942, +-1259, +-15961, +-1256, +-15979, +-1253, +-15997, +-1250, +-16016, +-1247, +-16034, +-1244, +-16053, +-1241, +-16071, +-1238, +-16089, +-1235, +-16108, +-1232, +-16126, +-1229, +-16145, +-1226, +-16163, +-1223, +-16182, +-1220, +-16200, +-1217, +-16218, +-1214, +-16237, +-1211, +-16256, +-1208, +-16274, +-1205, +-16293, +-1202, +-16311, +-1199, +-16330, +-1196, +-16348, +-1193, +-16367, +-1190, +-16386, +-1188, +-16404, +-1185, +-16423, +-1182, +-16441, +-1179, +-16460, +-1176, +-16479, +-1173, +-16497, +-1170, +-16516, +-1167, +-16535, +-1164, +-16554, +-1162, +-16572, +-1159, +-16591, +-1156, +-16610, +-1153, +-16629, +-1150, +-16647, +-1147, +-16666, +-1145, +-16685, +-1142, +-16704, +-1139, +-16723, +-1136, +-16742, +-1133, +-16761, +-1130, +-16779, +-1128, +-16798, +-1125, +-16817, +-1122, +-16836, +-1119, +-16855, +-1117, +-16874, +-1114, +-16893, +-1111, +-16912, +-1108, +-16931, +-1105, +-16950, +-1103, +-16969, +-1100, +-16988, +-1097, +-17007, +-1095, +-17026, +-1092, +-17045, +-1089, +-17064, +-1086, +-17084, +-1084, +-17103, +-1081, +-17122, +-1078, +-17141, +-1076, +-17160, +-1073, +-17179, +-1070, +-17198, +-1068, +-17218, +-1065, +-17237, +-1062, +-17256, +-1060, +-17275, +-1057, +-17295, +-1054, +-17314, +-1052, +-17333, +-1049, +-17352, +-1046, +-17372, +-1044, +-17391, +-1041, +-17410, +-1038, +-17430, +-1036, +-17449, +-1033, +-17469, +-1031, +-17488, +-1028, +-17507, +-1025, +-17527, +-1023, +-17546, +-1020, +-17566, +-1018, +-17585, +-1015, +-17605, +-1013, +-17624, +-1010, +-17643, +-1007, +-17663, +-1005, +-17683, +-1002, +-17702, +-1000, +-17722, +-997, +-17741, +-995, +-17761, +-992, +-17780, +-990, +-17800, +-987, +-17820, +-985, +-17839, +-982, +-17859, +-980, +-17879, +-977, +-17898, +-975, +-17918, +-972, +-17938, +-970, +-17957, +-967, +-17977, +-965, +-17997, +-962, +-18016, +-960, +-18036, +-957, +-18056, +-955, +-18076, +-952, +-18096, +-950, +-18115, +-948, +-18135, +-945, +-18155, +-943, +-18175, +-940, +-18195, +-938, +-18215, +-935, +-18235, +-933, +-18255, +-931, +-18275, +-928, +-18294, +-926, +-18314, +-923, +-18334, +-921, +-18354, +-919, +-18374, +-916, +-18394, +-914, +-18414, +-912, +-18434, +-909, +-18454, +-907, +-18475, +-905, +-18495, +-902, +-18515, +-900, +-18535, +-897, +-18555, +-895, +-18575, +-893, +-18595, +-891, +-18615, +-888, +-18636, +-886, +-18656, +-884, +-18676, +-881, +-18696, +-879, +-18716, +-877, +-18737, +-874, +-18757, +-872, +-18777, +-870, +-18797, +-868, +-18818, +-865, +-18838, +-863, +-18858, +-861, +-18879, +-859, +-18899, +-856, +-18919, +-854, +-18940, +-852, +-18960, +-850, +-18981, +-847, +-19001, +-845, +-19021, +-843, +-19042, +-841, +-19062, +-838, +-19083, +-836, +-19103, +-834, +-19124, +-832, +-19144, +-830, +-19165, +-827, +-19185, +-825, +-19206, +-823, +-19226, +-821, +-19247, +-819, +-19268, +-817, +-19288, +-814, +-19309, +-812, +-19330, +-810, +-19350, +-808, +-19371, +-806, +-19392, +-804, +-19412, +-802, +-19433, +-799, +-19454, +-797, +-19474, +-795, +-19495, +-793, +-19516, +-791, +-19537, +-789, +-19557, +-787, +-19578, +-785, +-19599, +-783, +-19620, +-781, +-19641, +-778, +-19662, +-776, +-19682, +-774, +-19703, +-772, +-19724, +-770, +-19745, +-768, +-19766, +-766, +-19787, +-764, +-19808, +-762, +-19829, +-760, +-19850, +-758, +-19871, +-756, +-19892, +-754, +-19913, +-752, +-19934, +-750, +-19955, +-748, +-19976, +-746, +-19997, +-744, +-20018, +-742, +-20039, +-740, +-20060, +-738, +-20082, +-736, +-20103, +-734, +-20124, +-732, +-20145, +-730, +-20166, +-728, +-20187, +-726, +-20209, +-724, +-20230, +-722, +-20251, +-720, +-20272, +-718, +-20294, +-716, +-20315, +-714, +-20336, +-712, +-20357, +-710, +-20379, +-708, +-20400, +-706, +-20421, +-704, +-20443, +-703, +-20464, +-701, +-20486, +-699, +-20507, +-697, +-20528, +-695, +-20550, +-693, +-20571, +-691, +-20593, +-689, +-20614, +-687, +-20636, +-685, +-20657, +-684, +-20679, +-682, +-20700, +-680, +-20722, +-678, +-20743, +-676, +-20765, +-674, +-20787, +-672, +-20808, +-671, +-20830, +-669, +-20851, +-667, +-20873, +-665, +-20895, +-663, +-20916, +-661, +-20938, +-660, +-20960, +-658, +-20981, +-656, +-21003, +-654, +-21025, +-652, +-21047, +-650, +-21068, +-649, +-21090, +-647, +-21112, +-645, +-21134, +-643, +-21156, +-642, +-21177, +-640, +-21199, +-638, +-21221, +-636, +-21243, +-634, +-21265, +-633, +-21287, +-631, +-21309, +-629, +-21331, +-627, +-21353, +-626, +-21375, +-624, +-21396, +-622, +-21418, +-620, +-21440, +-619, +-21462, +-617, +-21485, +-615, +-21507, +-614, +-21529, +-612, +-21551, +-610, +-21573, +-608, +-21595, +-607, +-21617, +-605, +-21639, +-603, +-21661, +-602, +-21683, +-600, +-21706, +-598, +-21728, +-597, +-21750, +-595, +-21772, +-593, +-21794, +-592, +-21817, +-590, +-21839, +-588, +-21861, +-587, +-21883, +-585, +-21906, +-583, +-21928, +-582, +-21950, +-580, +-21973, +-578, +-21995, +-577, +-22017, +-575, +-22040, +-573, +-22062, +-572, +-22084, +-570, +-22107, +-569, +-22129, +-567, +-22152, +-565, +-22174, +-564, +-22197, +-562, +-22219, +-561, +-22242, +-559, +-22264, +-557, +-22287, +-556, +-22309, +-554, +-22332, +-553, +-22354, +-551, +-22377, +-549, +-22400, +-548, +-22422, +-546, +-22445, +-545, +-22467, +-543, +-22490, +-542, +-22513, +-540, +-22535, +-539, +-22558, +-537, +-22581, +-536, +-22604, +-534, +-22626, +-532, +-22649, +-531, +-22672, +-529, +-22695, +-528, +-22717, +-526, +-22740, +-525, +-22763, +-523, +-22786, +-522, +-22809, +-520, +-22832, +-519, +-22854, +-517, +-22877, +-516, +-22900, +-514, +-22923, +-513, +-22946, +-511, +-22969, +-510, +-22992, +-508, +-23015, +-507, +-23038, +-505, +-23061, +-504, +-23084, +-503, +-23107, +-501, +-23130, +-500, +-23153, +-498, +-23176, +-497, +-23199, +-495, +-23222, +-494, +-23245, +-492, +-23269, +-491, +-23292, +-490, +-23315, +-488, +-23338, +-487, +-23361, +-485, +-23384, +-484, +-23408, +-482, +-23431, +-481, +-23454, +-480, +-23477, +-478, +-23501, +-477, +-23524, +-475, +-23547, +-474, +-23571, +-473, +-23594, +-471, +-23617, +-470, +-23641, +-469, +-23664, +-467, +-23687, +-466, +-23711, +-464, +-23734, +-463, +-23758, +-462, +-23781, +-460, +-23804, +-459, +-23828, +-458, +-23851, +-456, +-23875, +-455, +-23898, +-454, +-23922, +-452, +-23945, +-451, +-23969, +-450, +-23993, +-448, +-24016, +-447, +-24040, +-446, +-24063, +-444, +-24087, +-443, +-24111, +-442, +-24134, +-440, +-24158, +-439, +-24182, +-438, +-24205, +-436, +-24229, +-435, +-24253, +-434, +-24276, +-433, +-24300, +-431, +-24324, +-430, +-24348, +-429, +-24372, +-427, +-24395, +-426, +-24419, +-425, +-24443, +-424, +-24467, +-422, +-24491, +-421, +-24515, +-420, +-24538, +-419, +-24562, +-417, +-24586, +-416, +-24610, +-415, +-24634, +-414, +-24658, +-412, +-24682, +-411, +-24706, +-410, +-24730, +-409, +-24754, +-407, +-24778, +-406, +-24802, +-405, +-24826, +-404, +-24850, +-402, +-24874, +-401, +-24898, +-400, +-24923, +-399, +-24947, +-398, +-24971, +-396, +-24995, +-395, +-25019, +-394, +-25043, +-393, +-25068, +-392, +-25092, +-390, +-25116, +-389, +-25140, +-388, +-25165, +-387, +-25189, +-386, +-25213, +-385, +-25237, +-383, +-25262, +-382, +-25286, +-381, +-25310, +-380, +-25335, +-379, +-25359, +-378, +-25383, +-376, +-25408, +-375, +-25432, +-374, +-25457, +-373, +-25481, +-372, +-25506, +-371, +-25530, +-370, +-25555, +-369, +-25579, +-367, +-25604, +-366, +-25628, +-365, +-25653, +-364, +-25677, +-363, +-25702, +-362, +-25726, +-361, +-25751, +-360, +-25776, +-358, +-25800, +-357, +-25825, +-356, +-25849, +-355, +-25874, +-354, +-25899, +-353, +-25924, +-352, +-25948, +-351, +-25973, +-350, +-25998, +-349, +-26022, +-348, +-26047, +-347, +-26072, +-345, +-26097, +-344, +-26122, +-343, +-26146, +-342, +-26171, +-341, +-26196, +-340, +-26221, +-339, +-26246, +-338, +-26271, +-337, +-26296, +-336, +-26321, +-335, +-26346, +-334, +-26370, +-333, +-26395, +-332, +-26420, +-331, +-26445, +-330, +-26470, +-329, +-26495, +-328, +-26520, +-327, +-26546, +-326, +-26571, +-325, +-26596, +-324, +-26621, +-323, +-26646, +-322, +-26671, +-321, +-26696, +-320, +-26721, +-319, +-26746, +-318, +-26772, +-317, +-26797, +-316, +-26822, +-315, +-26847, +-314, +-26873, +-313, +-26898, +-312, +-26923, +-311, +-26948, +-310, +-26974, +-309, +-26999, +-308, +-27024, +-307, +-27050, +-306, +-27075, +-305, +-27100, +-304, +-27126, +-303, +-27151, +-302, +-27176, +-301, +-27202, +-300, +-27227, +-299, +-27253, +-298, +-27278, +-297, +-27304, +-296, +-27329, +-295, +-27355, +-294, +-27380, +-293, +-27406, +-292, +-27431, +-292, +-27457, +-291, +-27483, +-290, +-27508, +-289, +-27534, +-288, +-27559, +-287, +-27585, +-286, +-27611, +-285, +-27636, +-284, +-27662, +-283, +-27688, +-282, +-27713, +-281, +-27739, +-281, +-27765, +-280, +-27791, +-279, +-27816, +-278, +-27842, +-277, +-27868, +-276, +-27894, +-275, +-27920, +-274, +-27945, +-273, +-27971, +-273, +-27997, +-272, +-28023, +-271, +-28049, +-270, +-28075, +-269, +-28101, +-268, +-28127, +-267, +-28153, +-267, +-28179, +-266, +-28205, +-265, +-28231, +-264, +-28257, +-263, +-28283, +-262, +-28309, +-261, +-28335, +-261, +-28361, +-260, +-28387, +-259, +-28413, +-258, +-28439, +-257, +-28465, +-256, +-28491, +-256, +-28518, +-255, +-28544, +-254, +-28570, +-253, +-28596, +-252, +-28622, +-251, +-28649, +-251, +-28675, +-250, +-28701, +-249, +-28727, +-248, +-28754, +-247, +-28780, +-247, +-28806, +-246, +-28832, +-245, +-28859, +-244, +-28885, +-243, +-28912, +-243, +-28938, +-242, +-28964, +-241, +-28991, +-240, +-29017, +-239, +-29044, +-239, +-29070, +-238, +-29097, +-237, +-29123, +-236, +-29150, +-235, +-29176, +-235, +-29203, +-234, +-29229, +-233, +-29256, +-232, +-29282, +-232, +-29309, +-231, +-29335, +-230, +-29362, +-229, +-29389, +-229, +-29415, +-228, +-29442, +-227, +-29469, +-226, +-29495, +-226, +-29522, +-225, +-29549, +-224, +-29576, +-223, +-29602, +-223, +-29629, +-222, +-29656, +-221, +-29683, +-220, +-29709, +-220, +-29736, +-219, +-29763, +-218, +-29790, +-217, +-29817, +-217, +-29844, +-216, +-29871, +-215, +-29897, +-215, +-29924, +-214, +-29951, +-213, +-29978, +-212, +-30005, +-212, +-30032, +-211, +-30059, +-210, +-30086, +-210, +-30113, +-209, +-30140, +-208, +-30167, +-208, +-30194, +-207, +-30221, +-206, +-30249, +-205, +-30276, +-205, +-30303, +-204, +-30330, +-203, +-30357, +-203, +-30384, +-202, +-30411, +-201, +-30439, +-201, +-30466, +-200, +-30493, +-199, +-30520, +-199, +-30547, +-198, +-30575, +-197, +-30602, +-197, +-30629, +-196, +-30657, +-195, +-30684, +-195, +-30711, +-194, +-30739, +-193, +-30766, +-193, +-30793, +-192, +-30821, +-191, +-30848, +-191, +-30876, +-190, +-30903, +-189, +-30931, +-189, +-30958, +-188, +-30985, +-188, +-31013, +-187, +-31040, +-186, +-31068, +-186, +-31096, +-185, +-31123, +-184, +-31151, +-184, +-31178, +-183, +-31206, +-182, +-31233, +-182, +-31261, +-181, +-31289, +-181, +-31316, +-180, +-31344, +-179, +-31372, +-179, +-31399, +-178, +-31427, +-178, +-31455, +-177, +-31483, +-176, +-31510, +-176, +-31538, +-175, +-31566, +-175, +-31594, +-174, +-31622, +-173, +-31649, +-173, +-31677, +-172, +-31705, +-172, +-31733, +-171, +-31761, +-170, +-31789, +-170, +-31817, +-169, +-31845, +-169, +-31873, +-168, +-31901, +-167, +-31929, +-167, +-31957, +-166, +-31985, +-166, +-32013, +-165, +-32041, +-165, +-32069, +-164, +-32097, +-163, +-32125, +-163, +-32153, +-162, +-32181, +-162, +-32209, +-161, +-32237, +-161, +-32265, +-160, +-32294, +-159, +-32322, +-159, +-32350, +-158, +-32378, +-158, +-32406, +-157, +-32435, +-157, +-32463, +-156, +-32491, +-156, +-32519, +-155, +-32548, +-155, +-32576, +-154, +-32604, +-153, +-32633, +-153, +-32661, +-152, +-32689, +-152, +-32718, +-151, +-32746, +-151, +-32775, +-150, +-32803, +-150, +-32832, +-149, +-32860, +-149, +-32888, +-148, +-32917, +-148, +-32945, +-147, +-32974, +-147, +-33003, +-146, +-33031, +-146, +-33060, +-145, +-33088, +-145, +-33117, +-144, +-33145, +-144, +-33174, +-143, +-33203, +-143, +-33231, +-142, +-33260, +-142, +-33289, +-141, +-33317, +-141, +-33346, +-140, +-33375, +-140, +-33404, +-139, +-33432, +-139, +-33461, +-138, +-33490, +-138, +-33519, +-137, +-33547, +-137, +-33576, +-136, +-33605, +-136, +-33634, +-135, +-33663, +-135, +-33692, +-134, +-33721, +-134, +-33750, +-133, +-33778, +-133, +-33807, +-132, +-33836, +-132, +-33865, +-131, +-33894, +-131, +-33923, +-130, +-33952, +-130, +-33981, +-129, +-34010, +-129, +-34039, +-129, +-34069, +-128, +-34098, +-128, +-34127, +-127, +-34156, +-127, +-34185, +-126, +-34214, +-126, +-34243, +-125, +-34272, +-125, +-34302, +-124, +-34331, +-124, +-34360, +-124, +-34389, +-123, +-34419, +-123, +-34448, +-122, +-34477, +-122, +-34506, +-121, +-34536, +-121, +-34565, +-120, +-34594, +-120, +-34624, +-120, +-34653, +-119, +-34682, +-119, +-34712, +-118, +-34741, +-118, +-34771, +-117, +-34800, +-117, +-34830, +-117, +-34859, +-116, +-34889, +-116, +-34918, +-115, +-34948, +-115, +-34977, +-114, +-35007, +-114, +-35036, +-114, +-35066, +-113, +-35095, +-113, +-35125, +-112, +-35155, +-112, +-35184, +-112, +-35214, +-111, +-35243, +-111, +-35273, +-110, +-35303, +-110, +-35333, +-110, +-35362, +-109, +-35392, +-109, +-35422, +-108, +-35452, +-108, +-35481, +-108, +-35511, +-107, +-35541, +-107, +-35571, +-106, +-35601, +-106, +-35630, +-106, +-35660, +-105, +-35690, +-105, +-35720, +-104, +-35750, +-104, +-35780, +-104, +-35810, +-103, +-35840, +-103, +-35870, +-103, +-35900, +-102, +-35930, +-102, +-35960, +-101, +-35990, +-101, +-36020, +-101, +-36050, +-100, +-36080, +-100, +-36110, +-100, +-36140, +-99, +-36170, +-99, +-36200, +-98, +-36231, +-98, +-36261, +-98, +-36291, +-97, +-36321, +-97, +-36351, +-97, +-36381, +-96, +-36412, +-96, +-36442, +-96, +-36472, +-95, +-36503, +-95, +-36533, +-94, +-36563, +-94, +-36593, +-94, +-36624, +-93, +-36654, +-93, +-36684, +-93, +-36715, +-92, +-36745, +-92, +-36776, +-92, +-36806, +-91, +-36837, +-91, +-36867, +-91, +-36897, +-90, +-36928, +-90, +-36958, +-90, +-36989, +-89, +-37020, +-89, +-37050, +-89, +-37081, +-88, +-37111, +-88, +-37142, +-88, +-37172, +-87, +-37203, +-87, +-37234, +-87, +-37264, +-86, +-37295, +-86, +-37326, +-86, +-37356, +-85, +-37387, +-85, +-37418, +-85, +-37448, +-84, +-37479, +-84, +-37510, +-84, +-37541, +-83, +-37572, +-83, +-37602, +-83, +-37633, +-82, +-37664, +-82, +-37695, +-82, +-37726, +-82, +-37757, +-81, +-37788, +-81, +-37818, +-81, +-37849, +-80, +-37880, +-80, +-37911, +-80, +-37942, +-79, +-37973, +-79, +-38004, +-79, +-38035, +-78, +-38066, +-78, +-38097, +-78, +-38128, +-78, +-38160, +-77, +-38191, +-77, +-38222, +-77, +-38253, +-76, +-38284, +-76, +-38315, +-76, +-38346, +-75, +-38377, +-75, +-38409, +-75, +-38440, +-75, +-38471, +-74, +-38502, +-74, +-38534, +-74, +-38565, +-73, +-38596, +-73, +-38627, +-73, +-38659, +-73, +-38690, +-72, +-38721, +-72, +-38753, +-72, +-38784, +-72, +-38816, +-71, +-38847, +-71, +-38878, +-71, +-38910, +-70, +-38941, +-70, +-38973, +-70, +-39004, +-70, +-39036, +-69, +-39067, +-69, +-39099, +-69, +-39130, +-69, +-39162, +-68, +-39193, +-68, +-39225, +-68, +-39257, +-67, +-39288, +-67, +-39320, +-67, +-39351, +-67, +-39383, +-66, +-39415, +-66, +-39446, +-66, +-39478, +-66, +-39510, +-65, +-39542, +-65, +-39573, +-65, +-39605, +-65, +-39637, +-64, +-39669, +-64, +-39700, +-64, +-39732, +-64, +-39764, +-63, +-39796, +-63, +-39828, +-63, +-39860, +-63, +-39892, +-62, +-39924, +-62, +-39955, +-62, +-39987, +-62, +-40019, +-61, +-40051, +-61, +-40083, +-61, +-40115, +-61, +-40147, +-60, +-40179, +-60, +-40211, +-60, +-40243, +-60, +-40276, +-59, +-40308, +-59, +-40340, +-59, +-40372, +-59, +-40404, +-59, +-40436, +-58, +-40468, +-58, +-40500, +-58, +-40533, +-58, +-40565, +-57, +-40597, +-57, +-40629, +-57, +-40662, +-57, +-40694, +-56, +-40726, +-56, +-40758, +-56, +-40791, +-56, +-40823, +-56, +-40855, +-55, +-40888, +-55, +-40920, +-55, +-40952, +-55, +-40985, +-54, +-41017, +-54, +-41050, +-54, +-41082, +-54, +-41115, +-54, +-41147, +-53, +-41180, +-53, +-41212, +-53, +-41245, +-53, +-41277, +-53, +-41310, +-52, +-41342, +-52, +-41375, +-52, +-41407, +-52, +-41440, +-52, +-41473, +-51, +-41505, +-51, +-41538, +-51, +-41571, +-51, +-41603, +-50, +-41636, +-50, +-41669, +-50, +-41701, +-50, +-41734, +-50, +-41767, +-49, +-41800, +-49, +-41832, +-49, +-41865, +-49, +-41898, +-49, +-41931, +-48, +-41964, +-48, +-41997, +-48, +-42030, +-48, +-42062, +-48, +-42095, +-47, +-42128, +-47, +-42161, +-47, +-42194, +-47, +-42227, +-47, +-42260, +-47, +-42293, +-46, +-42326, +-46, +-42359, +-46, +-42392, +-46, +-42425, +-46, +-42458, +-45, +-42491, +-45, +-42524, +-45, +-42558, +-45, +-42591, +-45, +-42624, +-44, +-42657, +-44, +-42690, +-44, +-42723, +-44, +-42757, +-44, +-42790, +-44, +-42823, +-43, +-42856, +-43, +-42890, +-43, +-42923, +-43, +-42956, +-43, +-42989, +-43, +-43023, +-42, +-43056, +-42, +-43089, +-42, +-43123, +-42, +-43156, +-42, +-43190, +-41, +-43223, +-41, +-43256, +-41, +-43290, +-41, +-43323, +-41, +-43357, +-41, +-43390, +-40, +-43424, +-40, +-43457, +-40, +-43491, +-40, +-43524, +-40, +-43558, +-40, +-43592, +-39, +-43625, +-39, +-43659, +-39, +-43692, +-39, +-43726, +-39, +-43760, +-39, +-43793, +-38, +-43827, +-38, +-43861, +-38, +-43895, +-38, +-43928, +-38, +-43962, +-38, +-43996, +-38, +-44030, +-37, +-44063, +-37, +-44097, +-37, +-44131, +-37, +-44165, +-37, +-44199, +-37, +-44233, +-36, +-44266, +-36, +-44300, +-36, +-44334, +-36, +-44368, +-36, +-44402, +-36, +-44436, +-36, +-44470, +-35, +-44504, +-35, +-44538, +-35, +-44572, +-35, +-44606, +-35, +-44640, +-35, +-44674, +-35, +-44708, +-34, +-44742, +-34, +-44776, +-34, +-44811, +-34, +-44845, +-34, +-44879, +-34, +-44913, +-33, +-44947, +-33, +-44981, +-33, +-45016, +-33, +-45050, +-33, +-45084, +-33, +-45118, +-33, +-45153, +-33, +-45187, +-32, +-45221, +-32, +-45255, +-32, +-45290, +-32, +-45324, +-32, +-45358, +-32, +-45393, +-32, +-45427, +-31, +-45462, +-31, +-45496, +-31, +-45531, +-31, +-45565, +-31, +-45599, +-31, +-45634, +-31, +-45668, +-30, +-45703, +-30, +-45737, +-30, +-45772, +-30, +-45807, +-30, +-45841, +-30, +-45876, +-30, +-45910, +-30, +-45945, +-29, +-45980, +-29, +-46014, +-29, +-46049, +-29, +-46084, +-29, +-46118, +-29, +-46153, +-29, +-46188, +-29, +-46222, +-28, +-46257, +-28, +-46292, +-28, +-46327, +-28, +-46361, +-28, +-46396, +-28, +-46431, +-28, +-46466, +-28, +-46501, +-27, +-46536, +-27, +-46571, +-27, +-46606, +-27, +-46640, +-27, +-46675, +-27, +-46710, +-27, +-46745, +-27, +-46780, +-27, +-46815, +-26, +-46850, +-26, +-46885, +-26, +-46920, +-26, +-46955, +-26, +-46990, +-26, +-47026, +-26, +-47061, +-26, +-47096, +-26, +-47131, +-25, +-47166, +-25, +-47201, +-25, +-47236, +-25, +-47272, +-25, +-47307, +-25, +-47342, +-25, +-47377, +-25, +-47412, +-25, +-47448, +-24, +-47483, +-24, +-47518, +-24, +-47554, +-24, +-47589, +-24, +-47624, +-24, +-47660, +-24, +-47695, +-24, +-47730, +-24, +-47766, +-23, +-47801, +-23, +-47837, +-23, +-47872, +-23, +-47907, +-23, +-47943, +-23, +-47978, +-23, +-48014, +-23, +-48049, +-23, +-48085, +-23, +-48121, +-22, +-48156, +-22, +-48192, +-22, +-48227, +-22, +-48263, +-22, +-48299, +-22, +-48334, +-22, +-48370, +-22, +-48406, +-22, +-48441, +-22, +-48477, +-21, +-48513, +-21, +-48548, +-21, +-48584, +-21, +-48620, +-21, +-48656, +-21, +-48691, +-21, +-48727, +-21, +-48763, +-21, +-48799, +-21, +-48835, +-21, +-48871, +-20, +-48907, +-20, +-48942, +-20, +-48978, +-20, +-49014, +-20, +-49050, +-20, +-49086, +-20, +-49122, +-20, +-49158, +-20, +-49194, +-20, +-49230, +-20, +-49266, +-19, +-49302, +-19, +-49338, +-19, +-49374, +-19, +-49410, +-19, +-49447, +-19, +-49483, +-19, +-49519, +-19, +-49555, +-19, +-49591, +-19, +-49627, +-19, +-49664, +-19, +-49700, +-18, +-49736, +-18, +-49772, +-18, +-49809, +-18, +-49845, +-18, +-49881, +-18, +-49917, +-18, +-49954, +-18, +-49990, +-18, +-50026, +-18, +-50063, +-18, +-50099, +-18, +-50136, +-17, +-50172, +-17, +-50208, +-17, +-50245, +-17, +-50281, +-17, +-50318, +-17, +-50354, +-17, +-50391, +-17, +-50427, +-17, +-50464, +-17, +-50500, +-17, +-50537, +-17, +-50574, +-17, +-50610, +-16, +-50647, +-16, +-50683, +-16, +-50720, +-16, +-50757, +-16, +-50793, +-16, +-50830, +-16, +-50867, +-16, +-50903, +-16, +-50940, +-16, +-50977, +-16, +-51014, +-16, +-51050, +-16, +-51087, +-15, +-51124, +-15, +-51161, +-15, +-51198, +-15, +-51235, +-15, +-51271, +-15, +-51308, +-15, +-51345, +-15, +-51382, +-15, +-51419, +-15, +-51456, +-15, +-51493, +-15, +-51530, +-15, +-51567, +-15, +-51604, +-14, +-51641, +-14, +-51678, +-14, +-51715, +-14, +-51752, +-14, +-51789, +-14, +-51826, +-14, +-51863, +-14, +-51900, +-14, +-51938, +-14, +-51975, +-14, +-52012, +-14, +-52049, +-14, +-52086, +-14, +-52124, +-14, +-52161, +-14, +-52198, +-13, +-52235, +-13, +-52273, +-13, +-52310, +-13, +-52347, +-13, +-52384, +-13, +-52422, +-13, +-52459, +-13, +-52497, +-13, +-52534, +-13, +-52571, +-13, +-52609, +-13, +-52646, +-13, +-52684, +-13, +-52721, +-13, +-52759, +-13, +-52796, +-12, +-52834, +-12, +-52871, +-12, +-52909, +-12, +-52946, +-12, +-52984, +-12, +-53021, +-12, +-53059, +-12, +-53097, +-12, +-53134, +-12, +-53172, +-12, +-53209, +-12, +-53247, +-12, +-53285, +-12, +-53323, +-12, +-53360, +-12, +-53398, +-12, +-53436, +-11, +-53473, +-11, +-53511, +-11, +-53549, +-11, +-53587, +-11, +-53625, +-11, +-53663, +-11, +-53700, +-11, +-53738, +-11, +-53776, +-11, +-53814, +-11, +-53852, +-11, +-53890, +-11, +-53928, +-11, +-53966, +-11, +-54004, +-11, +-54042, +-11, +-54080, +-11, +-54118, +-11, +-54156, +-10, +-54194, +-10, +-54232, +-10, +-54270, +-10, +-54308, +-10, +-54346, +-10, +-54384, +-10, +-54423, +-10, +-54461, +-10, +-54499, +-10, +-54537, +-10, +-54575, +-10, +-54613, +-10, +-54652, +-10, +-54690, +-10, +-54728, +-10, +-54767, +-10, +-54805, +-10, +-54843, +-10, +-54881, +-10, +-54920, +-10, +-54958, +-9, +-54997, +-9, +-55035, +-9, +-55073, +-9, +-55112, +-9, +-55150, +-9, +-55189, +-9, +-55227, +-9, +-55266, +-9, +-55304, +-9, +-55343, +-9, +-55381, +-9, +-55420, +-9, +-55458, +-9, +-55497, +-9, +-55535, +-9, +-55574, +-9, +-55613, +-9, +-55651, +-9, +-55690, +-9, +-55729, +-9, +-55767, +-9, +-55806, +-8, +-55845, +-8, +-55883, +-8, +-55922, +-8, +-55961, +-8, +-56000, +-8, +-56038, +-8, +-56077, +-8, +-56116, +-8, +-56155, +-8, +-56194, +-8, +-56233, +-8, +-56271, +-8, +-56310, +-8, +-56349, +-8, +-56388, +-8, +-56427, +-8, +-56466, +-8, +-56505, +-8, +-56544, +-8, +-56583, +-8, +-56622, +-8, +-56661, +-8, +-56700, +-8, +-56739, +-8, +-56778, +-7, +-56817, +-7, +-56856, +-7, +-56896, +-7, +-56935, +-7, +-56974, +-7, +-57013, +-7, +-57052, +-7, +-57091, +-7, +-57131, +-7, +-57170, +-7, +-57209, +-7, +-57248, +-7, +-57288, +-7, +-57327, +-7, +-57366, +-7, +-57405, +-7, +-57445, +-7, +-57484, +-7, +-57524, +-7, +-57563, +-7, +-57602, +-7, +-57642, +-7, +-57681, +-7, +-57721, +-7, +-57760, +-7, +-57800, +-7, +-57839, +-7, +-57879, +-6, +-57918, +-6, +-57958, +-6, +-57997, +-6, +-58037, +-6, +-58076, +-6, +-58116, +-6, +-58155, +-6, +-58195, +-6, +-58235, +-6, +-58274, +-6, +-58314, +-6, +-58354, +-6, +-58393, +-6, +-58433, +-6, +-58473, +-6, +-58513, +-6, +-58552, +-6, +-58592, +-6, +-58632, +-6, +-58672, +-6, +-58712, +-6, +-58751, +-6, +-58791, +-6, +-58831, +-6, +-58871, +-6, +-58911, +-6, +-58951, +-6, +-58991, +-6, +-59031, +-6, +-59071, +-6, +-59111, +-5, +-59151, +-5, +-59191, +-5, +-59231, +-5, +-59271, +-5, +-59311, +-5, +-59351, +-5, +-59391, +-5, +-59431, +-5, +-59471, +-5, +-59511, +-5, +-59551, +-5, +-59592, +-5, +-59632, +-5, +-59672, +-5, +-59712, +-5, +-59752, +-5, +-59793, +-5, +-59833, +-5, +-59873, +-5, +-59913, +-5, +-59954, +-5, +-59994, +-5, +-60034, +-5, +-60075, +-5, +-60115, +-5, +-60156, +-5, +-60196, +-5, +-60236, +-5, +-60277, +-5, +-60317, +-5, +-60358, +-5, +-60398, +-5, +-60439, +-5, +-60479, +-5, +-60520, +-5, +-60560, +-5, +-60601, +-4, +-60641, +-4, +-60682, +-4, +-60722, +-4, +-60763, +-4, +-60804, +-4, +-60844, +-4, +-60885, +-4, +-60926, +-4, +-60966, +-4, +-61007, +-4, +-61048, +-4, +-61088, +-4, +-61129, +-4, +-61170, +-4, +-61211, +-4, +-61251, +-4, +-61292, +-4, +-61333, +-4, +-61374, +-4, +-61415, +-4, +-61456, +-4, +-61497, +-4, +-61537, +-4, +-61578, +-4, +-61619, +-4, +-61660, +-4, +-61701, +-4, +-61742, +-4, +-61783, +-4, +-61824, +-4, +-61865, +-4, +-61906, +-4, +-61947, +-4, +-61988, +-4, +-62029, +-4, +-62071, +-4, +-62112, +-4, +-62153, +-4, +-62194, +-4, +-62235, +-4, +-62276, +-4, +-62317, +-4, +-62359, +-4, +-62400, +-4, +-62441, +-3, +-62482, +-3, +-62524, +-3, +-62565, +-3, +-62606, +-3, +-62647, +-3, +-62689, +-3, +-62730, +-3, +-62772, +-3, +-62813, +-3, +-62854, +-3, +-62896, +-3, +-62937, +-3, +-62979, +-3, +-63020, +-3, +-63061, +-3, +-63103, +-3, +-63144, +-3, +-63186, +-3, +-63227, +-3, +-63269, +-3, +-63311, +-3, +-63352, +-3, +-63394, +-3, +-63435, +-3, +-63477, +-3, +-63519, +-3, +-63560, +-3, +-63602, +-3, +-63644, +-3, +-63685, +-3, +-63727, +-3, +-63769, +-3, +-63810, +-3, +-63852, +-3, +-63894, +-3, +-63936, +-3, +-63978, +-3, +-64019, +-3, +-64061, +-3, +-64103, +-3, +-64145, +-3, +-64187, +-3, +-64229, +-3, +-64271, +-3, +-64313, +-3, +-64355, +-3, +-64397, +-3, +-64438, +-3, +-64480, +-3, +-64522, +-3, +-64565, +-3, +-64607, +-3, +-64649, +-3, +-64691, +-3, +-64733, +-3, +-64775, +-2, +-64817, +-2, +-64859, +-2, +-64901, +-2, +-64943, +-2, +-64986, +-2, +-65028, +-2, +-65070, +-2, +-65112, +-2, +-65154, +-2, +-65197, +-2, +-65239, +-2, +-65281, +-2, +-65324, +-2, +-65366, +-2, +-65408, +-2, +-65450, +-2, +-65493, +-2, +-65535, +-2, +-65578, +-2, +-65620, +-2, +-65662, +-2, +-65705, +-2, +-65747, +-2, +-65790, +-2, +-65832, +-2, +-65875, +-2, +-65917, +-2, +-65960, +-2, +-66002, +-2, +-66045, +-2, +-66088, +-2, +-66130, +-2, +-66173, +-2, +-66215, +-2, +-66258, +-2, +-66301, +-2, +-66343, +-2, +-66386, +-2, +-66429, +-2, +-66471, +-2, +-66514, +-2, +-66557, +-2, +-66600, +-2, +-66642, +-2, +-66685, +-2, +-66728, +-2, +-66771, +-2, +-66814, +-2, +-66856, +-2, +-66899, +-2, +-66942, +-2, +-66985, +-2, +-67028, +-2, +-67071, +-2, +-67114, +-2, +-67157, +-2, +-67200, +-2, +-67243, +-2, +-67286, +-2, +-67329, +-2, +-67372, +-2, +-67415, +-2, +-67458, +-2, +-67501, +-2, +-67544, +-2, +-67587, +-2, +-67630, +-2, +-67674, +-2, +-67717, +-2, +-67760, +-2, +-67803, +-2, +-67846, +-2, +-67890, +-2, +-67933, +-2, +-67976, +-2, +-68019, +-2, +-68063, +-2, +-68106, +-1, +-68149, +-1, +-68193, +-1, +-68236, +-1, +-68279, +-1, +-68323, +-1, +-68366, +-1, +-68409, +-1, +-68453, +-1, +-68496, +-1, +-68540, +-1, +-68583, +-1, +-68627, +-1, +-68670, +-1, +-68714, +-1, +-68757, +-1, +-68801, +-1, +-68844, +-1, +-68888, +-1, +-68932, +-1, +-68975, +-1, +-69019, +-1, +-69062, +-1, +-69106, +-1, +-69150, +-1, +-69193, +-1, +-69237, +-1, +-69281, +-1, +-69325, +-1, +-69368, +-1, +-69412, +-1, +-69456, +-1, +-69500, +-1, +-69544, +-1, +-69587, +-1, +-69631, +-1, +-69675, +-1, +-69719, +-1, +-69763, +-1, +-69807, +-1, +-69851, +-1, +-69895, +-1, +-69939, +-1, +-69982, +-1, +-70026, +-1, +-70070, +-1, +-70114, +-1, +-70159, +-1, +-70203, +-1, +-70247, +-1, +-70291, +-1, +-70335, +-1, +-70379, +-1, +-70423, +-1, +-70467, +-1, +-70511, +-1, +-70555, +-1, +-70600, +-1, +-70644, +-1, +-70688, +-1, +-70732, +-1, +-70776, +-1, +-70821, +-1, +-70865, +-1, +-70909, +-1, +-70954, +-1, +-70998, +-1, +-71042, +-1, +-71087, +-1, +-71131, +-1, +-71175, +-1, +-71220, +-1, +-71264, +-1, +-71309, +-1, +-71353, +-1, +-71398, +-1, +-71442, +-1, +-71487, +-1, +-71531, +-1, +-71576, +-1, +-71620, +-1, +-71665, +-1, +-71709, +-1, +-71754, +-1, +-71798, +-1, +-71843, +-1, +-71888, +-1, +-71932, +-1, +-71977, +-1, +-72022, +-1, +-72066, +-1, +-72111, +-1, +-72156, +-1, +-72200, +-1, +-72245, +-1, +-72290, +-1, +-72335, +-1, +-72380, +-1, +-72424, +-1, +-72469, +-1, +-72514, +-1, +-72559, +-1, +-72604, +-1, +-72649, +-1, +-72694, +-1, +-72739, +-1, +-72783, +-1, +-72828, +-1, +-72873, +-1, +-72918, +-1, +-72963, +-1, +-73008, +-1, +-73053, +-1, +-73099, +-1, +-73144, +-1, +-73189, +-1, +-73234, +-1, +-73279, +-1, +-73324, +-1, +-73369, +-1, +-73414, +-1, +-73459, +-1, +-73505, +-1, +-73550, +-1, +-73595, +-1, +-73640, +-1, +-73686, +-1, +-73731, +-1, +-73776, +0, +-73821, +0, +-73867, +0, +-73912, +0, +-73957, +0, +-74003, +0, +-74048, +0, +-74094, +0, +-74139, +0, +-74184, +0, +-74230, +0, +-74275, +0, +-74321, +0, +-74366, +0, +-74412, +0, +-74457, +0, +-74503, +0, +-74548, +0, +-74594, +0, +-74639, +0, +-74685, +0, +-74731, +0, +-74776, +0, +-74822, +0, +-74868, +0, +-74913, +0, +-74959, +0, +-75005, +0, +-75050, +0, +-75096, +0, +-75142, +0, +-75188, +0, +-75233, +0, +-75279, +0, +-75325, +0, +-75371, +0, +-75417, +0, +-75462, +0, +-75508, +0, +-75554, +0, +-75600, +0, +-75646, +0, +-75692, +0, +-75738, +0, +-75784, +0, +-75830, +0, +-75876, +0, +-75922, +0, +-75968, +0, +-76014, +0, +-76060, +0, +-76106, +0, +-76152, +0, +-76198, +0, +-76244, +0, +-76291, +0, +-76337, +0, +-76383, +0, +-76429, +0, +-76475, +0, +-76521, +0, +-76568, +0, +-76614, +0, +-76660, +0, +-76706, +0, +-76753, +0, +-76799, +0, +-76845, +0, +-76892, +0, +-76938, +0, +-76984, +0, +-77031, +0, +-77077, +0, +-77124, +0, +-77170, +0, +-77217, +0, +-77263, +0, +-77309, +0, +-77356, +0, +-77402, +0, +-77449, +0, +-77496, +0, +-77542, +0, +-77589, +0, +-77635, +0, +-77682, +0, +-77728, +0, +-77775, +0, +-77822, +0, +-77868, +0, +-77915, +0, +-77962, +0, +-78008, +0, +-78055, +0, +-78102, +0, +-78149, +0, +-78195, +0, +-78242, +0, +-78289, +0, +-78336, +0, +-78383, +0, +-78430, +0, +-78476, +0, +-78523, +0, +-78570, +0, +-78617, +0, +-78664, +0, +-78711, +0, +-78758, +0, +-78805, +0, +-78852, +0, +-78899, +0, +-78946, +0, +-78993, +0, +-79040, +0, +-79087, +0, +-79134, +0, +-79181, +0, +-79228, +0, +-79276, +0, +-79323, +0, +-79370, +0, +-79417, +0, +-79464, +0, +-79511, +0, +-79559, +0, +-79606, +0, +-79653, +0, +-79700, +0, +-79748, +0, +-79795, +0, +-79842, +0, +-79890, +0, +-79937, +0, +-79984, +0, +-80032, +0, +-80079, +0, +-80127, +0, +-80174, +0, +-80221, +0, +-80269, +0, +-80316, +0, +-80364, +0, +-80411, +0, +-80459, +0, +-80506, +0, +-80554, +0, +-80602, +0, +-80649, +0, +-80697, +0, +-80744, +0, +-80792, +0, +-80840, +0, +-80887, +0, +-80935, +0, +-80983, +0, +-81030, +0, +-81078, +0, +-81126, +0, +-81174, +0, +-81221, +0, +-81269, +0, +-81317, +0, +-81365, +0, +-81413, +0, +-81460, +0, +-81508, +0, +-81556, +0, +-81604, +0, +-81652, +0, +-81700, +0, +-81748, +0, +-81796, +0, +-81844, +0, +-81892, +0, +-81940, +0, +-81988, +0, +-82036, +0, +-82084, +0, +-82132, +0, +-82180, +0, +-82228, +0, +-82276, +0, +-82324, +0, +-82373, +0, +-82421, +0, +-82469, +0, +-82517, +0, +-82565, +0, +-82613, +0, +-82662, +0, +-82710, +0, +-82758, +0, +-82807, +0, +-82855, +0, +-82903, +0, +-82951, +0, +-83000, +0, +-83048, +0, +-83097, +0, +-83145, +0, +-83193, +0, +-83242, +0, +-83290, +0, +-83339, +0, +-83387, +0, +-83436, +0, +-83484, +0, +-83533, +0, +-83581, +0, +-83630, +0, +-83678, +0, +-83727, +0, +-83775, +0, +-83824, +0, +-83873, +0, +-83921, +0, +-83970, +0, +-84019, +0, +-84067, +0, +-84116, +0, +-84165, +0, +-84214, +0, +-84262, +0, +-84311, +0, +-84360, +0, +-84409, +0, +-84457, +0, +-84506, +0, +-84555, +0, +-84604, +0, +-84653, +0, +-84702, +0, +-84751, +0, +-84800, +0, +-84849, +0, +-84898, +0, +-84946, +0, +-84995, +0, +-85044, +0, +-85093, +0, +-85143, +0, +-85192, +0, +-85241, +0, +-85290, +0, +-85339, +0, +-85388, +0, +-85437, +0, +-85486, +0, +-85535, +0, +-85585, +0, +-85634, +0, +-85683, +0, +-85732, +0, +-85781, +0, +-85831, +0, +-85880, +0, +-85929, +0, +-85978, +0, +-86028, +0, +-86077, +0, +-86126, +0, +-86176, +0, +-86225, +0, +-86275, +0, +-86324, +0, +-86373, +0, +-86423, +0, +-86472, +0, +-86522, +0, +-86571, +0, +-86621, +0, +-86670, +0, +-86720, +0, +-86769, +0, +-86819, +0, +-86869, +0, +-86918, +0, +-86968, +0, +-87017, +0, +-87067, +0, +-87117, +0, +-87166, +0, +-87216, +0, +-87266, +0, +-87315, +0, +-87365, +0, +-87415, +0, +-87465, +0, +-87515, +0, +-87564, +0, +-87614, +0, +-87664, +0, +-87714, +0, +-87764, +0, +-87814, +0, +-87863, +0, +-87913, +0, +-87963, +0, +-88013, +0, +-88063, +0, +-88113, +0, +-88163, +0, +-88213, +0, +-88263, +0, +-88313, +0, +-88363, +0, +-88413, +0, +-88463, +0, +-88513, +0, +-88564, +0, +-88614, +0, +-88664, +0, +-88714, +0, +-88764, +0, +-88814, +0, +-88865, +0, +-88915, +0, +-88965, +0, +-89015, +0, +-89066, +0, +-89116, +0, +-89166, +0, +-89216, +0, +-89267, +0, +-89317, +0, +-89368, +0, +-89418, +0, +-89468, +0, +-89519, +0, +-89569, +0, +-89620, +0, +-89670, +0, +-89721, +0, +-89771, +0, +-89822, +0, +-89872, +0, +-89923, +0, +-89973, +0, +-90024, +0, +-90074, +0, +-90125, +0, +-90175, +0, +-90226, +0, +-90277, +0, +-90327, +0, +-90378, +0, +-90429, +0, +-90479, +0, +-90530, +0, +-90581, +0, +-90632, +0, +-90682, +0, +-90733, +0, +-90784, +0, +-90835, +0, +-90886, +0, +-90937, +0, +-90987, +0, +-91038, +0, +-91089, +0, +-91140, +0, +-91191, +0, +-91242, +0, +-91293, +0, +-91344, +0, +-91395, +0, +-91446, +0, +-91497, +0, +-91548, +0, +-91599, +0, +-91650, +0, +-91701, +0, +-91752, +0, +-91803, +0, +-91855, +0, +-91906, +0, +-91957, +0, +-92008, +0, +-92059, +0, +-92110, +0, +-92162, +0, +-92213, +0, +-92264, +0, +-92315, +0, +-92367, +0, +-92418, +0, +-92469, +0, +-92521, +0, +-92572, +0, +-92623, +0, +-92675, +0, +-92726, +0, +-92778, +0, +-92829, +0, +-92880, +0, +-92932, +0, +-92983, +0, +-93035, +0, +-93086, +0, +-93138, +0, +-93189, +0, +-93241, +0, +-93293, +0, +-93344, +0, +-93396, +0, +-93447, +0, +-93499, +0, +-93551, +0, +-93602, +0, +-93654, +0, +-93706, +0, +-93757, +0, +-93809, +0, +-93861, +0, +-93913, +0, +-93964, +0, +-94016, +0, +-94068, +0, +-94120, +0, +-94172, +0, +-94223, +0, +-94275, +0, +-94327, +0, +-94379, +0, +-94431, +0, +-94483, +0, +-94535, +0, +-94587, +0, +-94639, +0, +-94691, +0, +-94743, +0, +-94795, +0, +-94847, +0, +-94899, +0, +-94951, +0, +-95003, +0, +-95055, +0, +-95107, +0, +-95160, +0, +-95212, +0, +-95264, +0, +-95316, +0, +-95368, +0, +-95420, +0, +-95473, +0, +-95525, +0, +-95577, +0, +-95629, +0, +-95682, +0, +-95734, +0, +-95786, +0, +-95839, +0, +-95891, +0, +-95943, +0, +-95996, +0, +-96048, +0, +-96101, +0, +-96153, +0, +-96205, +0, +-96258, +0, +-96310, +0, +-96363, +0, +-96415, +0, +-96468, +0, +-96521, +0, +-96573, +0, +-96626, +0, +-96678, +0, +-96731, +0, +-96783, +0, +-96836, +0, +-96889, +0, +-96941, +0, +-96994, +0, +-97047, +0, +-97100, +0, +-97152, +0, +-97205, +0, +-97258, +0, +-97311, +0, +-97363, +0, +-97416, +0, +-97469, +0, +-97522, +0, +-97575, +0, +-97628, +0, +-97680, +0, +-97733, +0, +-97786, +0, +-97839, +0, +-97892, +0, +-97945, +0, +-97998, +0, +-98051, +0, +-98104, +0, +-98157, +0, +-98210, +0, +-98263, +0, +-98316, +0, +-98369, +0, +-98423, +0, +-98476, +0, +-98529, +0, +-98582, +0, +-98635, +0, +-98688, +0, +-98742, +0, +-98795, +0, +-98848, +0, +-98901, +0, +-98954, +0, +-99008, +0, +-99061, +0, +-99114, +0, +-99168, +0, +-99221, +0, +-99274, +0, +-99328, +0, +-99381, +0, +-99435, +0, +-99488, +0, +-99541, +0, +-99595, +0, +-99648, +0, +-99702, +0, +-99755, +0, +-99809, +0, +-99862, +0, +-99916, +0, +-99970, +0, +-100023, +0, +-100077, +0, +-100130, +0, +-100184, +0, +-100238, +0, +-100291, +0, +-100345, +0, +-100399, +0, +-100452, +0, +-100506, +0, +-100560, +0, +-100614, +0, +-100667, +0, +-100721, +0, +-100775, +0, +-100829, +0, +-100883, +0, +-100936, +0, +-100990, +0, +-101044, +0, +-101098, +0, +-101152, +0, +-101206, +0, +-101260, +0, +-101314, +0, +-101368, +0, +-101422, +0, +-101476, +0, +-101530, +0, +-101584, +0, +-101638, +0, +-101692, +0, +-101746, +0, +-101800, +0, +-101854, +0, +-101908, +0, +-101962, +0, +-102017, +0, +-102071, +0, +-102125, +0, +-102179, +0, +-102233, +0, +-102288, +0, +-102342, +0, +-102396, +0, +-102450, +0, +-102505, +0, +-102559, +0, +-102613, +0, +-102668, +0, +-102722, +0, +-102777, +0, +-102831, +0, +-102885, +0, +-102940, +0, +-102994, +0, +-103049, +0, +-103103, +0, +-103158, +0, +-103212, +0, +-103267, +0, +-103321, +0, +-103376, +0, +-103430, +0, +-103485, +0, +-103540, +0, +-103594, +0, +-103649, +0, +-103703, +0, +-103758, +0, +-103813, +0, +-103868, +0, +-103922, +0, +-103977, +0, +-104032, +0, +-104086, +0, +-104141, +0, +-104196, +0, +-104251, +0, +-104306, +0, +-104361, +0, +-104415, +0, +-104470, +0, +-104525, +0, +-104580, +0, +-104635, +0, +-104690, +0, +-104745, +0, +-104800, +0, +-104855, +0, +-104910, +0, +-104965, +0, +-105020, +0, +-105075, +0, +-105130, +0, +-105185, +0, +-105240, +0, +-105295, +0, +-105350, +0, +-105405, +0, +-105461, +0, +-105516, +0, +-105571, +0, +-105626, +0, +-105681, +0, +-105737, +0, +-105792, +0, +-105847, +0, +-105902, +0, +-105958, +0, +-106013, +0, +-106068, +0, +-106124, +0, +-106179, +0, +-106234, +0, +-106290, +0, +-106345, +0, +-106401, +0, +-106456, +0, +-106512, +0, +-106567, +0, +-106622, +0, +-106678, +0, +-106734, +0, +-106789, +0, +-106845, +0, +-106900, +0, +-106956, +0, +-107011, +0, +-107067, +0, +-107123, +0, +-107178, +0, +-107234, +0, +-107290, +0, +-107345, +0, +-107401, +0, +-107457, +0, +-107512, +0, +-107568, +0, +-107624, +0, +-107680, +0, +-107736, +0, +-107791, +0, +-107847, +0, +-107903, +0, +-107959, +0, +-108015, +0, +-108071, +0, +-108127, +0, +-108182, +0, +-108238, +0, +-108294, +0, +-108350, +0, +-108406, +0, +-108462, +0, +-108518, +0, +-108574, +0, +-108630, +0, +-108687, +0, +-108743, +0, +-108799, +0, +-108855, +0, +-108911, +0, +-108967, +0, +-109023, +0, +-109079, +0, +-109136, +0, +-109192, +0, +-109248, +0, +-109304, +0, +-109361, +0, +-109417, +0, +-109473, +0, +-109529, +0, +-109586, +0, +-109642, +0, +-109699, +0, +-109755, +0, +-109811, +0, +-109868, +0, +-109924, +0, +-109981, +0, +-110037, +0, +-110093, +0, +-110150, +0, +-110206, +0, +-110263, +0, +-110319, +0, +-110376, +0, +-110433, +0, +-110489, +0, +-110546, +0, +-110602, +0, +-110659, +0, +-110716, +0, +-110772, +0, +-110829, +0, +-110886, +0, +-110942, +0, +-110999, +0, +-111056, +0, +-111112, +0, +-111169, +0, +-111226, +0, +-111283, +0, +-111340, +0, +-111396, +0, +-111453, +0, +-111510, +0, +-111567, +0, +-111624, +0, +-111681, +0, +-111738, +0, +-111795, +0, +-111852, +0, +-111909, +0, +-111966, +0, +-112023, +0, +-112080, +0, +-112137, +0, +-112194, +0, +-112251, +0, +-112308, +0, +-112365, +0, +-112422, +0, +-112479, +0, +-112536, +0, +-112593, +0, +-112651, +0, +-112708, +0, +-112765, +0, +-112822, +0, +-112880, +0, +-112937, +0, +-112994, +0, +-113051, +0, +-113109, +0, +-113166, +0, +-113223, +0, +-113281, +0, +-113338, +0, +-113395, +0, +-113453, +0, +-113510, +0, +-113568, +0, +-113625, +0, +-113682, +0, +-113740, +0, +-113797, +0, +-113855, +0, +-113912, +0, +-113970, +0, +-114028, +0, +-114085, +0, +-114143, +0, +-114200, +0, +-114258, +0, +-114316, +0, +-114373, +0, +-114431, +0, +-114489, +0, +-114546, +0, +-114604, +0, +-114662, +0, +-114719, +0, +-114777, +0, +-114835, +0, +-114893, +0, +-114951, +0, +-115008, +0, +-115066, +0, +-115124, +0, +-115182, +0, +-115240, +0, +-115298, +0, +-115356, +0, +-115414, +0, +-115472, +0, +-115530, +0, +-115588, +0, +-115646, +0, +-115704, +0, +-115762, +0, +-115820, +0, +-115878, +0, +-115936, +0, +-115994, +0, +-116052, +0, +-116110, +0, +-116168, +0, +-116226, +0, +-116285, +0, +-116343, +0, +-116401, +0, +-116459, +0, +-116517, +0, +-116576, +0, +-116634, +0, +-116692, +0, +-116750, +0, +-116809, +0, +-116867, +0, +-116925, +0, +-116984, +0, +-117042, +0, +-117101, +0, +-117159, +0, +-117217, +0, +-117276, +0, +-117334, +0, +-117393, +0, +-117451, +0, +-117510, +0, +-117568, +0, +-117627, +0, +-117685, +0, +-117744, +0, +-117803, +0, +-117861, +0, +-117920, +0, +-117978, +0, +-118037, +0, +-118096, +0, +-118154, +0, +-118213, +0, +-118272, +0, +-118330, +0, +-118389, +0, +-118448, +0, +-118507, +0, +-118566, +0, +-118624, +0, +-118683, +0, +-118742, +0, +-118801, +0, +-118860, +0, +-118919, +0, +-118977, +0, +-119036, +0, +-119095, +0, +-119154, +0, +-119213, +0, +-119272, +0, +-119331, +0, +-119390, +0, +-119449, +0, +-119508, +0, +-119567, +0, +-119626, +0, +-119685, +0, +-119745, +0, +-119804, +0, +-119863, +0, +-119922, +0, +-119981, +0, +-120040, +0, +-120100, +0, +-120159, +0, +-120218, +0, +-120277, +0, +-120336, +0, +-120396, +0, +-120455, +0, +-120514, +0, +-120574, +0, +-120633, +0, +-120692, +0, +-120752, +0, +-120811, +0, +-120871, +0, +-120930, +0, +-120989, +0, +-121049, +0, +-121108, +0, +-121168, +0, +-121227, +0, +-121287, +0, +-121346, +0, +-121406, +0, +-121465, +0, +-121525, +0, +-121585, +0, +-121644, +0, +-121704, +0, +-121764, +0, +-121823, +0, +-121883, +0, +-121943, +0, +-122002, +0, +-122062, +0, +-122122, +0, +-122181, +0, +-122241, +0, +-122301, +0, +-122361, +0, +-122421, +0, +-122480, +0, +-122540, +0, +-122600, +0, +-122660, +0, +-122720, +0, +-122780, +0, +-122840, +0, +-122900, +0, +-122960, +0, +-123020, +0, +-123080, +0, +-123140, +0, +-123200, +0, +-123260, +0, +-123320, +0, +-123380, +0, +-123440, +0, +-123500, +0, +-123560, +0, +-123620, +0, +-123680, +0, +-123741, +0, +-123801, +0, +-123861, +0, +-123921, +0, +-123981, +0, +-124042, +0, +-124102, +0, +-124162, +0, +-124223, +0, +-124283, +0, +-124343, +0, +-124404, +0, +-124464, +0, +-124524, +0, +-124585, +0, +-124645, +0, +-124705, +0, +-124766, +0, +-124826, +0, +-124887, +0, +-124947, +0, +-125008, +0, +-125068, +0, +-125129, +0, +-125189, +0, +-125250, +0, +-125311, +0, +-125371, +0, +-125432, +0, +-125492, +0, +-125553, +0, +-125614, +0, +-125674, +0, +-125735, +0, +-125796, +0, +-125856, +0, +-125917, +0, +-125978, +0, +-126039, +0, +-126099, +0, +-126160, +0, +-126221, +0, +-126282, +0, +-126343, +0, +-126404, +0, +-126465, +0, +-126525, +0, +-126586, +0, +-126647, +0, +-126708, +0, +-126769, +0, +-126830, +0, +-126891, +0, +-126952, +0, +-127013, +0, +-127074, +0, +-127135, +0, +-127196, +0, +-127257, +0, +-127318, +0, +-127380, +0, +-127441, +0, +-127502, +0, +-127563, +0, +-127624, +0, +-127685, +0, +-127747, +0, +-127808, +0, +-127869, +0, +-127930, +0, +-127992, +0, +-128053, +0, +-128114, +0, +-128176, +0, +-128237, +0, +-128298, +0, +-128360, +0, +-128421, +0, +-128482, +0, +-128544, +0, +-128605, +0, +-128667, +0, +-128728, +0, +-128790, +0, +-128851, +0, +-128913, +0, +-128974, +0, +-129036, +0, +-129097, +0, +-129159, +0, +-129220, +0, +-129282, +0, +-129344, +0, +-129405, +0, +-129467, +0, +-129529, +0, +-129590, +0, +-129652, +0, +-129714, +0, +-129776, +0, +-129837, +0, +-129899, +0, +-129961, +0, +-130023, +0, +-130084, +0, +-130146, +0, +-130208, +0, +-130270, +0, +-130332, +0, +-130394, +0, +-130456, +0, +-130518, +0, +-130580, +0, +-130642, +0, +-130703, +0, +-130765, +0, +-130827, +0, +-130889, +0, +-130952, +0, +-131014, +0, +-131076, +0, +-131138, +0, +-131200, +0, +-131262, +0, +-131324, +0, +-131386, +0, +-131448, +0, +-131511, +0, +-131573, +0, +-131635, +0, +-131697, +0, +-131759, +0, +-131822, +0, +-131884, +0, +-131946, +0, +-132009, +0, +-132071, +0, +-132133, +0, +-132196, +0, +-132258, +0, +-132320, +0, +-132383, +0, +-132445, +0, +-132508, +0, +-132570, +0, +-132633, +0, +-132695, +0, +-132758, +0, +-132820, +0, +-132883, +0, +-132945, +0, +-133008, +0, +-133070, +0, +-133133, +0, +-133195, +0, +-133258, +0, +-133321, +0, +-133383, +0, +-133446, +0, +-133509, +0, +-133571, +0, +-133634, +0, +-133697, +0, +-133760, +0, +-133822, +0, +-133885, +0, +-133948, +0, +-134011, +0, +-134074, +0, +-134137, +0, +-134199, +0, +-134262, +0, +-134325, +0, +-134388, +0, +-134451, +0, +-134514, +0, +-134577, +0, +-134640, +0, +-134703, +0, +-134766, +0, +-134829, +0, +-134892, +0, +-134955, +0, +-135018, +0, +-135081, +0, +-135144, +0, +-135207, +0, +-135270, +0, +-135334, +0, +-135397, +0, +-135460, +0, +-135523, +0, +-135586, +0, +-135650, +0, +-135713, +0, +-135776, +0, +-135839, +0, +-135903, +0, +-135966, +0, +-136029, +0, +-136093, +0, +-136156, +0, +-136219, +0, +-136283, +0, +-136346, +0, +-136410, +0, +-136473, +0, +-136536, +0, +-136600, +0, +-136663, +0, +-136727, +0, +-136790, +0, +-136854, +0, +-136918, +0, +-136981, +0, +-137045, +0, +-137108, +0, +-137172, +0, +-137236, +0, +-137299, +0, +-137363, +0, +-137426, +0, +-137490, +0, +-137554, +0, +-137618, +0, +-137681, +0, +-137745, +0, +-137809, +0, +-137873, +0, +-137936, +0, +-138000, +0, +-138064, +0, +-138128, +0, +-138192, +0, +-138256, +0, +-138320, +0, +-138384, +0, +-138447, +0, +-138511, +0, +-138575, +0, +-138639, +0, +-138703, +0, +-138767, +0, +-138831, +0, +-138895, +0, +-138959, +0, +-139024, +0, +-139088, +0, +-139152, +0, +-139216, +0, +-139280, +0, +-139344, +0, +-139408, +0, +-139472, +0, +-139537, +0, +-139601, +0, +-139665, +0, +-139729, +0, +-139794, +0, +-139858, +0, +-139922, +0, +-139986, +0, +-140051, +0, +-140115, +0, +-140180, +0, +-140244, +0, +-140308, +0, +-140373, +0, +-140437, +0, +-140502, +0, +-140566, +0, +-140630, +0, +-140695, +0, +-140759, +0, +-140824, +0, +-140889, +0, +-140953, +0, +-141018, +0, +-141082, +0, +-141147, +0, +-141211, +0, +-141276, +0, +-141341, +0, +-141405, +0, +-141470, +0, +-141535, +0, +-141599, +0, +-141664, +0, +-141729, +0, +-141794, +0, +-141858, +0, +-141923, +0, +-141988, +0, +-142053, +0, +-142118, +0, +-142183, +0, +-142247, +0, +-142312, +0, +-142377, +0, +-142442, +0, +-142507, +0, +-142572, +0, +-142637, +0, +-142702, +0, +-142767, +0, +-142832, +0, +-142897, +0, +-142962, +0, +-143027, +0, +-143092, +0, +-143157, +0, +-143222, +0, +-143287, +0, +-143353, +0, +-143418, +0, +-143483, +0, +-143548, +0, +-143613, +0, +-143678, +0, +-143744, +0, +-143809, +0, +-143874, +0, +-143940, +0, +-144005, +0, +-144070, +0, +-144135, +0, +-144201, +0, +-144266, +0, +-144332, +0, +-144397, +0, +-144462, +0, +-144528, +0, +-144593, +0, +-144659, +0, +-144724, +0, +-144790, +0, +-144855, +0, +-144921, +0, +-144986, +0, +-145052, +0, +-145117, +0, +-145183, +0, +-145248, +0, +-145314, +0, +-145380, +0, +-145445, +0, +-145511, +0, +-145577, +0, +-145642, +0, +-145708, +0, +-145774, +0, +-145840, +0, +-145905, +0, +-145971, +0, +-146037, +0, +-146103, +0, +-146169, +0, +-146234, +0, +-146300, +0, +-146366, +0, +-146432, +0, +-146498, +0, +-146564, +0, +-146630, +0, +-146696, +0, +-146762, +0, +-146828, +0, +-146894, +0, +-146960, +0, +-147026, +0, +-147092, +0, +-147158, +0, +-147224, +0, +-147290, +0, +-147356, +0, +-147422, +0, +-147488, +0, +-147555, +0, +-147621, +0, +-147687, +0, +-147753, +0, +-147819, +0, +-147886, +0, +-147952, +0, +-148018, +0, +-148084, +0, +-148151, +0, +-148217, +0, +-148283, +0, +-148350, +0, +-148416, +0, +-148482, +0, +-148549, +0, +-148615, +0, +-148682, +0, +-148748, +0, +-148815, +0, +-148881, +0, +-148948, +0, +-149014, +0, +-149081, +0, +-149147, +0, +-149214, +0, +-149280, +0, +-149347, +0, +-149413, +0, +-149480, +0, +-149547, +0, +-149613, +0, +-149680, +0, +-149747, +0, +-149813, +0, +-149880, +0, +-149947, +0, +-150014, +0, +-150080, +0, +-150147, +0, +-150214, +0, +-150281, +0, +-150348, +0, +-150414, +0, +-150481, +0, +-150548, +0, +-150615, +0, +-150682, +0, +-150749, +0, +-150816, +0, +-150883, +0, +-150950, +0, +-151017, +0, +-151084, +0, +-151151, +0, +-151218, +0, +-151285, +0, +-151352, +0, +-151419, +0, +-151486, +0, +-151553, +0, +-151620, +0, +-151687, +0, +-151755, +0, +-151822, +0, +-151889, +0, +-151956, +0, +-152023, +0, +-152091, +0, +-152158, +0, +-152225, +0, +-152292, +0, +-152360, +0, +-152427, +0, +-152494, +0, +-152562, +0, +-152629, +0, +-152696, +0, +-152764, +0, +-152831, +0, +-152899, +0, +-152966, +0, +-153034, +0, +-153101, +0, +-153169, +0, +-153236, +0, +-153304, +0, +-153371, +0, +-153439, +0, +-153506, +0, +-153574, +0, +-153642, +0, +-153709, +0, +-153777, +0, +-153844, +0, +-153912, +0, +-153980, +0, +-154048, +0, +-154115, +0, +-154183, +0, +-154251, +0, +-154319, +0, +-154386, +0, +-154454, +0, +-154522, +0, +-154590, +0, +-154658, +0, +-154725, +0, +-154793, +0, +-154861, +0, +-154929, +0, +-154997, +0, +-155065, +0, +-155133, +0, +-155201, +0, +-155269, +0, +-155337, +0, +-155405, +0, +-155473, +0, +-155541, +0, +-155609, +0, +-155677, +0, +-155745, +0, +-155813, +0, +-155882, +0, +-155950, +0, +-156018, +0, +-156086, +0, +-156154, +0, +-156222, +0, +-156291, +0, +-156359, +0, +-156427, +0, +-156495, +0, +-156564, +0, +-156632, +0, +-156700, +0, +-156769, +0, +-156837, +0, +-156905, +0, +-156974, +0, +-157042, +0, +-157111, +0, +-157179, +0, +-157248, +0, +-157316, +0, +-157385, +0, +-157453, +0, +-157522, +0, +-157590, +0, +-157659, +0, +-157727, +0, +-157796, +0, +-157864, +0, +-157933, +0, +-158002, +0, +-158070, +0, +-158139, +0, +-158208, +0, +-158276, +0, +-158345, +0, +-158414, +0, +-158482, +0, +-158551, +0, +-158620, +0, +-158689, +0, +-158758, +0, +-158826, +0, +-158895, +0, +-158964, +0, +-159033, +0, +-159102, +0, +-159171, +0, +-159240, +0, +-159309, +0, +-159378, +0, +-159447, +0, +-159516, +0, +-159516 diff --git a/rce/rcecalib/dataproc/fit/logx_ext_int.dat b/rce/rcecalib/dataproc/fit/logx_ext_int.dat new file mode 100644 index 0000000000000000000000000000000000000000..66719838698ca10bb468d2c238d0f40a8f1c7004 --- /dev/null +++ b/rce/rcecalib/dataproc/fit/logx_ext_int.dat @@ -0,0 +1,14002 @@ +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-13122363, +-2, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12716898, +-3, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12429216, +-4, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12206073, +-5, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-12023751, +-6, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11869600, +-7, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11736069, +-8, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11618286, +-9, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11512925, +-10, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11417615, +-11, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11330604, +-12, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11250561, +-13, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11176453, +-14, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11107460, +-15, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-11042922, +-16, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10982297, +-17, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10925139, +-18, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10871072, +-19, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10819778, +-20, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10770988, +-21, +-10724468, +-22, +-10724468, +-22, +-10724468, +-22, +-10724468, +-22, +-10724468, +-22, +-10724468, +-22, +-10724468, +-22, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10680016, +-23, +-10637457, +-24, +-10637457, +-24, +-10637457, +-24, +-10637457, +-24, +-10637457, +-24, +-10637457, +-24, +-10596635, +-25, +-10596635, +-25, +-10596635, +-25, +-10596635, +-25, +-10596635, +-25, +-10596635, +-25, +-10596635, +-25, +-10557414, +-26, +-10557414, +-26, +-10557414, +-26, +-10557414, +-26, +-10557414, +-26, +-10557414, +-26, +-10519674, +-27, +-10519674, +-27, +-10519674, +-27, +-10519674, +-27, +-10519674, +-27, +-10519674, +-27, +-10483306, +-28, +-10483306, +-28, +-10483306, +-28, +-10483306, +-28, +-10483306, +-28, +-10483306, +-28, +-10483306, +-28, +-10448215, +-29, +-10448215, +-29, +-10448215, +-29, +-10448215, +-29, +-10448215, +-29, +-10414313, +-30, +-10414313, +-30, +-10414313, +-30, +-10414313, +-30, +-10414313, +-30, +-10414313, +-30, +-10381523, +-31, +-10381523, +-31, +-10381523, +-31, +-10381523, +-31, +-10381523, +-31, +-10349775, +-32, +-10349775, +-32, +-10349775, +-32, +-10349775, +-32, +-10349775, +-32, +-10319003, +-33, +-10319003, +-33, +-10319003, +-33, +-10319003, +-33, +-10319003, +-33, +-10319003, +-33, +-10289150, +-34, +-10289150, +-34, +-10289150, +-34, +-10289150, +-34, +-10260162, +-35, +-10260162, +-35, +-10260162, +-35, +-10260162, +-35, +-10260162, +-35, +-10231992, +-36, +-10231992, +-36, +-10231992, +-36, +-10231992, +-36, +-10231992, +-36, +-10204593, +-37, +-10204593, +-37, +-10204593, +-37, +-10204593, +-37, +-10177924, +-38, +-10177924, +-38, +-10177924, +-38, +-10177924, +-38, +-10177924, +-38, +-10151949, +-39, +-10151949, +-39, +-10151949, +-39, +-10151949, +-39, +-10126631, +-40, +-10126631, +-40, +-10126631, +-40, +-10126631, +-40, +-10101939, +-41, +-10101939, +-41, +-10101939, +-41, +-10101939, +-41, +-10101939, +-41, +-10077841, +-42, +-10077841, +-42, +-10077841, +-42, +-10077841, +-42, +-10054310, +-43, +-10054310, +-43, +-10054310, +-43, +-10054310, +-43, +-10031321, +-44, +-10031321, +-44, +-10031321, +-44, +-10031321, +-44, +-10008848, +-45, +-10008848, +-45, +-10008848, +-45, +-9986869, +-46, +-9986869, +-46, +-9986869, +-46, +-9986869, +-46, +-9965363, +-47, +-9965363, +-47, +-9965363, +-47, +-9965363, +-47, +-9944310, +-48, +-9944310, +-48, +-9944310, +-48, +-9923690, +-49, +-9923690, +-49, +-9923690, +-49, +-9923690, +-49, +-9903488, +-50, +-9903488, +-50, +-9903488, +-50, +-9883685, +-51, +-9883685, +-51, +-9883685, +-51, +-9883685, +-51, +-9864267, +-52, +-9864267, +-52, +-9864267, +-52, +-9845219, +-53, +-9845219, +-53, +-9845219, +-53, +-9826527, +-54, +-9826527, +-54, +-9826527, +-54, +-9808177, +-55, +-9808177, +-55, +-9808177, +-55, +-9790159, +-56, +-9790159, +-56, +-9790159, +-56, +-9772459, +-57, +-9772459, +-57, +-9772459, +-57, +-9772459, +-57, +-9755068, +-58, +-9755068, +-58, +-9737973, +-59, +-9737973, +-59, +-9737973, +-59, +-9721166, +-60, +-9721166, +-60, +-9721166, +-60, +-9704637, +-61, +-9704637, +-61, +-9704637, +-61, +-9688376, +-62, +-9688376, +-62, +-9688376, +-62, +-9672376, +-63, +-9672376, +-63, +-9672376, +-63, +-9656627, +-64, +-9656627, +-64, +-9641123, +-65, +-9641123, +-65, +-9641123, +-65, +-9625856, +-66, +-9625856, +-66, +-9625856, +-66, +-9610818, +-67, +-9610818, +-67, +-9596003, +-68, +-9596003, +-68, +-9596003, +-68, +-9581404, +-69, +-9581404, +-69, +-9567015, +-70, +-9567015, +-70, +-9567015, +-70, +-9552831, +-71, +-9552831, +-71, +-9538844, +-72, +-9538844, +-72, +-9538844, +-72, +-9525051, +-73, +-9525051, +-73, +-9511445, +-74, +-9511445, +-74, +-9511445, +-74, +-9498022, +-75, +-9498022, +-75, +-9484777, +-76, +-9484777, +-76, +-9471705, +-77, +-9471705, +-77, +-9471705, +-77, +-9458802, +-78, +-9458802, +-78, +-9446063, +-79, +-9446063, +-79, +-9433484, +-80, +-9433484, +-80, +-9421061, +-81, +-9421061, +-81, +-9408791, +-82, +-9408791, +-82, +-9408791, +-82, +-9396670, +-83, +-9396670, +-83, +-9384694, +-84, +-9384694, +-84, +-9372859, +-85, +-9372859, +-85, +-9361163, +-86, +-9361163, +-86, +-9349602, +-87, +-9349602, +-87, +-9338174, +-88, +-9338174, +-88, +-9326874, +-89, +-9326874, +-89, +-9315701, +-90, +-9315701, +-90, +-9304651, +-91, +-9304651, +-91, +-9293722, +-92, +-9293722, +-92, +-9282911, +-93, +-9282911, +-93, +-9272216, +-94, +-9272216, +-94, +-9261634, +-95, +-9261634, +-95, +-9251162, +-96, +-9240800, +-97, +-9240800, +-97, +-9230543, +-98, +-9230543, +-98, +-9220391, +-99, +-9220391, +-99, +-9210340, +-100, +-9210340, +-100, +-9200390, +-101, +-9190538, +-102, +-9190538, +-102, +-9180782, +-103, +-9180782, +-103, +-9171120, +-104, +-9171120, +-104, +-9161550, +-105, +-9152071, +-106, +-9152071, +-106, +-9142682, +-107, +-9142682, +-107, +-9133379, +-108, +-9124163, +-109, +-9124163, +-109, +-9115030, +-110, +-9115030, +-110, +-9105980, +-111, +-9097012, +-112, +-9097012, +-112, +-9088123, +-113, +-9079312, +-114, +-9079312, +-114, +-9070578, +-115, +-9070578, +-115, +-9061920, +-116, +-9053337, +-117, +-9053337, +-117, +-9044826, +-118, +-9036387, +-119, +-9036387, +-119, +-9028019, +-120, +-9019720, +-121, +-9019720, +-121, +-9011490, +-122, +-9003326, +-123, +-9003326, +-123, +-8995229, +-124, +-8987197, +-125, +-8987197, +-125, +-8979229, +-126, +-8971323, +-127, +-8963480, +-128, +-8963480, +-128, +-8955698, +-129, +-8947976, +-130, +-8947976, +-130, +-8940313, +-131, +-8932709, +-132, +-8925161, +-133, +-8925161, +-133, +-8917671, +-134, +-8910236, +-135, +-8910236, +-135, +-8902856, +-136, +-8895530, +-137, +-8888257, +-138, +-8888257, +-138, +-8881037, +-139, +-8873868, +-140, +-8866751, +-141, +-8859683, +-142, +-8859683, +-142, +-8852666, +-143, +-8845697, +-144, +-8838777, +-145, +-8838777, +-145, +-8831904, +-146, +-8825078, +-147, +-8818298, +-148, +-8811564, +-149, +-8804875, +-150, +-8804875, +-150, +-8798231, +-151, +-8791630, +-152, +-8785073, +-153, +-8778558, +-154, +-8778558, +-154, +-8772085, +-155, +-8765655, +-156, +-8759265, +-157, +-8752916, +-158, +-8746606, +-159, +-8740337, +-160, +-8740337, +-160, +-8734106, +-161, +-8727914, +-162, +-8721760, +-163, +-8715644, +-164, +-8709565, +-165, +-8703523, +-166, +-8697517, +-167, +-8691547, +-168, +-8685612, +-169, +-8685612, +-169, +-8679712, +-170, +-8673847, +-171, +-8668016, +-172, +-8662219, +-173, +-8656455, +-174, +-8650725, +-175, +-8645027, +-176, +-8639361, +-177, +-8633727, +-178, +-8628125, +-179, +-8622554, +-180, +-8617014, +-181, +-8611504, +-182, +-8606024, +-183, +-8600575, +-184, +-8595155, +-185, +-8589764, +-186, +-8584402, +-187, +-8579069, +-188, +-8573764, +-189, +-8568486, +-190, +-8563237, +-191, +-8558015, +-192, +-8552820, +-193, +-8547652, +-194, +-8542511, +-195, +-8537396, +-196, +-8532307, +-197, +-8527244, +-198, +-8522206, +-199, +-8517193, +-200, +-8512206, +-201, +-8507243, +-202, +-8502305, +-203, +-8492501, +-205, +-8487634, +-206, +-8482792, +-207, +-8477972, +-208, +-8473176, +-209, +-8468403, +-210, +-8463652, +-211, +-8458924, +-212, +-8449535, +-214, +-8444873, +-215, +-8440232, +-216, +-8435613, +-217, +-8431015, +-218, +-8426439, +-219, +-8421883, +-220, +-8412833, +-222, +-8408339, +-223, +-8403864, +-224, +-8399410, +-225, +-8394976, +-226, +-8386165, +-228, +-8381788, +-229, +-8377431, +-230, +-8373093, +-231, +-8368772, +-232, +-8360189, +-234, +-8355924, +-235, +-8351679, +-236, +-8347450, +-237, +-8339047, +-239, +-8334872, +-240, +-8330714, +-241, +-8322449, +-243, +-8318341, +-244, +-8314252, +-245, +-8310179, +-246, +-8302082, +-248, +-8298057, +-248, +-8294050, +-250, +-8286080, +-252, +-8282121, +-253, +-8278176, +-254, +-8270333, +-256, +-8266434, +-257, +-8262551, +-258, +-8254829, +-260, +-8250990, +-261, +-8247166, +-262, +-8239561, +-264, +-8235780, +-265, +-8228262, +-267, +-8224524, +-268, +-8217089, +-270, +-8213392, +-271, +-8209707, +-272, +-8202382, +-274, +-8198739, +-275, +-8191492, +-277, +-8187889, +-278, +-8180721, +-280, +-8177156, +-281, +-8170064, +-283, +-8166536, +-284, +-8159518, +-286, +-8156027, +-287, +-8149084, +-289, +-8145630, +-290, +-8138757, +-292, +-8135338, +-293, +-8128534, +-295, +-8125151, +-296, +-8118417, +-298, +-8115067, +-299, +-8108400, +-301, +-8105084, +-302, +-8098483, +-304, +-8091925, +-306, +-8088663, +-307, +-8082169, +-309, +-8078938, +-310, +-8072507, +-312, +-8066117, +-314, +-8062938, +-315, +-8056609, +-317, +-8050319, +-319, +-8047190, +-320, +-8040959, +-322, +-8034767, +-324, +-8031684, +-325, +-8025550, +-327, +-8019453, +-329, +-8016418, +-330, +-8010376, +-332, +-8004370, +-334, +-8001379, +-335, +-7995428, +-337, +-7989510, +-339, +-7983628, +-341, +-7980700, +-342, +-7974869, +-344, +-7969072, +-346, +-7963308, +-348, +-7957577, +-350, +-7954724, +-351, +-7949042, +-353, +-7943393, +-355, +-7937775, +-357, +-7932188, +-359, +-7926633, +-361, +-7923866, +-362, +-7918357, +-364, +-7912877, +-366, +-7907428, +-368, +-7902008, +-370, +-7896617, +-372, +-7891255, +-374, +-7885921, +-376, +-7880616, +-378, +-7875339, +-380, +-7870090, +-382, +-7864868, +-384, +-7862267, +-385, +-7857086, +-387, +-7851931, +-389, +-7846803, +-391, +-7841701, +-393, +-7834096, +-396, +-7829059, +-398, +-7824046, +-400, +-7819058, +-402, +-7814096, +-404, +-7809157, +-406, +-7804243, +-408, +-7799353, +-410, +-7794487, +-412, +-7789645, +-414, +-7784825, +-416, +-7780029, +-418, +-7775256, +-420, +-7768138, +-423, +-7763421, +-425, +-7758727, +-427, +-7754054, +-429, +-7749402, +-431, +-7742466, +-434, +-7737868, +-436, +-7733292, +-438, +-7728736, +-440, +-7724201, +-442, +-7717436, +-445, +-7712952, +-447, +-7708488, +-449, +-7704043, +-451, +-7697413, +-454, +-7693018, +-456, +-7688641, +-458, +-7682113, +-461, +-7677783, +-463, +-7673473, +-465, +-7667042, +-468, +-7662778, +-470, +-7658532, +-472, +-7652196, +-475, +-7647994, +-477, +-7641724, +-480, +-7637566, +-482, +-7631362, +-485, +-7627246, +-487, +-7623148, +-488, +-7617032, +-492, +-7612975, +-494, +-7606921, +-497, +-7602904, +-499, +-7596910, +-501, +-7592934, +-504, +-7587000, +-506, +-7581100, +-510, +-7577186, +-512, +-7571344, +-515, +-7567468, +-517, +-7561682, +-520, +-7557843, +-522, +-7552112, +-525, +-7546414, +-528, +-7542634, +-530, +-7536989, +-533, +-7531376, +-536, +-7527652, +-538, +-7522091, +-541, +-7516561, +-544, +-7511062, +-547, +-7507412, +-549, +-7501962, +-552, +-7496542, +-555, +-7491152, +-558, +-7487574, +-560, +-7482231, +-563, +-7476916, +-566, +-7471630, +-569, +-7466372, +-572, +-7462881, +-574, +-7457668, +-577, +-7452482, +-580, +-7447323, +-583, +-7442191, +-586, +-7437084, +-589, +-7432004, +-592, +-7426949, +-595, +-7421920, +-598, +-7416916, +-601, +-7411936, +-604, +-7406982, +-607, +-7402052, +-610, +-7397146, +-613, +-7392264, +-616, +-7387405, +-619, +-7382570, +-622, +-7377759, +-625, +-7372970, +-628, +-7368205, +-631, +-7363462, +-634, +-7358741, +-637, +-7352481, +-641, +-7347812, +-644, +-7343164, +-647, +-7338538, +-650, +-7333933, +-653, +-7327827, +-657, +-7323271, +-660, +-7318736, +-663, +-7314221, +-666, +-7308233, +-670, +-7303765, +-673, +-7299317, +-676, +-7293418, +-680, +-7289016, +-683, +-7284633, +-686, +-7278819, +-690, +-7274481, +-693, +-7270161, +-696, +-7264430, +-700, +-7260154, +-703, +-7254480, +-707, +-7250246, +-710, +-7244628, +-714, +-7240435, +-717, +-7234871, +-721, +-7230719, +-724, +-7225209, +-728, +-7221097, +-731, +-7215640, +-735, +-7210213, +-739, +-7206161, +-742, +-7200785, +-746, +-7196772, +-749, +-7191445, +-753, +-7186147, +-757, +-7182192, +-760, +-7176943, +-764, +-7171721, +-768, +-7166526, +-772, +-7162647, +-775, +-7157500, +-779, +-7152378, +-783, +-7147282, +-787, +-7142213, +-791, +-7138427, +-794, +-7133402, +-798, +-7128402, +-802, +-7123427, +-806, +-7118476, +-810, +-7113550, +-814, +-7108648, +-818, +-7103770, +-822, +-7098916, +-826, +-7094085, +-830, +-7089277, +-834, +-7084492, +-838, +-7079731, +-842, +-7074991, +-846, +-7070274, +-850, +-7065579, +-854, +-7060906, +-858, +-7055096, +-863, +-7050472, +-867, +-7045869, +-871, +-7041287, +-875, +-7036726, +-879, +-7031054, +-884, +-7026539, +-888, +-7022044, +-892, +-7017570, +-896, +-7012005, +-901, +-7007576, +-905, +-7003165, +-909, +-6997680, +-914, +-6993313, +-918, +-6987881, +-923, +-6983557, +-927, +-6979251, +-931, +-6973895, +-936, +-6969631, +-940, +-6964326, +-945, +-6960102, +-949, +-6954847, +-954, +-6949619, +-959, +-6945457, +-963, +-6940278, +-968, +-6936155, +-972, +-6931024, +-977, +-6925919, +-982, +-6921854, +-985, +-6916796, +-990, +-6911763, +-995, +-6906756, +-1002, +-6902768, +-1006, +-6897805, +-1011, +-6892867, +-1016, +-6887953, +-1021, +-6883063, +-1026, +-6878196, +-1031, +-6874321, +-1035, +-6869497, +-1040, +-6864696, +-1045, +-6859918, +-1050, +-6855163, +-1055, +-6850430, +-1060, +-6845720, +-1065, +-6841032, +-1070, +-6836365, +-1075, +-6830794, +-1081, +-6826175, +-1086, +-6821578, +-1091, +-6817001, +-1096, +-6812445, +-1101, +-6807910, +-1106, +-6802495, +-1112, +-6798004, +-1117, +-6793534, +-1122, +-6789084, +-1127, +-6783769, +-1133, +-6779362, +-1138, +-6774974, +-1143, +-6769734, +-1149, +-6765388, +-1154, +-6760198, +-1160, +-6755893, +-1165, +-6750752, +-1171, +-6746487, +-1176, +-6741394, +-1182, +-6737169, +-1187, +-6732123, +-1193, +-6727937, +-1198, +-6722937, +-1204, +-6717962, +-1210, +-6713835, +-1215, +-6708904, +-1221, +-6703998, +-1227, +-6699116, +-1233, +-6695066, +-1238, +-6690227, +-1244, +-6685412, +-1250, +-6680620, +-1256, +-6675850, +-1262, +-6671103, +-1268, +-6666379, +-1274, +-6662459, +-1279, +-6657775, +-1285, +-6653113, +-1291, +-6648473, +-1297, +-6643086, +-1304, +-6638492, +-1310, +-6633919, +-1316, +-6629366, +-1322, +-6624835, +-1328, +-6620323, +-1334, +-6615832, +-1340, +-6610618, +-1347, +-6606170, +-1353, +-6601742, +-1359, +-6597334, +-1365, +-6592215, +-1372, +-6587848, +-1378, +-6582777, +-1385, +-6578452, +-1391, +-6573428, +-1398, +-6569142, +-1404, +-6564875, +-1410, +-6559919, +-1417, +-6554988, +-1424, +-6550780, +-1430, +-6545894, +-1437, +-6541724, +-1443, +-6536882, +-1450, +-6532062, +-1457, +-6527266, +-1464, +-6523173, +-1470, +-6518420, +-1477, +-6513688, +-1484, +-6508979, +-1491, +-6504292, +-1498, +-6500292, +-1504, +-6495646, +-1511, +-6491021, +-1518, +-6486417, +-1525, +-6481834, +-1532, +-6477272, +-1539, +-6472084, +-1547, +-6467567, +-1554, +-6463069, +-1561, +-6458592, +-1568, +-6454135, +-1575, +-6449698, +-1582, +-6444650, +-1590, +-6440255, +-1597, +-6435878, +-1604, +-6430900, +-1612, +-6426564, +-1619, +-6422247, +-1626, +-6417336, +-1634, +-6413059, +-1641, +-6408193, +-1649, +-6403954, +-1656, +-6399132, +-1664, +-6394932, +-1671, +-6390153, +-1679, +-6385396, +-1687, +-6381253, +-1694, +-6376539, +-1702, +-6371847, +-1710, +-6367177, +-1718, +-6362528, +-1726, +-6358478, +-1734, +-6353870, +-1742, +-6349283, +-1750, +-6344717, +-1758, +-6340171, +-1766, +-6335646, +-1774, +-6331142, +-1782, +-6326658, +-1790, +-6322193, +-1798, +-6317195, +-1807, +-6312772, +-1815, +-6308369, +-1823, +-6303986, +-1831, +-6299621, +-1839, +-6294734, +-1848, +-6290410, +-1856, +-6285567, +-1865, +-6281282, +-1873, +-6277016, +-1881, +-6272237, +-1890, +-6268009, +-1898, +-6263273, +-1907, +-6258560, +-1916, +-6254389, +-1924, +-6249717, +-1933, +-6245067, +-1942, +-6240952, +-1950, +-6236343, +-1958, +-6231754, +-1968, +-6227187, +-1977, +-6222640, +-1986, +-6218114, +-1994, +-6214108, +-2003, +-6209621, +-2012, +-6204658, +-2022, +-6200212, +-2030, +-6195786, +-2040, +-6191380, +-2049, +-6186993, +-2058, +-6182625, +-2067, +-6178276, +-2076, +-6173466, +-2086, +-6169157, +-2095, +-6164866, +-2104, +-6160120, +-2114, +-6155868, +-2123, +-6151164, +-2133, +-6146949, +-2142, +-6142287, +-2152, +-6138110, +-2161, +-6133489, +-2171, +-6128889, +-2181, +-6124767, +-2190, +-6120207, +-2200, +-6115668, +-2210, +-6111149, +-2220, +-6106651, +-2230, +-6102173, +-2241, +-6097714, +-2251, +-6093719, +-2260, +-6088857, +-2271, +-6084457, +-2281, +-6080077, +-2291, +-6075716, +-2301, +-6071374, +-2311, +-6067051, +-2321, +-6062316, +-2332, +-6058032, +-2342, +-6053766, +-2352, +-6049094, +-2363, +-6044865, +-2373, +-6040235, +-2384, +-6036044, +-2394, +-6031454, +-2405, +-6027299, +-2415, +-6022749, +-2426, +-6018219, +-2437, +-6014119, +-2447, +-6009628, +-2458, +-6005158, +-2469, +-6000707, +-2480, +-5996276, +-2491, +-5991865, +-2502, +-5987473, +-2513, +-5983100, +-2524, +-5978746, +-2535, +-5974411, +-2546, +-5970095, +-2557, +-5965797, +-2568, +-5961517, +-2579, +-5956870, +-2591, +-5952629, +-2602, +-5948022, +-2614, +-5943818, +-2625, +-5939631, +-2636, +-5935084, +-2649, +-5930558, +-2661, +-5926426, +-2672, +-5921939, +-2684, +-5917471, +-2696, +-5913393, +-2707, +-5908963, +-2719, +-5904553, +-2731, +-5900162, +-2743, +-5895791, +-2755, +-5891438, +-2767, +-5887105, +-2779, +-5882790, +-2791, +-5878493, +-2803, +-5874215, +-2815, +-5869955, +-2827, +-5865361, +-2840, +-5861138, +-2852, +-5856934, +-2864, +-5852399, +-2877, +-5848230, +-2889, +-5843734, +-2902, +-5839602, +-2914, +-5835145, +-2927, +-5830707, +-2940, +-5826628, +-2952, +-5822228, +-2965, +-5817847, +-2978, +-5813486, +-2991, +-5809143, +-3005, +-5804819, +-3018, +-5800514, +-3031, +-5796227, +-3044, +-5791958, +-3057, +-5787708, +-3070, +-5783475, +-3083, +-5779261, +-3096, +-5774742, +-3110, +-5770564, +-3123, +-5766083, +-3137, +-5761941, +-3150, +-5757500, +-3164, +-5753393, +-3177, +-5748989, +-3191, +-5744917, +-3204, +-5740550, +-3218, +-5736202, +-3232, +-5731873, +-3246, +-5727563, +-3260, +-5723271, +-3274, +-5718998, +-3288, +-5714742, +-3302, +-5710505, +-3316, +-5706286, +-3331, +-5702084, +-3345, +-5697602, +-3360, +-5693436, +-3374, +-5689288, +-3388, +-5684863, +-3403, +-5680750, +-3417, +-5676362, +-3432, +-5672284, +-3446, +-5667933, +-3461, +-5663601, +-3476, +-5659287, +-3491, +-5655278, +-3505, +-5651000, +-3520, +-5646741, +-3535, +-5642499, +-3550, +-5638276, +-3565, +-5634070, +-3580, +-5629603, +-3596, +-5625434, +-3612, +-5621281, +-3627, +-5617146, +-3642, +-5612754, +-3658, +-5608654, +-3673, +-5604299, +-3689, +-5600234, +-3704, +-5595915, +-3720, +-5591615, +-3736, +-5587334, +-3752, +-5583336, +-3767, +-5579090, +-3783, +-5574862, +-3799, +-5570651, +-3815, +-5566458, +-3831, +-5562283, +-3847, +-5557866, +-3864, +-5553726, +-3881, +-5549603, +-3897, +-5545498, +-3913, +-5541154, +-3930, +-5537082, +-3946, +-5532775, +-3963, +-5528486, +-3980, +-5524465, +-3996, +-5520212, +-4013, +-5515976, +-4029, +-5511758, +-4047, +-5507558, +-4064, +-5503375, +-4081, +-5499210, +-4098, +-5495062, +-4115, +-5490932, +-4133, +-5486818, +-4150, +-5482721, +-4167, +-5478401, +-4185, +-5474339, +-4202, +-5470055, +-4220, +-5466026, +-4237, +-5461778, +-4255, +-5457548, +-4273, +-5453335, +-4291, +-5449373, +-4308, +-5445195, +-4326, +-5441034, +-4344, +-5436890, +-4363, +-5432763, +-4381, +-5428426, +-4400, +-5424334, +-4418, +-5420259, +-4436, +-5416200, +-4454, +-5411934, +-4473, +-5407909, +-4491, +-5403678, +-4510, +-5399465, +-4529, +-5395489, +-4547, +-5391310, +-4566, +-5387149, +-4585, +-5383004, +-4605, +-5378877, +-4624, +-5374767, +-4643, +-5370673, +-4662, +-5366596, +-4681, +-5362323, +-4701, +-5358280, +-4720, +-5354253, +-4739, +-5350032, +-4759, +-5346038, +-4778, +-5341851, +-4798, +-5337682, +-4819, +-5333530, +-4839, +-5329602, +-4858, +-5325483, +-4878, +-5321381, +-4898, +-5317296, +-4918, +-5313025, +-4939, +-5308974, +-4959, +-5304939, +-4979, +-5300921, +-4999, +-5296719, +-5021, +-5292733, +-5041, +-5288565, +-5062, +-5284414, +-5083, +-5280477, +-5103, +-5276360, +-5124, +-5272260, +-5145, +-5268176, +-5166, +-5264109, +-5187, +-5260059, +-5209, +-5256024, +-5230, +-5251816, +-5252, +-5247814, +-5273, +-5243829, +-5294, +-5239671, +-5316, +-5235530, +-5338, +-5231594, +-5359, +-5227486, +-5381, +-5223395, +-5404, +-5219321, +-5426, +-5215264, +-5448, +-5211223, +-5470, +-5207198, +-5492, +-5203189, +-5514, +-5199196, +-5536, +-5195039, +-5559, +-5191079, +-5582, +-5186955, +-5605, +-5183026, +-5627, +-5178936, +-5650, +-5174862, +-5673, +-5170804, +-5696, +-5166763, +-5719, +-5162738, +-5742, +-5158729, +-5766, +-5154737, +-5789, +-5150760, +-5812, +-5146627, +-5836, +-5142682, +-5859, +-5138582, +-5883, +-5134669, +-5906, +-5130602, +-5931, +-5126551, +-5955, +-5122517, +-5979, +-5118666, +-6002, +-5114497, +-6027, +-5110511, +-6051, +-5106541, +-6075, +-5102586, +-6100, +-5098483, +-6125, +-5094561, +-6149, +-5090491, +-6174, +-5086599, +-6198, +-5082561, +-6223, +-5078539, +-6248, +-5074534, +-6274, +-5070545, +-6299, +-5066571, +-6324, +-5062613, +-6349, +-5058671, +-6374, +-5054744, +-6399, +-5050676, +-6426, +-5046781, +-6451, +-5042745, +-6477, +-5038726, +-6503, +-5034877, +-6528, +-5030889, +-6554, +-5026917, +-6581, +-5022961, +-6607, +-5018869, +-6634, +-5014945, +-6660, +-5011035, +-6686, +-5006992, +-6713, +-5003114, +-6740, +-4999102, +-6767, +-4995254, +-6793, +-4991274, +-6820, +-4987309, +-6847, +-4983361, +-6875, +-4979427, +-6902, +-4975509, +-6929, +-4971463, +-6957, +-4967576, +-6984, +-4963561, +-7013, +-4959705, +-7040, +-4955721, +-7068, +-4951753, +-7096, +-4947942, +-7123, +-4944005, +-7152, +-4940084, +-7180, +-4936038, +-7209, +-4932148, +-7237, +-4928272, +-7265, +-4924274, +-7295, +-4920429, +-7323, +-4916462, +-7352, +-4912647, +-7380, +-4908711, +-7409, +-4904790, +-7439, +-4900884, +-7468, +-4896994, +-7497, +-4892986, +-7527, +-4889126, +-7556, +-4885281, +-7586, +-4881319, +-7616, +-4877373, +-7646, +-4873573, +-7675, +-4869657, +-7706, +-4865756, +-7736, +-4861870, +-7766, +-4858000, +-7796, +-4854144, +-7827, +-4850176, +-7858, +-4846350, +-7887, +-4842413, +-7919, +-4838490, +-7951, +-4834709, +-7981, +-4830817, +-8012, +-4826940, +-8043, +-4823077, +-8075, +-4819230, +-8106, +-4815274, +-8137, +-4811457, +-8168, +-4807531, +-8202, +-4803743, +-8233, +-4799848, +-8265, +-4795968, +-8297, +-4792102, +-8330, +-4788252, +-8362, +-4784416, +-8394, +-4780596, +-8426, +-4776671, +-8460, +-4772879, +-8492, +-4768984, +-8525, +-4765222, +-8558, +-4761356, +-8591, +-4757506, +-8624, +-4753670, +-8657, +-4749849, +-8691, +-4745928, +-8725, +-4742136, +-8758, +-4738245, +-8793, +-4734482, +-8826, +-4730620, +-8860, +-4726773, +-8894, +-4722941, +-8929, +-4719123, +-8963, +-4715320, +-8997, +-4711531, +-9032, +-4707646, +-9067, +-4703886, +-9101, +-4700030, +-9137, +-4696190, +-9172, +-4692473, +-9206, +-4688661, +-9242, +-4684863, +-9277, +-4680972, +-9313, +-4677203, +-9349, +-4673449, +-9384, +-4669602, +-9420, +-4665770, +-9457, +-4661952, +-9493, +-4658255, +-9528, +-4654360, +-9566, +-4650586, +-9602, +-4646826, +-9638, +-4643080, +-9675, +-4639244, +-9712, +-4635423, +-9749, +-4631720, +-9786, +-4627927, +-9823, +-4624149, +-9860, +-4620385, +-9898, +-4616535, +-9936, +-4612799, +-9974, +-4609078, +-10011, +-4605270, +-10049, +-4601477, +-10088, +-4597698, +-10126, +-4593934, +-10164, +-4590183, +-10203, +-4586447, +-10241, +-4582724, +-10280, +-4578918, +-10319, +-4575126, +-10358, +-4571445, +-10397, +-4567682, +-10436, +-4563932, +-10476, +-4560197, +-10515, +-4556380, +-10556, +-4552673, +-10595, +-4548884, +-10635, +-4545205, +-10675, +-4541445, +-10715, +-4537698, +-10756, +-4533966, +-10796, +-4530248, +-10837, +-4526544, +-10877, +-4522761, +-10918, +-4519084, +-10959, +-4515329, +-11000, +-4511589, +-11042, +-4507862, +-11083, +-4504149, +-11125, +-4500450, +-11166, +-4496675, +-11209, +-4493003, +-11250, +-4489256, +-11293, +-4485611, +-11334, +-4481891, +-11376, +-4478185, +-11419, +-4474405, +-11462, +-4470727, +-11505, +-4467062, +-11547, +-4463323, +-11591, +-4459599, +-11634, +-4455975, +-11677, +-4452277, +-11720, +-4448508, +-11765, +-4444839, +-11808, +-4441182, +-11852, +-4437455, +-11896, +-4433825, +-11940, +-4430125, +-11985, +-4426438, +-12029, +-4422765, +-12074, +-4419023, +-12119, +-4415377, +-12164, +-4411661, +-12209, +-4408042, +-12254, +-4404354, +-12299, +-4400680, +-12345, +-4397018, +-12390, +-4393371, +-12436, +-4389656, +-12483, +-4386035, +-12528, +-4382347, +-12575, +-4378672, +-12621, +-4375011, +-12668, +-4371364, +-12714, +-4367729, +-12761, +-4364108, +-12808, +-4360422, +-12855, +-4356749, +-12903, +-4353089, +-12950, +-4349443, +-12998, +-4345810, +-13046, +-4342191, +-13093, +-4338584, +-13141, +-4334914, +-13190, +-4331257, +-13238, +-4327614, +-13287, +-4323984, +-13336, +-4320367, +-13384, +-4316763, +-13433, +-4313098, +-13482, +-4309520, +-13531, +-4305881, +-13581, +-4302255, +-13630, +-4298642, +-13680, +-4294969, +-13731, +-4291382, +-13781, +-4287735, +-13831, +-4284174, +-13881, +-4280554, +-13932, +-4276946, +-13982, +-4273352, +-14033, +-4269698, +-14085, +-4266130, +-14135, +-4262503, +-14187, +-4258889, +-14239, +-4255288, +-14291, +-4251700, +-14342, +-4248125, +-14394, +-4244493, +-14447, +-4240944, +-14499, +-4237338, +-14551, +-4233745, +-14604, +-4230164, +-14657, +-4226597, +-14710, +-4222974, +-14763, +-4219432, +-14816, +-4215834, +-14870, +-4212250, +-14924, +-4208679, +-14978, +-4205120, +-15031, +-4201573, +-15085, +-4197973, +-15140, +-4194386, +-15195, +-4190811, +-15250, +-4187249, +-15305, +-4183700, +-15359, +-4180164, +-15414, +-4176574, +-15470, +-4172997, +-15526, +-4169499, +-15581, +-4165948, +-15637, +-4162345, +-15694, +-4158819, +-15749, +-4155242, +-15806, +-4151741, +-15862, +-4148189, +-15919, +-4144649, +-15976, +-4141059, +-16034, +-4137544, +-16091, +-4133980, +-16149, +-4130490, +-16206, +-4126950, +-16264, +-4123423, +-16320, +-4119847, +-16379, +-4116345, +-16438, +-4112794, +-16497, +-4109315, +-16555, +-4105790, +-16614, +-4102216, +-16674, +-4098714, +-16733, +-4095225, +-16792, +-4091688, +-16852, +-4088164, +-16912, +-4084652, +-16972, +-4081152, +-17032, +-4077664, +-17092, +-4074130, +-17153, +-4070608, +-17214, +-4067099, +-17275, +-4063602, +-17336, +-4060117, +-17397, +-4056644, +-17459, +-4053126, +-17521, +-4049620, +-17583, +-4046126, +-17645, +-4042644, +-17707, +-4039175, +-17769, +-4035661, +-17832, +-4032159, +-17895, +-4028669, +-17958, +-4025191, +-18021, +-4021726, +-18085, +-4018272, +-18148, +-4014776, +-18212, +-4011291, +-18276, +-4007818, +-18340, +-4004358, +-18404, +-4000854, +-18470, +-3997417, +-18534, +-3993938, +-18599, +-3990471, +-18664, +-3987016, +-18729, +-3983573, +-18795, +-3980088, +-18861, +-3976615, +-18927, +-3973154, +-18993, +-3969705, +-19059, +-3966268, +-19126, +-3962843, +-19192, +-3959377, +-19259, +-3955923, +-19327, +-3952480, +-19394, +-3949050, +-19461, +-3945580, +-19529, +-3942173, +-19597, +-3938726, +-19665, +-3935292, +-19733, +-3931818, +-19803, +-3928407, +-19871, +-3924956, +-19940, +-3921568, +-20009, +-3918142, +-20078, +-3914677, +-20149, +-3911273, +-20218, +-3907832, +-20288, +-3904452, +-20358, +-3900984, +-20429, +-3897578, +-20500, +-3894183, +-20570, +-3890751, +-20642, +-3887330, +-20713, +-3883922, +-20785, +-3880524, +-20856, +-3877139, +-20927, +-3873716, +-21000, +-3870305, +-21072, +-3866906, +-21145, +-3863519, +-21218, +-3860142, +-21290, +-3856730, +-21364, +-3853330, +-21437, +-3849941, +-21511, +-3846563, +-21584, +-3843150, +-21659, +-3839795, +-21732, +-3836405, +-21807, +-3833027, +-21882, +-3829614, +-21957, +-3826258, +-22032, +-3822868, +-22108, +-3819489, +-22183, +-3816122, +-22259, +-3812721, +-22336, +-3809376, +-22411, +-3805998, +-22488, +-3802631, +-22565, +-3799275, +-22641, +-3795886, +-22719, +-3792552, +-22796, +-3789186, +-22874, +-3785831, +-22951, +-3782487, +-23029, +-3779111, +-23108, +-3775745, +-23187, +-3772392, +-23266, +-3769049, +-23344, +-3765717, +-23423, +-3762354, +-23503, +-3759002, +-23583, +-3755661, +-23663, +-3752331, +-23743, +-3749012, +-23823, +-3745661, +-23903, +-3742322, +-23984, +-3738994, +-24065, +-3735678, +-24146, +-3732330, +-24228, +-3728993, +-24310, +-3725668, +-24392, +-3722354, +-24474, +-3719009, +-24557, +-3715716, +-24639, +-3712394, +-24722, +-3709082, +-24805, +-3705741, +-24889, +-3702451, +-24972, +-3699132, +-25056, +-3695824, +-25140, +-3692486, +-25226, +-3689199, +-25310, +-3685884, +-25395, +-3682579, +-25480, +-3679286, +-25565, +-3676003, +-25650, +-3672691, +-25736, +-3669391, +-25823, +-3666101, +-25909, +-3662822, +-25995, +-3659515, +-26082, +-3656219, +-26169, +-3652933, +-26257, +-3649659, +-26344, +-3646356, +-26432, +-3643065, +-26521, +-3639785, +-26609, +-3636515, +-26697, +-3633256, +-26786, +-3629969, +-26875, +-3626694, +-26964, +-3623429, +-27054, +-3620137, +-27144, +-3616894, +-27233, +-3613624, +-27324, +-3610364, +-27414, +-3607078, +-27506, +-3603840, +-27596, +-3600576, +-27688, +-3597322, +-27779, +-3594042, +-27872, +-3590809, +-27963, +-3587551, +-28056, +-3584303, +-28148, +-3581066, +-28241, +-3577803, +-28335, +-3574551, +-28428, +-3571310, +-28522, +-3568079, +-28616, +-3564823, +-28710, +-3561577, +-28805, +-3558343, +-28900, +-3555118, +-28994, +-3551904, +-29089, +-3548665, +-29185, +-3545437, +-29281, +-3542185, +-29377, +-3538978, +-29473, +-3535746, +-29570, +-3532525, +-29667, +-3529315, +-29764, +-3526081, +-29861, +-3522857, +-29959, +-3519643, +-30057, +-3516440, +-30155, +-3513213, +-30254, +-3510031, +-30352, +-3506825, +-30451, +-3503596, +-30551, +-3500410, +-30650, +-3497202, +-30750, +-3494004, +-30850, +-3490783, +-30951, +-3487605, +-31051, +-3484405, +-31152, +-3481215, +-31253, +-3478003, +-31355, +-3474833, +-31457, +-3471641, +-31558, +-3468428, +-31662, +-3465256, +-31764, +-3462063, +-31867, +-3458879, +-31971, +-3455706, +-32074, +-3452543, +-32176, +-3449359, +-32280, +-3446184, +-32385, +-3443020, +-32489, +-3439834, +-32596, +-3436659, +-32701, +-3433493, +-32806, +-3430338, +-32912, +-3427162, +-33018, +-3423995, +-33125, +-3420839, +-33231, +-3417693, +-33338, +-3414526, +-33445, +-3411369, +-33553, +-3408222, +-33660, +-3405055, +-33769, +-3401898, +-33877, +-3398750, +-33986, +-3395613, +-34095, +-3392456, +-34204, +-3389338, +-34313, +-3386171, +-34424, +-3383043, +-34533, +-3379896, +-34644, +-3376758, +-34755, +-3373631, +-34866, +-3370513, +-34977, +-3367376, +-35088, +-3364248, +-35200, +-3361102, +-35313, +-3357994, +-35425, +-3354867, +-35538, +-3351750, +-35651, +-3348614, +-35765, +-3345488, +-35879, +-3342372, +-35993, +-3339265, +-36107, +-3336140, +-36222, +-3333053, +-36336, +-3329919, +-36452, +-3326823, +-36568, +-3323709, +-36684, +-3320604, +-36800, +-3317509, +-36916, +-3314396, +-37033, +-3311293, +-37151, +-3308199, +-37268, +-3305115, +-37385, +-3302013, +-37504, +-3298921, +-37622, +-3295838, +-37740, +-3292738, +-37860, +-3289647, +-37979, +-3286566, +-38099, +-3283494, +-38218, +-3280406, +-38339, +-3277326, +-38459, +-3274230, +-38581, +-3271170, +-38701, +-3268092, +-38823, +-3265024, +-38945, +-3261940, +-39067, +-3258865, +-39190, +-3255799, +-39313, +-3252743, +-39435, +-3249670, +-39559, +-3246607, +-39683, +-3243553, +-39807, +-3240483, +-39932, +-3237422, +-40057, +-3234370, +-40182, +-3231303, +-40308, +-3228270, +-40432, +-3225221, +-40558, +-3222156, +-40686, +-3219126, +-40812, +-3216080, +-40939, +-3213018, +-41067, +-3209990, +-41194, +-3206947, +-41322, +-3203913, +-41450, +-3200864, +-41580, +-3197824, +-41709, +-3194793, +-41838, +-3191771, +-41967, +-3188735, +-42098, +-3185707, +-42228, +-3182689, +-42359, +-3179655, +-42490, +-3176631, +-42622, +-3173616, +-42753, +-3170586, +-42886, +-3167565, +-43018, +-3164553, +-43151, +-3161527, +-43284, +-3158534, +-43417, +-3155502, +-43552, +-3152503, +-43685, +-3149490, +-43820, +-3146485, +-43955, +-3143490, +-44090, +-3140481, +-44226, +-3137480, +-44362, +-3134489, +-44497, +-3131483, +-44634, +-3128487, +-44771, +-3125499, +-44908, +-3122498, +-45047, +-3119506, +-45185, +-3116522, +-45323, +-3113548, +-45461, +-3110560, +-45600, +-3107558, +-45740, +-3104588, +-45880, +-3101604, +-46020, +-3098629, +-46160, +-3095663, +-46301, +-3092684, +-46442, +-3089713, +-46583, +-3086730, +-46726, +-3083755, +-46868, +-3080789, +-47011, +-3077832, +-47153, +-3074862, +-47297, +-3071901, +-47441, +-3068948, +-47584, +-3065983, +-47729, +-3063027, +-47874, +-3060079, +-48019, +-3057118, +-48165, +-3054167, +-48310, +-3051203, +-48457, +-3048268, +-48603, +-3045322, +-48750, +-3042363, +-48898, +-3039433, +-49045, +-3036492, +-49193, +-3033538, +-49343, +-3030614, +-49491, +-3027677, +-49640, +-3024729, +-49790, +-3021809, +-49939, +-3018878, +-50090, +-3015935, +-50241, +-3013021, +-50392, +-3010075, +-50544, +-3007157, +-50696, +-3004228, +-50848, +-3001308, +-51001, +-2998396, +-51153, +-2995472, +-51307, +-2992557, +-51461, +-2989651, +-51614, +-2986733, +-51769, +-2983823, +-51924, +-2980922, +-52079, +-2978010, +-52235, +-2975106, +-52391, +-2972192, +-52548, +-2969305, +-52704, +-2966387, +-52862, +-2963497, +-53019, +-2960597, +-53177, +-2957705, +-53335, +-2954802, +-53495, +-2951926, +-53653, +-2949020, +-53813, +-2946142, +-53973, +-2943254, +-54133, +-2940373, +-54294, +-2937482, +-54455, +-2934600, +-54617, +-2931725, +-54778, +-2928840, +-54941, +-2925964, +-55104, +-2923095, +-55266, +-2920217, +-55430, +-2917346, +-55594, +-2914484, +-55758, +-2911612, +-55923, +-2908748, +-56088, +-2905873, +-56254, +-2903025, +-56419, +-2900149, +-56586, +-2897300, +-56752, +-2894440, +-56920, +-2891588, +-57087, +-2888727, +-57255, +-2885874, +-57424, +-2883029, +-57592, +-2880174, +-57762, +-2877327, +-57931, +-2874489, +-58101, +-2871640, +-58271, +-2868800, +-58442, +-2865950, +-58614, +-2863126, +-58784, +-2860275, +-58957, +-2857450, +-59129, +-2854615, +-59302, +-2851788, +-59475, +-2848952, +-59649, +-2846123, +-59823, +-2843303, +-59997, +-2840474, +-60173, +-2837652, +-60348, +-2834822, +-60524, +-2831999, +-60701, +-2829185, +-60877, +-2826378, +-61053, +-2823562, +-61231, +-2820737, +-61410, +-2817938, +-61587, +-2815129, +-61766, +-2812311, +-61946, +-2809502, +-62125, +-2806700, +-62305, +-2803906, +-62485, +-2801103, +-62666, +-2798292, +-62848, +-2795505, +-63029, +-2792710, +-63211, +-2789906, +-63395, +-2787126, +-63576, +-2784321, +-63761, +-2781541, +-63945, +-2778752, +-64129, +-2775970, +-64312, +-2773181, +-64499, +-2770399, +-64685, +-2767625, +-64870, +-2764843, +-65057, +-2762068, +-65244, +-2759286, +-65432, +-2756511, +-65620, +-2753743, +-65808, +-2750968, +-65997, +-2748201, +-66186, +-2745441, +-66375, +-2742673, +-66565, +-2739912, +-66755, +-2737144, +-66947, +-2734384, +-67138, +-2731631, +-67330, +-2728870, +-67522, +-2726117, +-67715, +-2723357, +-67908, +-2720604, +-68102, +-2717858, +-68296, +-2715105, +-68491, +-2712359, +-68686, +-2709621, +-68881, +-2706876, +-69077, +-2704138, +-69273, +-2701392, +-69470, +-2698655, +-69667, +-2695924, +-69865, +-2693186, +-70063, +-2690456, +-70262, +-2687718, +-70461, +-2684988, +-70661, +-2682266, +-70860, +-2679536, +-71061, +-2676813, +-71262, +-2674098, +-71463, +-2671376, +-71665, +-2668647, +-71868, +-2665939, +-72070, +-2663211, +-72274, +-2660504, +-72477, +-2657790, +-72681, +-2655083, +-72886, +-2652370, +-73091, +-2649663, +-73297, +-2646950, +-73503, +-2644259, +-73709, +-2641546, +-73917, +-2638855, +-74124, +-2636158, +-74331, +-2633453, +-74540, +-2630756, +-74749, +-2628066, +-74958, +-2625369, +-75169, +-2622680, +-75379, +-2619998, +-75589, +-2617310, +-75801, +-2614614, +-76013, +-2611940, +-76225, +-2609260, +-76437, +-2606573, +-76651, +-2603893, +-76865, +-2601220, +-77079, +-2598541, +-77294, +-2595870, +-77509, +-2593191, +-77725, +-2590534, +-77940, +-2587857, +-78157, +-2585187, +-78375, +-2582524, +-78592, +-2579868, +-78809, +-2577206, +-79028, +-2574538, +-79248, +-2571877, +-79468, +-2569223, +-79687, +-2566577, +-79907, +-2563924, +-80128, +-2561265, +-80350, +-2558613, +-80573, +-2555969, +-80795, +-2553318, +-81018, +-2550675, +-81242, +-2548038, +-81465, +-2545396, +-81690, +-2542748, +-81915, +-2540119, +-82140, +-2537472, +-82367, +-2534845, +-82593, +-2532212, +-82820, +-2529574, +-83048, +-2526954, +-83275, +-2524317, +-83504, +-2521699, +-83733, +-2519076, +-83962, +-2516447, +-84193, +-2513825, +-84423, +-2511210, +-84654, +-2508589, +-84886, +-2505975, +-85118, +-2503356, +-85351, +-2500743, +-85584, +-2498138, +-85817, +-2495527, +-86051, +-2492911, +-86287, +-2490313, +-86521, +-2487711, +-86757, +-2485103, +-86994, +-2482502, +-87230, +-2479907, +-87467, +-2477308, +-87705, +-2474703, +-87944, +-2472117, +-88182, +-2469526, +-88421, +-2466929, +-88662, +-2464340, +-88902, +-2461757, +-89143, +-2459169, +-89384, +-2456587, +-89626, +-2454001, +-89869, +-2451422, +-90112, +-2448837, +-90356, +-2446259, +-90600, +-2443688, +-90844, +-2441112, +-91089, +-2438542, +-91335, +-2435968, +-91581, +-2433400, +-91828, +-2430828, +-92076, +-2428262, +-92324, +-2425702, +-92572, +-2423138, +-92821, +-2420581, +-93070, +-2418018, +-93320, +-2415463, +-93570, +-2412902, +-93822, +-2410349, +-94073, +-2407801, +-94325, +-2405249, +-94578, +-2402704, +-94831, +-2400154, +-95085, +-2397610, +-95339, +-2395062, +-95594, +-2392521, +-95849, +-2389975, +-96106, +-2387446, +-96361, +-2384902, +-96619, +-2382365, +-96877, +-2379833, +-97134, +-2377298, +-97393, +-2374769, +-97653, +-2372246, +-97912, +-2369719, +-98172, +-2367188, +-98433, +-2364663, +-98695, +-2362144, +-98957, +-2359621, +-99219, +-2357105, +-99482, +-2354584, +-99746, +-2352069, +-100010, +-2349551, +-100276, +-2347039, +-100541, +-2344533, +-100806, +-2342023, +-101073, +-2339519, +-101340, +-2337011, +-101608, +-2334509, +-101875, +-2332004, +-102145, +-2329504, +-102414, +-2327001, +-102684, +-2324504, +-102955, +-2322013, +-103225, +-2319518, +-103497, +-2317019, +-103770, +-2314536, +-104041, +-2312040, +-104316, +-2309559, +-104589, +-2307075, +-104863, +-2304587, +-105138, +-2302105, +-105414, +-2299620, +-105691, +-2297140, +-105967, +-2294667, +-106244, +-2292189, +-106522, +-2289718, +-106800, +-2287243, +-107080, +-2284775, +-107359, +-2282302, +-107640, +-2279836, +-107920, +-2277376, +-108201, +-2274912, +-108483, +-2272444, +-108766, +-2269982, +-109050, +-2267527, +-109333, +-2265068, +-109617, +-2262615, +-109902, +-2260158, +-110188, +-2257707, +-110474, +-2255253, +-110761, +-2252805, +-111048, +-2250353, +-111336, +-2247908, +-111625, +-2245468, +-111913, +-2243025, +-112203, +-2240587, +-112493, +-2238147, +-112784, +-2235702, +-113076, +-2233274, +-113367, +-2230832, +-113660, +-2228406, +-113953, +-2225976, +-114247, +-2223543, +-114541, +-2221116, +-114836, +-2218685, +-115133, +-2216261, +-115429, +-2213842, +-115725, +-2211420, +-116023, +-2209004, +-116320, +-2206584, +-116619, +-2204171, +-116918, +-2201754, +-117218, +-2199343, +-117519, +-2196929, +-117820, +-2194520, +-118122, +-2192109, +-118424, +-2189703, +-118727, +-2187303, +-119030, +-2184900, +-119334, +-2182494, +-119640, +-2180093, +-119945, +-2177698, +-120251, +-2175301, +-120558, +-2172909, +-120865, +-2170514, +-121173, +-2168124, +-121481, +-2165732, +-121790, +-2163345, +-122100, +-2160955, +-122411, +-2158571, +-122721, +-2156193, +-123032, +-2153812, +-123345, +-2151427, +-123658, +-2149049, +-123972, +-2146676, +-124285, +-2144300, +-124600, +-2141921, +-124916, +-2139557, +-125231, +-2137181, +-125548, +-2134811, +-125866, +-2132446, +-126183, +-2130078, +-126502, +-2127716, +-126820, +-2125360, +-127140, +-2123001, +-127460, +-2120639, +-127782, +-2118282, +-128104, +-2115923, +-128427, +-2113569, +-128750, +-2111221, +-129073, +-2108870, +-129397, +-2106525, +-129722, +-2104177, +-130047, +-2101826, +-130373, +-2099481, +-130701, +-2097141, +-131028, +-2094799, +-131357, +-2092461, +-131685, +-2090122, +-132015, +-2087788, +-132345, +-2085459, +-132675, +-2083120, +-133007, +-2080794, +-133338, +-2078466, +-133671, +-2076134, +-134005, +-2073808, +-134339, +-2071489, +-134673, +-2069166, +-135008, +-2066841, +-135344, +-2064521, +-135681, +-2062207, +-136018, +-2059890, +-136356, +-2057578, +-136694, +-2055264, +-137034, +-2052954, +-137373, +-2050644, +-137714, +-2048331, +-138056, +-2046030, +-138397, +-2043727, +-138739, +-2041421, +-139083, +-2039121, +-139426, +-2036819, +-139771, +-2034522, +-140116, +-2032222, +-140463, +-2029928, +-140809, +-2027639, +-141156, +-2025347, +-141504, +-2023054, +-141853, +-2020765, +-142202, +-2018482, +-142551, +-2016195, +-142902, +-2013907, +-143254, +-2011632, +-143605, +-2009348, +-143958, +-2007069, +-144312, +-2004794, +-144665, +-2002517, +-145020, +-2000246, +-145375, +-1997972, +-145731, +-1995703, +-146088, +-1993433, +-146445, +-1991167, +-146803, +-1988899, +-147162, +-1986636, +-147521, +-1984379, +-147881, +-1982112, +-148242, +-1979857, +-148603, +-1977600, +-148965, +-1975341, +-149329, +-1973087, +-149692, +-1970838, +-150056, +-1968587, +-150421, +-1966334, +-150787, +-1964086, +-151153, +-1961843, +-151520, +-1959598, +-151887, +-1957351, +-152256, +-1955109, +-152626, +-1952872, +-152995, +-1950633, +-153366, +-1948399, +-153736, +-1946163, +-154109, +-1943932, +-154481, +-1941699, +-154854, +-1939471, +-155228, +-1937241, +-155603, +-1935016, +-155978, +-1932789, +-156354, +-1930567, +-156731, +-1928342, +-157109, +-1926123, +-157487, +-1923902, +-157866, +-1921686, +-158246, +-1919475, +-158625, +-1917261, +-159006, +-1915046, +-159389, +-1912836, +-159771, +-1910631, +-160153, +-1908417, +-160539, +-1906215, +-160923, +-1904010, +-161308, +-1901811, +-161693, +-1899610, +-162080, +-1897407, +-162468, +-1895208, +-162857, +-1893015, +-163245, +-1890820, +-163635, +-1888629, +-164025, +-1886437, +-164416, +-1884243, +-164809, +-1882061, +-165200, +-1879870, +-165594, +-1877690, +-165987, +-1875502, +-166383, +-1873325, +-166777, +-1871140, +-167174, +-1868967, +-167570, +-1866785, +-167969, +-1864614, +-168367, +-1862442, +-168765, +-1860267, +-169166, +-1858098, +-169566, +-1855927, +-169968, +-1853760, +-170370, +-1851592, +-170773, +-1849429, +-171176, +-1847270, +-171580, +-1845110, +-171985, +-1842947, +-172391, +-1840790, +-172797, +-1838637, +-173204, +-1836483, +-173612, +-1834327, +-174021, +-1832175, +-174431, +-1830028, +-174840, +-1827880, +-175251, +-1825736, +-175663, +-1823591, +-176075, +-1821444, +-176489, +-1819307, +-176902, +-1817163, +-177317, +-1815024, +-177733, +-1812889, +-178149, +-1810753, +-178566, +-1808621, +-178983, +-1806487, +-179402, +-1804358, +-179821, +-1802228, +-180241, +-1800102, +-180661, +-1797975, +-181083, +-1795852, +-181505, +-1793733, +-181927, +-1791607, +-182352, +-1789492, +-182776, +-1787375, +-183201, +-1785257, +-183627, +-1783143, +-184054, +-1781033, +-184481, +-1778922, +-184909, +-1776810, +-185338, +-1774702, +-185768, +-1772598, +-186198, +-1770493, +-186630, +-1768387, +-187062, +-1766285, +-187495, +-1764187, +-187928, +-1762088, +-188363, +-1759988, +-188799, +-1757897, +-189234, +-1755800, +-189671, +-1753707, +-190109, +-1751618, +-190547, +-1749528, +-190986, +-1747442, +-191426, +-1745355, +-191867, +-1743272, +-192308, +-1741188, +-192750, +-1739108, +-193193, +-1737027, +-193637, +-1734950, +-194081, +-1732878, +-194526, +-1730804, +-194972, +-1728728, +-195419, +-1726657, +-195866, +-1724585, +-196315, +-1722517, +-196765, +-1720453, +-197214, +-1718388, +-197665, +-1716322, +-198117, +-1714260, +-198569, +-1712202, +-199022, +-1710143, +-199476, +-1708082, +-199931, +-1706026, +-200387, +-1703974, +-200843, +-1701921, +-201300, +-1699872, +-201758, +-1697821, +-202217, +-1695775, +-202676, +-1693728, +-203136, +-1691684, +-203597, +-1689640, +-204059, +-1687599, +-204522, +-1685558, +-204986, +-1683521, +-205450, +-1681482, +-205915, +-1679447, +-206381, +-1677417, +-206847, +-1675385, +-207314, +-1673353, +-207783, +-1671324, +-208252, +-1669294, +-208723, +-1667268, +-209194, +-1665247, +-209665, +-1663224, +-210137, +-1661205, +-210610, +-1659185, +-211084, +-1657164, +-211560, +-1655152, +-212034, +-1653134, +-212512, +-1651120, +-212989, +-1649110, +-213467, +-1647098, +-213946, +-1645091, +-214425, +-1643083, +-214906, +-1641078, +-215387, +-1639078, +-215869, +-1637071, +-216353, +-1635074, +-216836, +-1633075, +-217321, +-1631075, +-217807, +-1629080, +-218293, +-1627088, +-218779, +-1625095, +-219267, +-1623101, +-219757, +-1621111, +-220246, +-1619125, +-220736, +-1617137, +-221228, +-1615154, +-221720, +-1613170, +-222213, +-1611189, +-222706, +-1609208, +-223201, +-1607230, +-223696, +-1605252, +-224193, +-1603277, +-224690, +-1601301, +-225188, +-1599329, +-225687, +-1597361, +-226186, +-1595392, +-226686, +-1593422, +-227188, +-1591456, +-227690, +-1589493, +-228193, +-1587530, +-228696, +-1585565, +-229202, +-1583609, +-229706, +-1581648, +-230213, +-1579690, +-230721, +-1577736, +-231229, +-1575781, +-231738, +-1573829, +-232247, +-1571882, +-232757, +-1569934, +-233268, +-1567984, +-233781, +-1566038, +-234294, +-1564092, +-234809, +-1562149, +-235324, +-1560210, +-235839, +-1558270, +-236355, +-1556333, +-236872, +-1554396, +-237391, +-1552458, +-237911, +-1550528, +-238430, +-1548592, +-238952, +-1546665, +-239472, +-1544737, +-239995, +-1542808, +-240519, +-1540882, +-241043, +-1538956, +-241569, +-1537034, +-242094, +-1535115, +-242621, +-1533195, +-243149, +-1531279, +-243677, +-1529361, +-244206, +-1527443, +-244738, +-1525533, +-245268, +-1523618, +-245801, +-1521711, +-246333, +-1519803, +-246866, +-1517894, +-247402, +-1515989, +-247937, +-1514082, +-248474, +-1512180, +-249012, +-1510281, +-249549, +-1508381, +-250087, +-1506484, +-250628, +-1504587, +-251168, +-1502693, +-251710, +-1500799, +-252253, +-1498908, +-252796, +-1497016, +-253340, +-1495128, +-253886, +-1493243, +-254432, +-1491357, +-254979, +-1489471, +-255527, +-1487588, +-256076, +-1485708, +-256625, +-1483828, +-257176, +-1481951, +-257726, +-1480073, +-258280, +-1478199, +-258832, +-1476324, +-259388, +-1474453, +-259942, +-1472585, +-260498, +-1470716, +-261054, +-1468846, +-261612, +-1466984, +-262170, +-1465117, +-262731, +-1463257, +-263290, +-1461393, +-263852, +-1459536, +-264414, +-1457679, +-264976, +-1455820, +-265541, +-1453965, +-266106, +-1452114, +-266671, +-1450261, +-267238, +-1448412, +-267805, +-1446563, +-268374, +-1444716, +-268943, +-1442869, +-269513, +-1441025, +-270084, +-1439181, +-270657, +-1437339, +-271230, +-1435501, +-271803, +-1433663, +-272378, +-1431827, +-272954, +-1429991, +-273531, +-1428159, +-274108, +-1426325, +-274687, +-1424495, +-275266, +-1422668, +-275846, +-1420840, +-276427, +-1419012, +-277010, +-1417191, +-277592, +-1415365, +-278177, +-1413546, +-278761, +-1411727, +-279346, +-1409907, +-279934, +-1408090, +-280521, +-1406277, +-281109, +-1404462, +-281699, +-1402651, +-282289, +-1400840, +-282880, +-1399031, +-283472, +-1397222, +-284066, +-1395416, +-284660, +-1393613, +-285254, +-1391810, +-285850, +-1390009, +-286447, +-1388208, +-287045, +-1386410, +-287643, +-1384612, +-288244, +-1382816, +-288844, +-1381024, +-289445, +-1379231, +-290048, +-1377438, +-290652, +-1375651, +-291255, +-1373864, +-291860, +-1372076, +-292467, +-1370291, +-293074, +-1368509, +-293681, +-1366727, +-294291, +-1364944, +-294901, +-1363168, +-295511, +-1361391, +-296123, +-1359613, +-296736, +-1357839, +-297350, +-1356068, +-297964, +-1354296, +-298580, +-1352527, +-299196, +-1350757, +-299814, +-1348991, +-300432, +-1347224, +-301052, +-1345463, +-301671, +-1343699, +-302294, +-1341941, +-302915, +-1340178, +-303539, +-1338423, +-304162, +-1336666, +-304788, +-1334909, +-305414, +-1333159, +-306040, +-1331405, +-306669, +-1329657, +-307297, +-1327908, +-307927, +-1326159, +-308558, +-1324417, +-309189, +-1322670, +-309823, +-1320930, +-310455, +-1319185, +-311091, +-1317448, +-311726, +-1315709, +-312363, +-1313974, +-313000, +-1312237, +-313639, +-1310504, +-314278, +-1308771, +-314919, +-1307040, +-315560, +-1305312, +-316202, +-1303583, +-316846, +-1301858, +-317490, +-1300135, +-318134, +-1298412, +-318781, +-1296688, +-319429, +-1294970, +-320076, +-1293249, +-320726, +-1291533, +-321375, +-1289818, +-322026, +-1288105, +-322678, +-1286391, +-323331, +-1284680, +-323985, +-1282969, +-324641, +-1281261, +-325297, +-1279555, +-325953, +-1277849, +-326611, +-1276146, +-327270, +-1274442, +-327931, +-1272744, +-328590, +-1271043, +-329253, +-1269347, +-329915, +-1267648, +-330580, +-1265955, +-331244, +-1264261, +-331910, +-1262570, +-332576, +-1260878, +-333244, +-1259190, +-333913, +-1257504, +-334582, +-1255817, +-335253, +-1254133, +-335925, +-1252449, +-336598, +-1250767, +-337272, +-1249089, +-337946, +-1247409, +-338622, +-1245733, +-339298, +-1244059, +-339975, +-1242384, +-340654, +-1240709, +-341335, +-1239041, +-342014, +-1237371, +-342696, +-1235701, +-343379, +-1234037, +-344062, +-1232369, +-344748, +-1230707, +-345433, +-1229045, +-346119, +-1227385, +-346807, +-1225724, +-347496, +-1224067, +-348185, +-1222412, +-348875, +-1220756, +-349567, +-1219103, +-350260, +-1217450, +-350954, +-1215799, +-351649, +-1214151, +-352344, +-1212502, +-353042, +-1210856, +-353739, +-1209213, +-354437, +-1207569, +-355138, +-1205928, +-355838, +-1204290, +-356539, +-1202650, +-357242, +-1201014, +-357946, +-1199377, +-358651, +-1197742, +-359357, +-1196111, +-360064, +-1194478, +-360772, +-1192848, +-361481, +-1191221, +-362190, +-1189593, +-362901, +-1187968, +-363613, +-1186346, +-364326, +-1184723, +-365040, +-1183102, +-365755, +-1181481, +-366471, +-1179866, +-367187, +-1178247, +-367906, +-1176633, +-368625, +-1175019, +-369345, +-1173408, +-370066, +-1171796, +-370788, +-1170187, +-371512, +-1168580, +-372235, +-1166973, +-372961, +-1165368, +-373687, +-1163765, +-374414, +-1162163, +-375143, +-1160562, +-375872, +-1158964, +-376602, +-1157366, +-377334, +-1155770, +-378066, +-1154174, +-378801, +-1152580, +-379536, +-1150988, +-380271, +-1149399, +-381007, +-1147810, +-381745, +-1146223, +-382484, +-1144638, +-383223, +-1143053, +-383964, +-1141471, +-384706, +-1139887, +-385449, +-1138307, +-386193, +-1136729, +-386938, +-1135153, +-387684, +-1133576, +-388431, +-1132003, +-389179, +-1130428, +-389929, +-1128856, +-390679, +-1127286, +-391431, +-1125719, +-392182, +-1124152, +-392936, +-1122586, +-393690, +-1121024, +-394445, +-1119460, +-395202, +-1117899, +-395959, +-1116337, +-396719, +-1114781, +-397478, +-1113225, +-398238, +-1111667, +-399001, +-1110112, +-399764, +-1108560, +-400528, +-1107009, +-401293, +-1105459, +-402059, +-1103910, +-402827, +-1102364, +-403594, +-1100821, +-404363, +-1099277, +-405133, +-1097732, +-405906, +-1096192, +-406677, +-1094652, +-407451, +-1093114, +-408225, +-1091576, +-409002, +-1090043, +-409777, +-1088510, +-410555, +-1086975, +-411335, +-1085443, +-412115, +-1083914, +-412896, +-1082387, +-413678, +-1080859, +-414461, +-1079336, +-415244, +-1077810, +-416031, +-1076289, +-416816, +-1074768, +-417604, +-1073249, +-418392, +-1071729, +-419183, +-1070214, +-419972, +-1068699, +-420764, +-1067183, +-421558, +-1065673, +-422351, +-1064162, +-423146, +-1062653, +-423942, +-1061143, +-424740, +-1059636, +-425538, +-1058131, +-426337, +-1056628, +-427137, +-1055125, +-427939, +-1053624, +-428742, +-1052125, +-429545, +-1050625, +-430351, +-1049131, +-431155, +-1047633, +-431964, +-1046140, +-432771, +-1044647, +-433581, +-1043156, +-434391, +-1041666, +-435202, +-1040180, +-436013, +-1038693, +-436827, +-1037207, +-437642, +-1035725, +-438457, +-1034241, +-439274, +-1032759, +-440092, +-1031280, +-440911, +-1029801, +-441732, +-1028326, +-442552, +-1026851, +-443374, +-1025374, +-444199, +-1023903, +-445022, +-1022432, +-445848, +-1020963, +-446675, +-1019495, +-447502, +-1018027, +-448331, +-1016561, +-449162, +-1015098, +-449992, +-1013636, +-450824, +-1012173, +-451658, +-1010713, +-452492, +-1009255, +-453327, +-1007798, +-454165, +-1006343, +-455002, +-1004890, +-455840, +-1003438, +-456680, +-1001984, +-457522, +-1000534, +-458364, +-999086, +-459208, +-997639, +-460052, +-996195, +-460896, +-994750, +-461743, +-993307, +-462591, +-991866, +-463440, +-990424, +-464290, +-988985, +-465142, +-987548, +-465994, +-986113, +-466847, +-984679, +-467701, +-983246, +-468557, +-981814, +-469413, +-980384, +-470271, +-978954, +-471131, +-977525, +-471991, +-976102, +-472851, +-974675, +-473715, +-973253, +-474577, +-971830, +-475442, +-970409, +-476308, +-968990, +-477175, +-967574, +-478042, +-966156, +-478912, +-964743, +-479781, +-963327, +-480654, +-961916, +-481526, +-960506, +-482399, +-959096, +-483274, +-957688, +-484150, +-956282, +-485026, +-954876, +-485905, +-953474, +-486784, +-952071, +-487664, +-950670, +-488546, +-949271, +-489428, +-947872, +-490312, +-946474, +-491198, +-945079, +-492084, +-943685, +-492971, +-942293, +-493859, +-940901, +-494749, +-939511, +-495640, +-938122, +-496532, +-936736, +-497424, +-935351, +-498318, +-933966, +-499213, +-932583, +-500110, +-931201, +-501007, +-929822, +-501905, +-928442, +-502806, +-927064, +-503708, +-925690, +-504607, +-924313, +-505513, +-922940, +-506417, +-921570, +-507322, +-920198, +-508229, +-918829, +-509136, +-917461, +-510046, +-916096, +-510955, +-914729, +-511868, +-913365, +-512781, +-912005, +-513692, +-910642, +-514609, +-909283, +-515525, +-907926, +-516441, +-906568, +-517360, +-905212, +-518279, +-903858, +-519201, +-902506, +-520122, +-901156, +-521043, +-899805, +-521969, +-898456, +-522895, +-897108, +-523821, +-895763, +-524749, +-894419, +-525677, +-893075, +-526608, +-891735, +-527538, +-890394, +-528470, +-889055, +-529404, +-887718, +-530338, +-886380, +-531275, +-885046, +-532211, +-883712, +-533150, +-882380, +-534089, +-881049, +-535030, +-879720, +-535971, +-878393, +-536913, +-877065, +-537858, +-875739, +-538803, +-874415, +-539750, +-873092, +-540697, +-871772, +-541646, +-870453, +-542595, +-869133, +-543547, +-867817, +-544498, +-866501, +-545452, +-865187, +-546406, +-863874, +-547362, +-862560, +-548320, +-861251, +-549277, +-859941, +-550237, +-858633, +-551198, +-857326, +-552160, +-856021, +-553123, +-854718, +-554086, +-853417, +-555051, +-852115, +-556018, +-850817, +-556985, +-849518, +-557954, +-848221, +-558924, +-846926, +-559895, +-845630, +-560869, +-844338, +-561842, +-843047, +-562816, +-841756, +-563792, +-840467, +-564770, +-839179, +-565748, +-837893, +-566728, +-836609, +-567708, +-835326, +-568690, +-834043, +-569674, +-832763, +-570657, +-831483, +-571643, +-830205, +-572630, +-828928, +-573618, +-827653, +-574607, +-826379, +-575597, +-825105, +-576590, +-823835, +-577582, +-822564, +-578576, +-821297, +-579570, +-820029, +-580567, +-818763, +-581565, +-817498, +-582563, +-816235, +-583563, +-814971, +-584565, +-813712, +-585567, +-812451, +-586572, +-811195, +-587575, +-809937, +-588582, +-808681, +-589589, +-807427, +-590598, +-806175, +-591607, +-804924, +-592618, +-803674, +-593630, +-802424, +-594644, +-801178, +-595658, +-799931, +-596674, +-798688, +-597690, +-797444, +-598708, +-796201, +-599728, +-794961, +-600749, +-793721, +-601770, +-792484, +-602793, +-791245, +-603818, +-790011, +-604843, +-788777, +-605869, +-787544, +-606898, +-786311, +-607928, +-785083, +-608957, +-783853, +-609989, +-782626, +-611022, +-781399, +-612056, +-780175, +-613091, +-778951, +-614127, +-777729, +-615164, +-776507, +-616205, +-775288, +-617244, +-774069, +-618286, +-772853, +-619328, +-771636, +-620373, +-770424, +-621416, +-769210, +-622463, +-767998, +-623511, +-766787, +-624560, +-765578, +-625610, +-764370, +-626661, +-763164, +-627713, +-761959, +-628767, +-760754, +-629823, +-759552, +-630879, +-758352, +-631935, +-757150, +-632995, +-755953, +-634054, +-754755, +-635116, +-753558, +-636179, +-752364, +-637241, +-751170, +-638307, +-749978, +-639373, +-748787, +-640441, +-747597, +-641510, +-746409, +-642580, +-745222, +-643651, +-744036, +-644723, +-742852, +-645796, +-741670, +-646871, +-740488, +-647946, +-739308, +-649023, +-738128, +-650103, +-736951, +-651182, +-735773, +-652264, +-734599, +-653346, +-733426, +-654429, +-732252, +-655514, +-731082, +-656599, +-729911, +-657687, +-728741, +-658777, +-727575, +-659865, +-726408, +-660957, +-725243, +-662050, +-724079, +-663144, +-722918, +-664237, +-721757, +-665334, +-720596, +-666431, +-719438, +-667530, +-718280, +-668630, +-717124, +-669731, +-715970, +-670834, +-714816, +-671938, +-713664, +-673043, +-712514, +-674149, +-711364, +-675256, +-710216, +-676365, +-709069, +-677475, +-707924, +-678586, +-706780, +-679698, +-705637, +-680812, +-704495, +-681926, +-703355, +-683042, +-702214, +-684162, +-701077, +-685280, +-699940, +-686400, +-698805, +-687521, +-697671, +-688643, +-696539, +-689767, +-695406, +-690894, +-694276, +-692020, +-693147, +-693147, +-693147, +-693147, +-693147, +-693147, +-692020, +-694276, +-690894, +-695406, +-689767, +-696539, +-688643, +-697671, +-687521, +-698805, +-686400, +-699940, +-685280, +-701077, +-684162, +-702214, +-683042, +-703355, +-681926, +-704495, +-680812, +-705637, +-679698, +-706780, +-678586, +-707924, +-677475, +-709069, +-676365, +-710216, +-675256, +-711364, +-674149, +-712514, +-673043, +-713664, +-671938, +-714816, +-670834, +-715970, +-669731, +-717124, +-668630, +-718280, +-667530, +-719438, +-666431, +-720596, +-665334, +-721757, +-664237, +-722918, +-663144, +-724079, +-662050, +-725243, +-660957, +-726408, +-659865, +-727575, +-658777, +-728741, +-657687, +-729911, +-656599, +-731082, +-655514, +-732252, +-654429, +-733426, +-653346, +-734599, +-652264, +-735773, +-651182, +-736951, +-650103, +-738128, +-649023, +-739308, +-647946, +-740488, +-646871, +-741670, +-645796, +-742852, +-644723, +-744036, +-643651, +-745222, +-642580, +-746409, +-641510, +-747597, +-640441, +-748787, +-639373, +-749978, +-638307, +-751170, +-637241, +-752364, +-636179, +-753558, +-635116, +-754755, +-634054, +-755953, +-632995, +-757150, +-631935, +-758351, +-630879, +-759552, +-629823, +-760754, +-628767, +-761959, +-627713, +-763164, +-626661, +-764370, +-625610, +-765578, +-624560, +-766787, +-623511, +-767998, +-622463, +-769210, +-621416, +-770424, +-620373, +-771636, +-619328, +-772853, +-618286, +-774069, +-617244, +-775288, +-616205, +-776507, +-615164, +-777730, +-614127, +-778951, +-613091, +-780175, +-612056, +-781399, +-611022, +-782626, +-609989, +-783853, +-608957, +-785083, +-607928, +-786311, +-606898, +-787544, +-605869, +-788777, +-604843, +-790011, +-603818, +-791245, +-602793, +-792484, +-601770, +-793721, +-600749, +-794961, +-599728, +-796201, +-598708, +-797444, +-597690, +-798688, +-596674, +-799931, +-595658, +-801178, +-594644, +-802424, +-593630, +-803674, +-592618, +-804924, +-591607, +-806175, +-590598, +-807427, +-589589, +-808681, +-588582, +-809937, +-587575, +-811195, +-586572, +-812451, +-585567, +-813712, +-584565, +-814971, +-583563, +-816235, +-582563, +-817498, +-581565, +-818763, +-580567, +-820029, +-579570, +-821297, +-578576, +-822564, +-577582, +-823835, +-576590, +-825105, +-575597, +-826379, +-574607, +-827653, +-573618, +-828928, +-572630, +-830205, +-571643, +-831483, +-570657, +-832763, +-569674, +-834043, +-568690, +-835326, +-567708, +-836609, +-566728, +-837893, +-565748, +-839179, +-564770, +-840467, +-563792, +-841756, +-562816, +-843047, +-561842, +-844338, +-560869, +-845630, +-559895, +-846926, +-558924, +-848221, +-557954, +-849518, +-556985, +-850817, +-556018, +-852115, +-555051, +-853417, +-554086, +-854718, +-553123, +-856022, +-552160, +-857326, +-551198, +-858633, +-550237, +-859941, +-549277, +-861251, +-548320, +-862560, +-547362, +-863874, +-546406, +-865187, +-545452, +-866501, +-544498, +-867817, +-543547, +-869133, +-542595, +-870452, +-541646, +-871772, +-540697, +-873092, +-539750, +-874415, +-538803, +-875739, +-537858, +-877065, +-536913, +-878393, +-535971, +-879720, +-535030, +-881049, +-534089, +-882380, +-533150, +-883712, +-532211, +-885046, +-531275, +-886380, +-530338, +-887718, +-529404, +-889055, +-528470, +-890394, +-527538, +-891735, +-526608, +-893075, +-525677, +-894419, +-524749, +-895763, +-523821, +-897108, +-522895, +-898456, +-521969, +-899805, +-521043, +-901156, +-520122, +-902506, +-519201, +-903858, +-518279, +-905212, +-517360, +-906568, +-516441, +-907926, +-515525, +-909283, +-514609, +-910642, +-513692, +-912005, +-512781, +-913365, +-511868, +-914729, +-510955, +-916096, +-510046, +-917461, +-509136, +-918829, +-508229, +-920198, +-507322, +-921570, +-506417, +-922940, +-505513, +-924313, +-504607, +-925690, +-503708, +-927064, +-502806, +-928442, +-501905, +-929822, +-501007, +-931201, +-500110, +-932583, +-499213, +-933966, +-498318, +-935351, +-497424, +-936736, +-496532, +-938122, +-495640, +-939511, +-494749, +-940901, +-493859, +-942293, +-492971, +-943685, +-492084, +-945079, +-491198, +-946474, +-490312, +-947872, +-489428, +-949271, +-488546, +-950670, +-487664, +-952071, +-486784, +-953474, +-485905, +-954876, +-485026, +-956282, +-484150, +-957688, +-483274, +-959097, +-482399, +-960506, +-481526, +-961916, +-480654, +-963327, +-479781, +-964743, +-478912, +-966156, +-478042, +-967574, +-477175, +-968990, +-476308, +-970409, +-475442, +-971830, +-474577, +-973253, +-473714, +-974675, +-472851, +-976102, +-471991, +-977525, +-471131, +-978954, +-470271, +-980384, +-469413, +-981814, +-468557, +-983245, +-467701, +-984679, +-466847, +-986113, +-465994, +-987548, +-465142, +-988985, +-464290, +-990424, +-463440, +-991866, +-462591, +-993307, +-461743, +-994750, +-460896, +-996195, +-460052, +-997639, +-459208, +-999086, +-458364, +-1000534, +-457522, +-1001984, +-456680, +-1003438, +-455840, +-1004890, +-455002, +-1006343, +-454165, +-1007798, +-453327, +-1009255, +-452492, +-1010713, +-451658, +-1012173, +-450824, +-1013636, +-449992, +-1015098, +-449162, +-1016561, +-448331, +-1018027, +-447502, +-1019495, +-446675, +-1020963, +-445848, +-1022432, +-445022, +-1023903, +-444199, +-1025374, +-443374, +-1026851, +-442552, +-1028326, +-441732, +-1029801, +-440911, +-1031280, +-440092, +-1032759, +-439274, +-1034241, +-438457, +-1035725, +-437642, +-1037207, +-436827, +-1038693, +-436013, +-1040180, +-435202, +-1041666, +-434391, +-1043156, +-433581, +-1044647, +-432771, +-1046140, +-431964, +-1047633, +-431155, +-1049131, +-430351, +-1050625, +-429545, +-1052125, +-428742, +-1053624, +-427939, +-1055125, +-427137, +-1056628, +-426337, +-1058131, +-425538, +-1059636, +-424740, +-1061143, +-423942, +-1062653, +-423146, +-1064162, +-422351, +-1065673, +-421558, +-1067183, +-420764, +-1068699, +-419972, +-1070214, +-419183, +-1071729, +-418392, +-1073249, +-417604, +-1074768, +-416816, +-1076289, +-416031, +-1077810, +-415244, +-1079336, +-414461, +-1080859, +-413678, +-1082387, +-412896, +-1083914, +-412115, +-1085443, +-411335, +-1086975, +-410555, +-1088509, +-409777, +-1090043, +-409002, +-1091576, +-408225, +-1093114, +-407451, +-1094652, +-406677, +-1096192, +-405906, +-1097732, +-405133, +-1099277, +-404363, +-1100821, +-403594, +-1102364, +-402827, +-1103910, +-402059, +-1105459, +-401293, +-1107009, +-400528, +-1108560, +-399764, +-1110112, +-399001, +-1111667, +-398238, +-1113225, +-397478, +-1114781, +-396719, +-1116338, +-395959, +-1117899, +-395202, +-1119460, +-394445, +-1121024, +-393690, +-1122586, +-392936, +-1124152, +-392182, +-1125719, +-391431, +-1127286, +-390679, +-1128856, +-389929, +-1130428, +-389179, +-1132003, +-388431, +-1133577, +-387684, +-1135153, +-386938, +-1136729, +-386194, +-1138307, +-385449, +-1139888, +-384706, +-1141471, +-383964, +-1143053, +-383223, +-1144638, +-382484, +-1146223, +-381745, +-1147810, +-381007, +-1149399, +-380271, +-1150988, +-379536, +-1152580, +-378801, +-1154174, +-378066, +-1155770, +-377334, +-1157366, +-376602, +-1158964, +-375872, +-1160562, +-375143, +-1162163, +-374414, +-1163765, +-373687, +-1165368, +-372961, +-1166972, +-372235, +-1168580, +-371512, +-1170187, +-370788, +-1171796, +-370066, +-1173408, +-369345, +-1175019, +-368625, +-1176633, +-367906, +-1178247, +-367187, +-1179866, +-366471, +-1181481, +-365755, +-1183102, +-365040, +-1184723, +-364326, +-1186346, +-363613, +-1187968, +-362901, +-1189593, +-362190, +-1191221, +-361481, +-1192848, +-360772, +-1194478, +-360064, +-1196111, +-359357, +-1197742, +-358651, +-1199377, +-357946, +-1201014, +-357242, +-1202650, +-356539, +-1204290, +-355838, +-1205928, +-355138, +-1207569, +-354437, +-1209213, +-353739, +-1210857, +-353042, +-1212503, +-352344, +-1214151, +-351649, +-1215799, +-350954, +-1217450, +-350260, +-1219103, +-349567, +-1220756, +-348875, +-1222412, +-348185, +-1224067, +-347496, +-1225724, +-346807, +-1227385, +-346119, +-1229044, +-345433, +-1230707, +-344748, +-1232369, +-344062, +-1234037, +-343379, +-1235701, +-342696, +-1237371, +-342014, +-1239041, +-341335, +-1240709, +-340654, +-1242385, +-339975, +-1244059, +-339298, +-1245733, +-338622, +-1247409, +-337946, +-1249089, +-337272, +-1250768, +-336598, +-1252449, +-335925, +-1254133, +-335253, +-1255817, +-334582, +-1257504, +-333913, +-1259190, +-333244, +-1260878, +-332576, +-1262570, +-331910, +-1264261, +-331244, +-1265955, +-330580, +-1267648, +-329915, +-1269347, +-329253, +-1271043, +-328590, +-1272744, +-327931, +-1274442, +-327270, +-1276146, +-326611, +-1277849, +-325953, +-1279555, +-325297, +-1281261, +-324641, +-1282969, +-323985, +-1284680, +-323331, +-1286391, +-322678, +-1288105, +-322026, +-1289818, +-321375, +-1291533, +-320726, +-1293249, +-320076, +-1294970, +-319429, +-1296688, +-318781, +-1298412, +-318134, +-1300135, +-317490, +-1301858, +-316846, +-1303583, +-316202, +-1305312, +-315560, +-1307040, +-314919, +-1308771, +-314278, +-1310504, +-313639, +-1312237, +-313000, +-1313974, +-312363, +-1315709, +-311726, +-1317448, +-311091, +-1319185, +-310455, +-1320930, +-309823, +-1322670, +-309189, +-1324417, +-308558, +-1326159, +-307927, +-1327909, +-307297, +-1329657, +-306669, +-1331405, +-306040, +-1333159, +-305414, +-1334910, +-304788, +-1336666, +-304162, +-1338423, +-303539, +-1340178, +-302915, +-1341941, +-302294, +-1343699, +-301671, +-1345463, +-301052, +-1347224, +-300432, +-1348991, +-299814, +-1350757, +-299196, +-1352527, +-298580, +-1354296, +-297964, +-1356068, +-297350, +-1357839, +-296736, +-1359613, +-296123, +-1361391, +-295511, +-1363168, +-294901, +-1364944, +-294290, +-1366727, +-293681, +-1368509, +-293074, +-1370291, +-292467, +-1372076, +-291860, +-1373864, +-291255, +-1375651, +-290652, +-1377438, +-290048, +-1379231, +-289445, +-1381024, +-288844, +-1382816, +-288244, +-1384612, +-287643, +-1386410, +-287045, +-1388208, +-286447, +-1390009, +-285850, +-1391810, +-285254, +-1393613, +-284660, +-1395416, +-284066, +-1397222, +-283472, +-1399031, +-282880, +-1400840, +-282289, +-1402651, +-281699, +-1404462, +-281109, +-1406277, +-280521, +-1408090, +-279934, +-1409907, +-279346, +-1411727, +-278761, +-1413546, +-278177, +-1415365, +-277592, +-1417191, +-277010, +-1419012, +-276427, +-1420840, +-275846, +-1422668, +-275266, +-1424495, +-274687, +-1426325, +-274108, +-1428158, +-273531, +-1429991, +-272954, +-1431827, +-272378, +-1433663, +-271803, +-1435501, +-271230, +-1437339, +-270657, +-1439181, +-270084, +-1441025, +-269513, +-1442869, +-268943, +-1444716, +-268374, +-1446562, +-267805, +-1448412, +-267238, +-1450261, +-266671, +-1452114, +-266106, +-1453965, +-265541, +-1455820, +-264976, +-1457679, +-264414, +-1459536, +-263852, +-1461393, +-263290, +-1463257, +-262731, +-1465117, +-262170, +-1466984, +-261612, +-1468846, +-261054, +-1470716, +-260498, +-1472585, +-259942, +-1474453, +-259386, +-1476324, +-258832, +-1478199, +-258280, +-1480073, +-257726, +-1481951, +-257176, +-1483828, +-256625, +-1485708, +-256076, +-1487588, +-255527, +-1489471, +-254979, +-1491357, +-254432, +-1493243, +-253886, +-1495128, +-253340, +-1497016, +-252796, +-1498908, +-252253, +-1500799, +-251710, +-1502693, +-251168, +-1504587, +-250628, +-1506484, +-250087, +-1508381, +-249549, +-1510280, +-249012, +-1512180, +-248474, +-1514082, +-247937, +-1515988, +-247402, +-1517894, +-246866, +-1519803, +-246333, +-1521711, +-245801, +-1523618, +-245268, +-1525534, +-244738, +-1527443, +-244206, +-1529361, +-243677, +-1531279, +-243149, +-1533195, +-242621, +-1535115, +-242094, +-1537034, +-241568, +-1538956, +-241043, +-1540883, +-240519, +-1542808, +-239995, +-1544737, +-239472, +-1546665, +-238952, +-1548592, +-238430, +-1550528, +-237911, +-1552457, +-237391, +-1554396, +-236872, +-1556333, +-236355, +-1558270, +-235839, +-1560210, +-235324, +-1562149, +-234809, +-1564092, +-234294, +-1566038, +-233781, +-1567984, +-233268, +-1569934, +-232757, +-1571882, +-232247, +-1573829, +-231738, +-1575781, +-231229, +-1577736, +-230721, +-1579690, +-230214, +-1581648, +-229706, +-1583609, +-229202, +-1585565, +-228696, +-1587530, +-228193, +-1589493, +-227690, +-1591455, +-227188, +-1593422, +-226686, +-1595392, +-226186, +-1597361, +-225687, +-1599329, +-225188, +-1601301, +-224690, +-1603277, +-224193, +-1605252, +-223696, +-1607230, +-223201, +-1609208, +-222706, +-1611189, +-222213, +-1613170, +-221720, +-1615154, +-221228, +-1617137, +-220736, +-1619125, +-220246, +-1621111, +-219757, +-1623101, +-219267, +-1625095, +-218779, +-1627088, +-218293, +-1629080, +-217807, +-1631075, +-217321, +-1633075, +-216836, +-1635074, +-216353, +-1637071, +-215869, +-1639078, +-215387, +-1641078, +-214906, +-1643083, +-214425, +-1645091, +-213946, +-1647098, +-213467, +-1649110, +-212989, +-1651120, +-212512, +-1653134, +-212034, +-1655152, +-211560, +-1657164, +-211084, +-1659185, +-210610, +-1661205, +-210137, +-1663224, +-209665, +-1665247, +-209194, +-1667268, +-208723, +-1669294, +-208252, +-1671324, +-207783, +-1673353, +-207315, +-1675385, +-206847, +-1677417, +-206381, +-1679447, +-205915, +-1681482, +-205450, +-1683520, +-204986, +-1685558, +-204522, +-1687600, +-204059, +-1689640, +-203597, +-1691684, +-203136, +-1693728, +-202676, +-1695775, +-202217, +-1697821, +-201758, +-1699871, +-201300, +-1701921, +-200843, +-1703974, +-200387, +-1706026, +-199931, +-1708082, +-199476, +-1710143, +-199022, +-1712202, +-198569, +-1714260, +-198117, +-1716322, +-197665, +-1718388, +-197214, +-1720453, +-196765, +-1722517, +-196315, +-1724585, +-195867, +-1726657, +-195419, +-1728728, +-194972, +-1730803, +-194526, +-1732878, +-194081, +-1734950, +-193637, +-1737027, +-193193, +-1739108, +-192750, +-1741188, +-192308, +-1743272, +-191867, +-1745355, +-191426, +-1747442, +-190986, +-1749528, +-190547, +-1751618, +-190109, +-1753707, +-189671, +-1755800, +-189234, +-1757897, +-188799, +-1759987, +-188363, +-1762088, +-187928, +-1764187, +-187495, +-1766285, +-187062, +-1768387, +-186630, +-1770493, +-186198, +-1772598, +-185768, +-1774702, +-185338, +-1776810, +-184909, +-1778922, +-184481, +-1781033, +-184054, +-1783143, +-183627, +-1785257, +-183201, +-1787375, +-182776, +-1789492, +-182352, +-1791607, +-181927, +-1793733, +-181505, +-1795852, +-181083, +-1797975, +-180661, +-1800102, +-180241, +-1802228, +-179821, +-1804359, +-179402, +-1806487, +-178983, +-1808621, +-178566, +-1810753, +-178149, +-1812889, +-177733, +-1815024, +-177317, +-1817163, +-176902, +-1819308, +-176489, +-1821444, +-176075, +-1823591, +-175663, +-1825736, +-175251, +-1827880, +-174840, +-1830029, +-174431, +-1832175, +-174021, +-1834327, +-173612, +-1836483, +-173204, +-1838637, +-172797, +-1840790, +-172391, +-1842948, +-171985, +-1845110, +-171580, +-1847270, +-171176, +-1849429, +-170773, +-1851592, +-170370, +-1853760, +-169968, +-1855927, +-169566, +-1858098, +-169166, +-1860267, +-168765, +-1862442, +-168367, +-1864614, +-167969, +-1866785, +-167570, +-1868967, +-167174, +-1871140, +-166777, +-1873325, +-166383, +-1875502, +-165987, +-1877690, +-165594, +-1879870, +-165200, +-1882061, +-164809, +-1884243, +-164416, +-1886437, +-164025, +-1888630, +-163635, +-1890820, +-163245, +-1893015, +-162857, +-1895209, +-162468, +-1897407, +-162080, +-1899610, +-161693, +-1901811, +-161308, +-1904010, +-160923, +-1906215, +-160539, +-1908417, +-160154, +-1910631, +-159771, +-1912836, +-159389, +-1915046, +-159006, +-1917261, +-158625, +-1919475, +-158246, +-1921686, +-157866, +-1923902, +-157487, +-1926123, +-157109, +-1928342, +-156731, +-1930566, +-156354, +-1932789, +-155978, +-1935016, +-155603, +-1937241, +-155228, +-1939471, +-154854, +-1941699, +-154481, +-1943932, +-154109, +-1946163, +-153736, +-1948399, +-153366, +-1950633, +-152995, +-1952872, +-152626, +-1955109, +-152256, +-1957351, +-151887, +-1959599, +-151520, +-1961843, +-151153, +-1964086, +-150787, +-1966334, +-150421, +-1968587, +-150056, +-1970838, +-149692, +-1973087, +-149329, +-1975341, +-148965, +-1977600, +-148603, +-1979857, +-148242, +-1982112, +-147881, +-1984379, +-147521, +-1986636, +-147162, +-1988899, +-146803, +-1991167, +-146445, +-1993433, +-146088, +-1995703, +-145731, +-1997972, +-145375, +-2000246, +-145020, +-2002517, +-144665, +-2004794, +-144312, +-2007069, +-143958, +-2009348, +-143605, +-2011632, +-143254, +-2013907, +-142902, +-2016195, +-142551, +-2018482, +-142202, +-2020765, +-141853, +-2023053, +-141504, +-2025347, +-141156, +-2027639, +-140809, +-2029928, +-140463, +-2032222, +-140116, +-2034522, +-139771, +-2036819, +-139426, +-2039121, +-139083, +-2041421, +-138739, +-2043727, +-138397, +-2046030, +-138056, +-2048331, +-137714, +-2050644, +-137373, +-2052954, +-137034, +-2055264, +-136694, +-2057579, +-136356, +-2059890, +-136018, +-2062207, +-135681, +-2064522, +-135344, +-2066841, +-135008, +-2069167, +-134673, +-2071489, +-134339, +-2073808, +-134005, +-2076134, +-133671, +-2078466, +-133338, +-2080794, +-133007, +-2083120, +-132675, +-2085459, +-132345, +-2087789, +-132015, +-2090122, +-131685, +-2092461, +-131357, +-2094799, +-131028, +-2097141, +-130701, +-2099481, +-130373, +-2101826, +-130047, +-2104177, +-129722, +-2106525, +-129397, +-2108870, +-129073, +-2111221, +-128750, +-2113570, +-128427, +-2115923, +-128104, +-2118282, +-127782, +-2120639, +-127460, +-2123001, +-127140, +-2125360, +-126820, +-2127716, +-126502, +-2130078, +-126183, +-2132446, +-125866, +-2134811, +-125548, +-2137181, +-125231, +-2139557, +-124916, +-2141921, +-124600, +-2144300, +-124285, +-2146676, +-123971, +-2149049, +-123658, +-2151428, +-123345, +-2153812, +-123032, +-2156193, +-122721, +-2158571, +-122411, +-2160955, +-122100, +-2163345, +-121790, +-2165732, +-121481, +-2168124, +-121173, +-2170514, +-120865, +-2172909, +-120558, +-2175300, +-120251, +-2177699, +-119945, +-2180093, +-119640, +-2182494, +-119334, +-2184900, +-119030, +-2187303, +-118727, +-2189703, +-118424, +-2192109, +-118122, +-2194520, +-117820, +-2196929, +-117519, +-2199343, +-117218, +-2201754, +-116918, +-2204170, +-116619, +-2206584, +-116320, +-2209004, +-116023, +-2211420, +-115725, +-2213842, +-115429, +-2216261, +-115133, +-2218685, +-114836, +-2221115, +-114541, +-2223543, +-114247, +-2225976, +-113953, +-2228406, +-113660, +-2230832, +-113367, +-2233273, +-113076, +-2235702, +-112784, +-2238146, +-112493, +-2240587, +-112203, +-2243025, +-111913, +-2245468, +-111625, +-2247907, +-111336, +-2250353, +-111048, +-2252805, +-110761, +-2255253, +-110474, +-2257707, +-110188, +-2260158, +-109902, +-2262615, +-109617, +-2265068, +-109333, +-2267527, +-109050, +-2269983, +-108766, +-2272444, +-108483, +-2274912, +-108201, +-2277375, +-107920, +-2279836, +-107640, +-2282302, +-107359, +-2284775, +-107080, +-2287243, +-106800, +-2289718, +-106522, +-2292189, +-106244, +-2294667, +-105967, +-2297140, +-105691, +-2299620, +-105414, +-2302105, +-105138, +-2304587, +-104863, +-2307075, +-104589, +-2309560, +-104315, +-2312040, +-104041, +-2314536, +-103770, +-2317019, +-103497, +-2319517, +-103225, +-2322013, +-102955, +-2324503, +-102684, +-2327001, +-102414, +-2329504, +-102145, +-2332004, +-101876, +-2334509, +-101608, +-2337011, +-101340, +-2339519, +-101073, +-2342023, +-100806, +-2344533, +-100541, +-2347039, +-100276, +-2349551, +-100010, +-2352070, +-99746, +-2354584, +-99482, +-2357104, +-99219, +-2359621, +-98957, +-2362144, +-98695, +-2364662, +-98433, +-2367188, +-98172, +-2369719, +-97912, +-2372246, +-97653, +-2374769, +-97393, +-2377298, +-97134, +-2379833, +-96877, +-2382364, +-96619, +-2384902, +-96361, +-2387446, +-96106, +-2389975, +-95849, +-2392521, +-95594, +-2395063, +-95339, +-2397610, +-95085, +-2400154, +-94831, +-2402704, +-94578, +-2405249, +-94325, +-2407801, +-94073, +-2410348, +-93822, +-2412902, +-93570, +-2415462, +-93320, +-2418019, +-93070, +-2420581, +-92821, +-2423138, +-92572, +-2425703, +-92324, +-2428261, +-92076, +-2430828, +-91828, +-2433400, +-91581, +-2435968, +-91335, +-2438542, +-91090, +-2441111, +-90844, +-2443688, +-90600, +-2446259, +-90356, +-2448837, +-90112, +-2451422, +-89869, +-2454001, +-89626, +-2456588, +-89384, +-2459168, +-89143, +-2461757, +-88902, +-2464340, +-88662, +-2466929, +-88421, +-2469525, +-88182, +-2472117, +-87944, +-2474703, +-87705, +-2477308, +-87467, +-2479907, +-87230, +-2482502, +-86994, +-2485103, +-86757, +-2487710, +-86521, +-2490313, +-86287, +-2492910, +-86051, +-2495527, +-85817, +-2498138, +-85584, +-2500744, +-85351, +-2503356, +-85118, +-2505975, +-84886, +-2508589, +-84654, +-2511209, +-84423, +-2513825, +-84193, +-2516447, +-83962, +-2519076, +-83733, +-2521700, +-83504, +-2524317, +-83275, +-2526954, +-83048, +-2529573, +-82820, +-2532212, +-82593, +-2534845, +-82367, +-2537473, +-82140, +-2540119, +-81915, +-2542748, +-81690, +-2545396, +-81465, +-2548039, +-81241, +-2550675, +-81018, +-2553318, +-80795, +-2555969, +-80573, +-2558613, +-80350, +-2561265, +-80128, +-2563924, +-79907, +-2566576, +-79687, +-2569223, +-79468, +-2571877, +-79248, +-2574538, +-79028, +-2577206, +-78809, +-2579868, +-78592, +-2582524, +-78375, +-2585187, +-78157, +-2587857, +-77940, +-2590534, +-77725, +-2593191, +-77509, +-2595869, +-77294, +-2598541, +-77079, +-2601220, +-76865, +-2603893, +-76651, +-2606573, +-76437, +-2609259, +-76225, +-2611941, +-76013, +-2614615, +-75801, +-2617310, +-75589, +-2619998, +-75379, +-2622680, +-75169, +-2625369, +-74958, +-2628066, +-74749, +-2630756, +-74540, +-2633453, +-74331, +-2636157, +-74124, +-2638855, +-73917, +-2641547, +-73709, +-2644259, +-73503, +-2646950, +-73297, +-2649663, +-73091, +-2652370, +-72886, +-2655083, +-72681, +-2657790, +-72477, +-2660503, +-72274, +-2663210, +-72070, +-2665939, +-71868, +-2668647, +-71665, +-2671376, +-71463, +-2674098, +-71262, +-2676814, +-71061, +-2679536, +-70860, +-2682265, +-70661, +-2684988, +-70461, +-2687718, +-70262, +-2690456, +-70063, +-2693187, +-69865, +-2695924, +-69667, +-2698654, +-69470, +-2701392, +-69273, +-2704137, +-69077, +-2706876, +-68881, +-2709621, +-68686, +-2712359, +-68491, +-2715105, +-68296, +-2717858, +-68102, +-2720604, +-67908, +-2723357, +-67715, +-2726117, +-67522, +-2728870, +-67330, +-2731631, +-67138, +-2734384, +-66947, +-2737144, +-66755, +-2739912, +-66565, +-2742673, +-66375, +-2745440, +-66186, +-2748201, +-65997, +-2750968, +-65808, +-2753744, +-65620, +-2756511, +-65432, +-2759285, +-65244, +-2762068, +-65057, +-2764843, +-64870, +-2767625, +-64685, +-2770400, +-64499, +-2773181, +-64312, +-2775970, +-64129, +-2778751, +-63945, +-2781541, +-63761, +-2784322, +-63576, +-2787126, +-63395, +-2789906, +-63211, +-2792710, +-63029, +-2795506, +-62848, +-2798293, +-62666, +-2801104, +-62485, +-2803906, +-62305, +-2806700, +-62125, +-2809501, +-61946, +-2812312, +-61766, +-2815129, +-61587, +-2817938, +-61410, +-2820737, +-61231, +-2823562, +-61053, +-2826378, +-60877, +-2829185, +-60701, +-2831999, +-60524, +-2834822, +-60348, +-2837652, +-60173, +-2840473, +-59997, +-2843303, +-59823, +-2846123, +-59649, +-2848951, +-59475, +-2851788, +-59302, +-2854614, +-59129, +-2857450, +-58957, +-2860275, +-58784, +-2863127, +-58614, +-2865951, +-58442, +-2868800, +-58271, +-2871640, +-58101, +-2874489, +-57931, +-2877327, +-57762, +-2880174, +-57592, +-2883029, +-57424, +-2885874, +-57255, +-2888727, +-57087, +-2891589, +-56920, +-2894440, +-56752, +-2897299, +-56586, +-2900149, +-56419, +-2903025, +-56254, +-2905874, +-56088, +-2908748, +-55923, +-2911612, +-55758, +-2914484, +-55594, +-2917346, +-55430, +-2920217, +-55266, +-2923095, +-55104, +-2925964, +-54941, +-2928840, +-54778, +-2931726, +-54617, +-2934599, +-54455, +-2937482, +-54294, +-2940373, +-54133, +-2943253, +-53973, +-2946143, +-53813, +-2949021, +-53653, +-2951926, +-53495, +-2954802, +-53335, +-2957705, +-53177, +-2960597, +-53019, +-2963497, +-52862, +-2966387, +-52704, +-2969305, +-52548, +-2972192, +-52391, +-2975106, +-52235, +-2978010, +-52079, +-2980922, +-51924, +-2983824, +-51769, +-2986733, +-51614, +-2989651, +-51461, +-2992558, +-51307, +-2995472, +-51153, +-2998396, +-51001, +-3001307, +-50848, +-3004228, +-50696, +-3007158, +-50544, +-3010075, +-50392, +-3013021, +-50241, +-3015934, +-50090, +-3018878, +-49940, +-3021809, +-49790, +-3024729, +-49640, +-3027677, +-49491, +-3030613, +-49343, +-3033538, +-49193, +-3036491, +-49045, +-3039434, +-48898, +-3042363, +-48750, +-3045321, +-48603, +-3048268, +-48457, +-3051203, +-48310, +-3054167, +-48165, +-3057118, +-48019, +-3060079, +-47874, +-3063026, +-47729, +-3065984, +-47584, +-3068949, +-47441, +-3071901, +-47297, +-3074862, +-47153, +-3077832, +-47011, +-3080789, +-46868, +-3083756, +-46726, +-3086729, +-46583, +-3089713, +-46442, +-3092684, +-46301, +-3095663, +-46160, +-3098629, +-46020, +-3101604, +-45880, +-3104587, +-45740, +-3107559, +-45600, +-3110560, +-45461, +-3113548, +-45323, +-3116523, +-45185, +-3119505, +-45047, +-3122498, +-44908, +-3125500, +-44771, +-3128486, +-44634, +-3131483, +-44497, +-3134489, +-44362, +-3137480, +-44226, +-3140481, +-44090, +-3143490, +-43955, +-3146485, +-43820, +-3149490, +-43685, +-3152503, +-43552, +-3155502, +-43417, +-3158534, +-43284, +-3161527, +-43151, +-3164554, +-43018, +-3167566, +-42886, +-3170585, +-42753, +-3173616, +-42622, +-3176631, +-42490, +-3179655, +-42359, +-3182689, +-42228, +-3185707, +-42098, +-3188735, +-41967, +-3191771, +-41838, +-3194794, +-41709, +-3197824, +-41580, +-3200864, +-41450, +-3203914, +-41322, +-3206947, +-41194, +-3209991, +-41067, +-3213018, +-40939, +-3216079, +-40812, +-3219126, +-40686, +-3222156, +-40558, +-3225221, +-40432, +-3228270, +-40308, +-3231302, +-40182, +-3234370, +-40057, +-3237422, +-39932, +-3240483, +-39807, +-3243553, +-39683, +-3246607, +-39559, +-3249670, +-39435, +-3252743, +-39313, +-3255799, +-39190, +-3258865, +-39067, +-3261940, +-38945, +-3265024, +-38823, +-3268092, +-38701, +-3271169, +-38581, +-3274229, +-38459, +-3277326, +-38339, +-3280406, +-38218, +-3283495, +-38099, +-3286566, +-37979, +-3289646, +-37860, +-3292738, +-37740, +-3295837, +-37622, +-3298921, +-37504, +-3302012, +-37385, +-3305115, +-37268, +-3308199, +-37151, +-3311293, +-37033, +-3314397, +-36916, +-3317508, +-36800, +-3320603, +-36684, +-3323708, +-36567, +-3326824, +-36452, +-3329919, +-36336, +-3333053, +-36222, +-3336140, +-36107, +-3339266, +-35993, +-3342372, +-35879, +-3345489, +-35765, +-3348614, +-35651, +-3351751, +-35538, +-3354867, +-35425, +-3357994, +-35313, +-3361102, +-35200, +-3364249, +-35088, +-3367377, +-34977, +-3370514, +-34866, +-3373631, +-34755, +-3376759, +-34644, +-3379896, +-34533, +-3383043, +-34424, +-3386172, +-34313, +-3389338, +-34204, +-3392455, +-34095, +-3395614, +-33986, +-3398750, +-33877, +-3401898, +-33769, +-3405056, +-33660, +-3408222, +-33553, +-3411369, +-33445, +-3414526, +-33338, +-3417693, +-33231, +-3420840, +-33125, +-3423996, +-33018, +-3427162, +-32912, +-3430338, +-32806, +-3433493, +-32701, +-3436658, +-32595, +-3439835, +-32489, +-3443020, +-32385, +-3446183, +-32280, +-3449359, +-32176, +-3452542, +-32074, +-3455706, +-31971, +-3458880, +-31867, +-3462063, +-31764, +-3465255, +-31662, +-3468427, +-31558, +-3471641, +-31457, +-3474833, +-31355, +-3478003, +-31253, +-3481215, +-31152, +-3484405, +-31051, +-3487605, +-30951, +-3490783, +-30850, +-3494004, +-30750, +-3497201, +-30650, +-3500411, +-30551, +-3503595, +-30451, +-3506825, +-30352, +-3510030, +-30254, +-3513213, +-30155, +-3516440, +-30057, +-3519644, +-29959, +-3522856, +-29861, +-3526080, +-29764, +-3529315, +-29667, +-3532525, +-29570, +-3535746, +-29473, +-3538977, +-29377, +-3542186, +-29280, +-3545438, +-29185, +-3548666, +-29089, +-3551904, +-28994, +-3555119, +-28900, +-3558342, +-28805, +-3561578, +-28710, +-3564822, +-28616, +-3568079, +-28522, +-3571309, +-28428, +-3574551, +-28335, +-3577803, +-28241, +-3581067, +-28148, +-3584304, +-28056, +-3587552, +-27963, +-3590808, +-27872, +-3594043, +-27779, +-3597323, +-27688, +-3600576, +-27596, +-3603840, +-27506, +-3607078, +-27414, +-3610365, +-27324, +-3613624, +-27234, +-3616893, +-27144, +-3620137, +-27054, +-3623428, +-26964, +-3626694, +-26875, +-3629970, +-26786, +-3633255, +-26697, +-3636515, +-26609, +-3639785, +-26521, +-3643066, +-26432, +-3646358, +-26344, +-3649658, +-26257, +-3652932, +-26169, +-3656220, +-26082, +-3659516, +-25995, +-3662823, +-25909, +-3666101, +-25823, +-3669390, +-25736, +-3672690, +-25650, +-3676003, +-25565, +-3679285, +-25480, +-3682580, +-25395, +-3685883, +-25310, +-3689200, +-25225, +-3692487, +-25140, +-3695823, +-25056, +-3699132, +-24972, +-3702452, +-24889, +-3705740, +-24805, +-3709082, +-24722, +-3712393, +-24639, +-3715716, +-24557, +-3719008, +-24474, +-3722353, +-24392, +-3725667, +-24310, +-3728994, +-24228, +-3732330, +-24146, +-3735678, +-24065, +-3738994, +-23984, +-3742323, +-23903, +-3745661, +-23822, +-3749013, +-23743, +-3752330, +-23663, +-3755661, +-23583, +-3759000, +-23503, +-3762354, +-23423, +-3765718, +-23344, +-3769050, +-23266, +-3772391, +-23187, +-3775745, +-23108, +-3779110, +-23029, +-3782487, +-22951, +-3785831, +-22874, +-3789186, +-22796, +-3792552, +-22719, +-3795885, +-22641, +-3799274, +-22565, +-3802631, +-22488, +-3805998, +-22411, +-3809375, +-22336, +-3812721, +-22259, +-3816122, +-22183, +-3819490, +-22108, +-3822868, +-22032, +-3826259, +-21957, +-3829613, +-21882, +-3833027, +-21807, +-3836406, +-21732, +-3839794, +-21659, +-3843149, +-21584, +-3846563, +-21511, +-3849940, +-21437, +-3853330, +-21364, +-3856730, +-21290, +-3860143, +-21218, +-3863518, +-21145, +-3866905, +-21073, +-3870304, +-21000, +-3873717, +-20927, +-3877139, +-20856, +-3880524, +-20784, +-3883923, +-20713, +-3887330, +-20642, +-3890749, +-20570, +-3894183, +-20500, +-3897579, +-20429, +-3900984, +-20358, +-3904453, +-20288, +-3907831, +-20218, +-3911273, +-20149, +-3914677, +-20078, +-3918143, +-20009, +-3921567, +-19941, +-3924955, +-19871, +-3928406, +-19803, +-3931817, +-19733, +-3935291, +-19665, +-3938726, +-19597, +-3942172, +-19529, +-3945581, +-19461, +-3949051, +-19394, +-3952480, +-19327, +-3955922, +-19259, +-3959378, +-19192, +-3962843, +-19126, +-3966267, +-19059, +-3969705, +-18993, +-3973153, +-18927, +-3976615, +-18861, +-3980086, +-18795, +-3983573, +-18729, +-3987017, +-18664, +-3990470, +-18599, +-3993938, +-18534, +-3997418, +-18470, +-4000854, +-18404, +-4004359, +-18340, +-4007818, +-18276, +-4011292, +-18212, +-4014776, +-18148, +-4018274, +-18085, +-4021727, +-18021, +-4025191, +-17958, +-4028669, +-17895, +-4032158, +-17832, +-4035659, +-17769, +-4039176, +-17707, +-4042644, +-17645, +-4046124, +-17583, +-4049620, +-17521, +-4053124, +-17459, +-4056644, +-17397, +-4060116, +-17336, +-4063602, +-17275, +-4067100, +-17214, +-4070608, +-17153, +-4074131, +-17092, +-4077666, +-17032, +-4081151, +-16972, +-4084651, +-16912, +-4088163, +-16852, +-4091688, +-16792, +-4095226, +-16733, +-4098715, +-16674, +-4102216, +-16614, +-4105790, +-16555, +-4109315, +-16497, +-4112793, +-16438, +-4116344, +-16379, +-4119849, +-16320, +-4123425, +-16264, +-4126951, +-16206, +-4130489, +-16149, +-4133981, +-16091, +-4137544, +-16034, +-4141060, +-15976, +-4144649, +-15919, +-4148187, +-15862, +-4151741, +-15806, +-4155242, +-15749, +-4158818, +-15692, +-4162345, +-15637, +-4165946, +-15581, +-4169498, +-15526, +-4172996, +-15470, +-4176574, +-15414, +-4180164, +-15359, +-4183702, +-15304, +-4187251, +-15250, +-4190813, +-15195, +-4194388, +-15140, +-4197975, +-15085, +-4201575, +-15031, +-4205121, +-14978, +-4208679, +-14924, +-4212250, +-14870, +-4215833, +-14816, +-4219430, +-14763, +-4222974, +-14710, +-4226596, +-14657, +-4230166, +-14604, +-4233745, +-14551, +-4237336, +-14499, +-4240945, +-14447, +-4244492, +-14394, +-4248126, +-14342, +-4251699, +-14291, +-4255288, +-14239, +-4258890, +-14187, +-4262501, +-14135, +-4266130, +-14085, +-4269699, +-14033, +-4273350, +-13982, +-4276945, +-13932, +-4280553, +-13881, +-4284174, +-13831, +-4287734, +-13781, +-4291382, +-13731, +-4294968, +-13680, +-4298642, +-13630, +-4302255, +-13581, +-4305880, +-13531, +-4309519, +-13482, +-4313100, +-13433, +-4316765, +-13384, +-4320368, +-13336, +-4323983, +-13287, +-4327616, +-13238, +-4331258, +-13190, +-4334913, +-13141, +-4338582, +-13093, +-4342191, +-13046, +-4345813, +-12998, +-4349443, +-12950, +-4353091, +-12903, +-4356748, +-12855, +-4360423, +-12808, +-4364107, +-12761, +-4367730, +-12714, +-4371365, +-12668, +-4375009, +-12621, +-4378672, +-12575, +-4382347, +-12528, +-4386036, +-12483, +-4389657, +-12436, +-4393369, +-12390, +-4397017, +-12345, +-4400678, +-12299, +-4404353, +-12254, +-4408041, +-12209, +-4411659, +-12164, +-4415374, +-12119, +-4419024, +-12074, +-4422767, +-12029, +-4426439, +-11985, +-4430125, +-11940, +-4433824, +-11896, +-4437457, +-11852, +-4441183, +-11808, +-4444837, +-11765, +-4448510, +-11720, +-4452278, +-11677, +-4455973, +-11634, +-4459599, +-11591, +-4463322, +-11547, +-4467063, +-11505, +-4470724, +-11462, +-4474405, +-11419, +-4478183, +-11376, +-4481890, +-11334, +-4485612, +-11292, +-4489257, +-11250, +-4493001, +-11209, +-4496674, +-11166, +-4500451, +-11125, +-4504151, +-11083, +-4507865, +-11042, +-4511587, +-11000, +-4515328, +-10959, +-4519084, +-10918, +-4522760, +-10877, +-4526543, +-10837, +-4530247, +-10796, +-4533965, +-10756, +-4537697, +-10715, +-4541442, +-10675, +-4545207, +-10635, +-4548885, +-10595, +-4552673, +-10556, +-4556379, +-10515, +-4560195, +-10476, +-4563934, +-10436, +-4567682, +-10397, +-4571444, +-10358, +-4575127, +-10319, +-4578917, +-10280, +-4582722, +-10241, +-4586447, +-10203, +-4590180, +-10164, +-4593933, +-10126, +-4597701, +-10088, +-4601477, +-10049, +-4605272, +-10011, +-4609077, +-9974, +-4612800, +-9936, +-4616537, +-9898, +-4620384, +-9860, +-4624149, +-9823, +-4627929, +-9786, +-4631717, +-9749, +-4635420, +-9712, +-4639243, +-9675, +-4643080, +-9638, +-4646826, +-9602, +-4650587, +-9566, +-4654361, +-9528, +-4658257, +-9493, +-4661953, +-9457, +-4665771, +-9420, +-4669603, +-9384, +-4673450, +-9349, +-4677203, +-9313, +-4680971, +-9277, +-4684862, +-9242, +-4688658, +-9206, +-4692475, +-9172, +-4696189, +-9137, +-4700029, +-9101, +-4703883, +-9067, +-4707647, +-9032, +-4711531, +-8997, +-4715317, +-8963, +-4719124, +-8929, +-4722939, +-8894, +-4726775, +-8860, +-4730619, +-8826, +-4734485, +-8793, +-4738243, +-8758, +-4742138, +-8725, +-4745925, +-8691, +-4749851, +-8657, +-4753667, +-8624, +-4757506, +-8591, +-4761358, +-8558, +-4765219, +-8525, +-4768983, +-8492, +-4772880, +-8460, +-4776672, +-8426, +-4780593, +-8394, +-4784415, +-8362, +-4788251, +-8330, +-4792102, +-8297, +-4795969, +-8265, +-4799850, +-8233, +-4803746, +-8202, +-4807533, +-8168, +-4811460, +-8137, +-4815277, +-8106, +-4819234, +-8074, +-4823080, +-8043, +-4826942, +-8012, +-4830818, +-7981, +-4834710, +-7951, +-4838489, +-7919, +-4842410, +-7887, +-4846347, +-7858, +-4850178, +-7827, +-4854146, +-7796, +-4857999, +-7766, +-4861867, +-7736, +-4865758, +-7706, +-4869656, +-7675, +-4873569, +-7646, +-4877373, +-7616, +-4881317, +-7586, +-4885284, +-7556, +-4889125, +-7527, +-4892988, +-7497, +-4896994, +-7468, +-4900888, +-7439, +-4904789, +-7409, +-4908714, +-7380, +-4912646, +-7352, +-4916463, +-7323, +-4920425, +-7295, +-4924273, +-7265, +-4928274, +-7237, +-4932144, +-7209, +-4936036, +-7180, +-4940085, +-7151, +-4944009, +-7123, +-4947940, +-7096, +-4951751, +-7068, +-4955720, +-7040, +-4959706, +-7013, +-4963562, +-6984, +-4967579, +-6957, +-4971466, +-6929, +-4975507, +-6902, +-4979425, +-6875, +-4983358, +-6847, +-4987307, +-6820, +-4991272, +-6793, +-4995252, +-6767, +-4999098, +-6740, +-5003110, +-6713, +-5006995, +-6686, +-5011039, +-6660, +-5014946, +-6634, +-5018869, +-6607, +-5022961, +-6581, +-5026915, +-6554, +-5030885, +-6528, +-5034880, +-6503, +-5038725, +-6477, +-5042743, +-6451, +-5046785, +-6426, +-5050677, +-6399, +-5054743, +-6374, +-5058675, +-6349, +-5062613, +-6324, +-5066567, +-6299, +-5070546, +-6274, +-5074531, +-6248, +-5078542, +-6223, +-5082560, +-6198, +-5086603, +-6174, +-5090488, +-6149, +-5094564, +-6125, +-5098480, +-6100, +-5102589, +-6075, +-5106537, +-6051, +-5110510, +-6027, +-5114500, +-6002, +-5118665, +-5979, +-5122517, +-5955, +-5126555, +-5931, +-5130599, +-5906, +-5134669, +-5883, +-5138584, +-5859, +-5142687, +-5836, +-5146623, +-5812, +-5150759, +-5789, +-5154738, +-5766, +-5158732, +-5742, +-5162742, +-5719, +-5166768, +-5696, +-5170800, +-5673, +-5174859, +-5650, +-5178934, +-5627, +-5183026, +-5605, +-5186953, +-5582, +-5191078, +-5559, +-5195038, +-5536, +-5199196, +-5514, +-5203188, +-5492, +-5207196, +-5470, +-5211220, +-5448, +-5215260, +-5426, +-5219316, +-5404, +-5223400, +-5381, +-5227490, +-5359, +-5231596, +-5338, +-5235529, +-5316, +-5239669, +-5294, +-5243826, +-5273, +-5247819, +-5252, +-5251816, +-5230, +-5256024, +-5209, +-5260054, +-5187, +-5264113, +-5166, +-5268176, +-5145, +-5272256, +-5124, +-5276364, +-5103, +-5280478, +-5083, +-5284420, +-5062, +-5288567, +-5041, +-5292731, +-5021, +-5296722, +-4999, +-5300920, +-4979, +-5304944, +-4959, +-5308973, +-4939, +-5313029, +-4918, +-5317297, +-4898, +-5321387, +-4878, +-5325482, +-4858, +-5329606, +-4839, +-5333525, +-4819, +-5337683, +-4799, +-5341846, +-4778, +-5346038, +-4759, +-5350035, +-4739, +-5354249, +-4720, +-5358279, +-4701, +-5362325, +-4681, +-5366591, +-4662, +-5370671, +-4643, +-5374767, +-4624, +-5378881, +-4605, +-5382998, +-4586, +-5387145, +-4566, +-5391310, +-4547, +-5395492, +-4529, +-5399468, +-4510, +-5403684, +-4491, +-5407905, +-4473, +-5411930, +-4454, +-5416200, +-4436, +-5420258, +-4418, +-5424334, +-4400, +-5428426, +-4381, +-5432766, +-4362, +-5436893, +-4344, +-5441037, +-4326, +-5445198, +-4308, +-5449376, +-4291, +-5453336, +-4273, +-5457548, +-4255, +-5461779, +-4237, +-5466027, +-4220, +-5470053, +-4202, +-5474337, +-4185, +-5478396, +-4167, +-5482716, +-4150, +-5486824, +-4133, +-5490935, +-4115, +-5495063, +-4098, +-5499208, +-4081, +-5503370, +-4064, +-5507564, +-4047, +-5511761, +-4029, +-5515975, +-4013, +-5520208, +-3996, +-5524459, +-3980, +-5528487, +-3963, +-5532773, +-3946, +-5537077, +-3930, +-5541157, +-3913, +-5545498, +-3897, +-5549597, +-3881, +-5553728, +-3864, +-5557861, +-3847, +-5562275, +-3831, +-5566459, +-3815, +-5570646, +-3799, +-5574865, +-3783, +-5579086, +-3767, +-5583342, +-3752, +-5587328, +-3736, +-5591619, +-3720, +-5595912, +-3704, +-5600240, +-3689, +-5604294, +-3673, +-5608659, +-3658, +-5612748, +-3642, +-5617149, +-3627, +-5621273, +-3612, +-5625431, +-3596, +-5629606, +-3580, +-5634066, +-3565, +-5638278, +-3550, +-5642507, +-3535, +-5646737, +-3520, +-5651003, +-3505, +-5655286, +-3491, +-5659280, +-3476, +-5663600, +-3461, +-5667938, +-3446, +-5672277, +-3432, +-5676357, +-3417, +-5680751, +-3403, +-5684866, +-3388, +-5689280, +-3374, +-5693430, +-3360, +-5697598, +-3345, +-5702086, +-3331, +-5706290, +-3316, +-5710512, +-3302, +-5714751, +-3288, +-5718990, +-3274, +-5723266, +-3260, +-5727560, +-3246, +-5731873, +-3232, +-5736204, +-3218, +-5740554, +-3204, +-5744923, +-3191, +-5748993, +-3177, +-5753399, +-3164, +-5757504, +-3150, +-5761948, +-3137, +-5766088, +-3123, +-5770570, +-3110, +-5774746, +-3096, +-5779268, +-3083, +-5783480, +-3070, +-5787711, +-3057, +-5791959, +-3044, +-5796226, +-3031, +-5800511, +-3018, +-5804814, +-3005, +-5809136, +-2991, +-5813477, +-2978, +-5817856, +-2965, +-5822235, +-2952, +-5826633, +-2940, +-5830705, +-2927, +-5835141, +-2914, +-5839596, +-2902, +-5843742, +-2889, +-5848236, +-2877, +-5852397, +-2864, +-5856930, +-2852, +-5861128, +-2840, +-5865365, +-2827, +-5869957, +-2815, +-5874210, +-2803, +-5878502, +-2791, +-5882792, +-2779, +-5887100, +-2767, +-5891448, +-2755, +-5895793, +-2743, +-5900158, +-2731, +-5904563, +-2719, +-5908966, +-2707, +-5913389, +-2696, +-5917477, +-2684, +-5921937, +-2672, +-5926417, +-2661, +-5930559, +-2649, +-5935078, +-2636, +-5939641, +-2625, +-5943815, +-2614, +-5948029, +-2602, +-5952628, +-2591, +-5956880, +-2579, +-5961520, +-2568, +-5965787, +-2557, +-5970095, +-2546, +-5974422, +-2535, +-5978744, +-2524, +-5983108, +-2513, +-5987468, +-2502, +-5991871, +-2491, +-5996269, +-2480, +-6000711, +-2469, +-6005149, +-2458, +-6009630, +-2447, +-6014107, +-2437, +-6018213, +-2426, +-6022754, +-2415, +-6027290, +-2405, +-6031450, +-2394, +-6036052, +-2384, +-6040223, +-2373, +-6044865, +-2363, +-6049099, +-2352, +-6053757, +-2342, +-6058029, +-2332, +-6062320, +-2321, +-6067040, +-2311, +-6071369, +-2301, +-6075717, +-2291, +-6080084, +-2281, +-6084470, +-2271, +-6088850, +-2260, +-6093723, +-2251, +-6097719, +-2240, +-6102184, +-2231, +-6106641, +-2220, +-6111146, +-2210, +-6115671, +-2200, +-6120216, +-2190, +-6124755, +-2181, +-6128877, +-2171, +-6133483, +-2161, +-6138110, +-2152, +-6142288, +-2142, +-6146956, +-2133, +-6151171, +-2123, +-6155881, +-2114, +-6160133, +-2104, +-6164858, +-2095, +-6169149, +-2086, +-6173458, +-2076, +-6178275, +-2067, +-6182624, +-2058, +-6186992, +-2049, +-6191379, +-2040, +-6195785, +-2030, +-6200211, +-2022, +-6204657, +-2012, +-6209627, +-2003, +-6214114, +-1994, +-6218114, +-1986, +-6222640, +-1977, +-6227187, +-1968, +-6231754, +-1958, +-6236343, +-1950, +-6240953, +-1942, +-6245061, +-1933, +-6249711, +-1924, +-6254383, +-1916, +-6258547, +-1907, +-6263261, +-1898, +-6267996, +-1890, +-6272249, +-1881, +-6277028, +-1873, +-6281288, +-1865, +-6285566, +-1856, +-6290408, +-1848, +-6294726, +-1839, +-6299613, +-1831, +-6303971, +-1823, +-6308380, +-1815, +-6312775, +-1807, +-6317191, +-1798, +-6322189, +-1790, +-6326646, +-1782, +-6331157, +-1774, +-6335654, +-1766, +-6340172, +-1758, +-6344710, +-1750, +-6349268, +-1741, +-6353882, +-1733, +-6358483, +-1727, +-6362518, +-1718, +-6367193, +-1710, +-6371856, +-1702, +-6376541, +-1694, +-6381247, +-1687, +-6385410, +-1679, +-6390159, +-1671, +-6394930, +-1664, +-6399115, +-1656, +-6403965, +-1649, +-6408187, +-1641, +-6413046, +-1634, +-6417344, +-1626, +-6422247, +-1619, +-6426547, +-1612, +-6430904, +-1604, +-6435874, +-1597, +-6440271, +-1590, +-6444650, +-1582, +-6449689, +-1575, +-6454148, +-1568, +-6458588, +-1561, +-6463087, +-1554, +-6467567, +-1547, +-6472068, +-1539, +-6477286, +-1532, +-6481831, +-1525, +-6486435, +-1518, +-6491022, +-1511, +-6495630, +-1504, +-6500298, +-1498, +-6504312, +-1491, +-6508981, +-1484, +-6513673, +-1477, +-6518426, +-1470, +-6523162, +-1464, +-6527269, +-1457, +-6532047, +-1450, +-6536889, +-1443, +-6541714, +-1437, +-6545897, +-1430, +-6550765, +-1424, +-6554987, +-1417, +-6559900, +-1410, +-6564879, +-1404, +-6569161, +-1398, +-6573418, +-1391, +-6578466, +-1385, +-6582763, +-1378, +-6587858, +-1372, +-6592196, +-1365, +-6597339, +-1359, +-6601762, +-1353, +-6606161, +-1347, +-6610624, +-1340, +-6615819, +-1334, +-6620325, +-1328, +-6624851, +-1322, +-6629353, +-1316, +-6633920, +-1310, +-6638509, +-1304, +-6643073, +-1297, +-6648485, +-1291, +-6653095, +-1285, +-6657773, +-1279, +-6662472, +-1274, +-6666397, +-1268, +-6671091, +-1262, +-6675854, +-1256, +-6680639, +-1250, +-6685400, +-1244, +-6690231, +-1238, +-6695086, +-1233, +-6699094, +-1227, +-6703992, +-1221, +-6708914, +-1215, +-6713812, +-1210, +-6717945, +-1204, +-6722936, +-1198, +-6727953, +-1193, +-6732145, +-1187, +-6737158, +-1182, +-6741388, +-1176, +-6746499, +-1171, +-6750769, +-1165, +-6755877, +-1160, +-6760187, +-1154, +-6765395, +-1149, +-6769747, +-1143, +-6774952, +-1138, +-6779346, +-1133, +-6783759, +-1127, +-6789091, +-1122, +-6793548, +-1117, +-6798024, +-1112, +-6802521, +-1106, +-6807900, +-1101, +-6812442, +-1096, +-6817004, +-1091, +-6821587, +-1086, +-6826191, +-1081, +-6830816, +-1075, +-6836350, +-1070, +-6841023, +-1065, +-6845718, +-1060, +-6850434, +-1055, +-6855173, +-1050, +-6859935, +-1045, +-6864719, +-1040, +-6869469, +-1035, +-6874300, +-1031, +-6878169, +-1026, +-6883042, +-1021, +-6887939, +-1016, +-6892859, +-1011, +-6897804, +-1005, +-6902774, +-1002, +-6906755, +-995, +-6911770, +-990, +-6916809, +-985, +-6921874, +-982, +-6925933, +-977, +-6931045, +-972, +-6936183, +-968, +-6940300, +-963, +-6945486, +-959, +-6949641, +-954, +-6954876, +-949, +-6960075, +-945, +-6964355, +-940, +-6969604, +-936, +-6973925, +-931, +-6979225, +-927, +-6983588, +-923, +-6987905, +-918, +-6993345, +-914, +-6997704, +-909, +-7003198, +-905, +-7007601, +-901, +-7012023, +-896, +-7017596, +-892, +-7022063, +-888, +-7026550, +-884, +-7031057, +-879, +-7036737, +-875, +-7041291, +-871, +-7045866, +-867, +-7050461, +-863, +-7055078, +-858, +-7060896, +-854, +-7065561, +-850, +-7070249, +-846, +-7074958, +-842, +-7079760, +-838, +-7084514, +-834, +-7089291, +-830, +-7094091, +-826, +-7098914, +-822, +-7103761, +-818, +-7108631, +-814, +-7113525, +-810, +-7118443, +-806, +-7123459, +-802, +-7128426, +-798, +-7133418, +-794, +-7138435, +-791, +-7142196, +-787, +-7147257, +-783, +-7152344, +-779, +-7157534, +-775, +-7162674, +-772, +-7166527, +-768, +-7171713, +-764, +-7176927, +-760, +-7182167, +-757, +-7186175, +-753, +-7191465, +-749, +-7196782, +-746, +-7200769, +-742, +-7206137, +-739, +-7210242, +-735, +-7215661, +-731, +-7221109, +-728, +-7225194, +-724, +-7230695, +-721, +-7234902, +-717, +-7240457, +-714, +-7244622, +-710, +-7250231, +-707, +-7254521, +-703, +-7260186, +-700, +-7264435, +-696, +-7270156, +-693, +-7274447, +-690, +-7278843, +-686, +-7284648, +-683, +-7289002, +-680, +-7293375, +-676, +-7299353, +-673, +-7303771, +-670, +-7308209, +-666, +-7314187, +-663, +-7318762, +-660, +-7323267, +-657, +-7327793, +-653, +-7333890, +-650, +-7338556, +-647, +-7343151, +-644, +-7347768, +-641, +-7352499, +-637, +-7358749, +-634, +-7363439, +-631, +-7368245, +-628, +-7372979, +-625, +-7377736, +-622, +-7382612, +-619, +-7387415, +-616, +-7392241, +-613, +-7397188, +-610, +-7402062, +-607, +-7406959, +-604, +-7411980, +-601, +-7416926, +-598, +-7421897, +-595, +-7426994, +-592, +-7432015, +-589, +-7437062, +-586, +-7442236, +-583, +-7447335, +-580, +-7452460, +-577, +-7457715, +-574, +-7462894, +-572, +-7466327, +-569, +-7471655, +-566, +-7476906, +-563, +-7482186, +-560, +-7487599, +-558, +-7491118, +-555, +-7496581, +-552, +-7501965, +-549, +-7507379, +-547, +-7511077, +-544, +-7516540, +-541, +-7522143, +-538, +-7527668, +-536, +-7531331, +-533, +-7537018, +-530, +-7542625, +-528, +-7546456, +-525, +-7552117, +-522, +-7557809, +-520, +-7561699, +-517, +-7567447, +-515, +-7571374, +-512, +-7577178, +-510, +-7581144, +-506, +-7587005, +-504, +-7592901, +-501, +-7596930, +-499, +-7602884, +-497, +-7606954, +-494, +-7612968, +-492, +-7617079, +-488, +-7623155, +-487, +-7627186, +-485, +-7631355, +-482, +-7637519, +-480, +-7641732, +-477, +-7647961, +-475, +-7652218, +-472, +-7658512, +-470, +-7662815, +-468, +-7667009, +-465, +-7673525, +-463, +-7677764, +-461, +-7682151, +-458, +-7688637, +-456, +-7693071, +-454, +-7697394, +-451, +-7703980, +-449, +-7708484, +-447, +-7713007, +-445, +-7717418, +-442, +-7724137, +-440, +-7728732, +-438, +-7733349, +-436, +-7737850, +-434, +-7742509, +-431, +-7749400, +-429, +-7754113, +-427, +-7758709, +-425, +-7763466, +-423, +-7768105, +-420, +-7775317, +-418, +-7780011, +-416, +-7784871, +-414, +-7789611, +-412, +-7794518, +-410, +-7799304, +-408, +-7804259, +-406, +-7809091, +-404, +-7814095, +-402, +-7819124, +-400, +-7824029, +-398, +-7829108, +-396, +-7834063, +-393, +-7841769, +-391, +-7846786, +-389, +-7851983, +-387, +-7857052, +-385, +-7862303, +-384, +-7864938, +-382, +-7870074, +-380, +-7875393, +-378, +-7880583, +-376, +-7885958, +-374, +-7891204, +-372, +-7896637, +-370, +-7901938, +-368, +-7907430, +-366, +-7912952, +-364, +-7918341, +-362, +-7923924, +-361, +-7926562, +-359, +-7932192, +-357, +-7937853, +-355, +-7943378, +-353, +-7949103, +-351, +-7954691, +-350, +-7957582, +-348, +-7963389, +-346, +-7969057, +-344, +-7974932, +-342, +-7980666, +-341, +-7983633, +-339, +-7989594, +-337, +-7995414, +-335, +-8001445, +-334, +-8004296, +-332, +-8010382, +-330, +-8016505, +-329, +-8019399, +-327, +-8025577, +-325, +-8031611, +-324, +-8034734, +-322, +-8041008, +-320, +-8047135, +-319, +-8050307, +-317, +-8056680, +-315, +-8062904, +-314, +-8066126, +-312, +-8072601, +-310, +-8078925, +-309, +-8082200, +-307, +-8088585, +-306, +-8091892, +-304, +-8098537, +-302, +-8105028, +-301, +-8108389, +-299, +-8115144, +-298, +-8118339, +-296, +-8125162, +-295, +-8128591, +-293, +-8135282, +-292, +-8138745, +-290, +-8145709, +-289, +-8149005, +-287, +-8156041, +-286, +-8159578, +-284, +-8166480, +-283, +-8170054, +-281, +-8177239, +-280, +-8180640, +-278, +-8187904, +-277, +-8191554, +-275, +-8198682, +-274, +-8202373, +-272, +-8209797, +-271, +-8213309, +-270, +-8217055, +-268, +-8224589, +-267, +-8228154, +-265, +-8235772, +-264, +-8239603, +-262, +-8247082, +-261, +-8250957, +-260, +-8254846, +-258, +-8262440, +-257, +-8266375, +-256, +-8270325, +-254, +-8278273, +-253, +-8282035, +-252, +-8286047, +-250, +-8294122, +-248, +-8297943, +-248, +-8302021, +-246, +-8310226, +-245, +-8314354, +-244, +-8318255, +-243, +-8322416, +-241, +-8330790, +-240, +-8334754, +-239, +-8338986, +-237, +-8347500, +-236, +-8351786, +-235, +-8355835, +-234, +-8360156, +-232, +-8368854, +-231, +-8372973, +-230, +-8377369, +-229, +-8381784, +-228, +-8386219, +-226, +-8394883, +-225, +-8399377, +-224, +-8403890, +-223, +-8408424, +-222, +-8412710, +-220, +-8421880, +-219, +-8426496, +-218, +-8431134, +-217, +-8435519, +-216, +-8440199, +-215, +-8444901, +-214, +-8449625, +-212, +-8458860, +-211, +-8463650, +-210, +-8468464, +-209, +-8473301, +-208, +-8477875, +-207, +-8482758, +-206, +-8487665, +-205, +-8492596, +-203, +-8502238, +-202, +-8507242, +-201, +-8512271, +-200, +-8517325, +-199, +-8522106, +-198, +-8527210, +-197, +-8532341, +-196, +-8537498, +-195, +-8542376, +-194, +-8547585, +-193, +-8552821, +-192, +-8558085, +-191, +-8563377, +-190, +-8568383, +-189, +-8573730, +-188, +-8579106, +-187, +-8584510, +-186, +-8589624, +-185, +-8595085, +-184, +-8600577, +-183, +-8606099, +-182, +-8611652, +-181, +-8616907, +-180, +-8622520, +-179, +-8628165, +-178, +-8633842, +-177, +-8639215, +-176, +-8644955, +-175, +-8650729, +-174, +-8656536, +-173, +-8662377, +-172, +-8667906, +-171, +-8673814, +-170, +-8679757, +-169, +-8685735, +-169, +-8685735, +-168, +-8691395, +-167, +-8697444, +-166, +-8703529, +-165, +-8709652, +-164, +-8715813, +-163, +-8721646, +-162, +-8727881, +-161, +-8734155, +-160, +-8740469, +-160, +-8740469, +-159, +-8746448, +-158, +-8752840, +-157, +-8759273, +-156, +-8765748, +-155, +-8772266, +-154, +-8778438, +-154, +-8778438, +-153, +-8785039, +-152, +-8791684, +-151, +-8798373, +-150, +-8804709, +-150, +-8804709, +-149, +-8811486, +-148, +-8818310, +-147, +-8825180, +-146, +-8832097, +-145, +-8838652, +-145, +-8838652, +-144, +-8845664, +-143, +-8852725, +-142, +-8859837, +-142, +-8859837, +-141, +-8866576, +-140, +-8873787, +-139, +-8881051, +-138, +-8888367, +-138, +-8888367, +-137, +-8895738, +-136, +-8902725, +-135, +-8910202, +-135, +-8910202, +-134, +-8917736, +-133, +-8925327, +-133, +-8925327, +-132, +-8932525, +-131, +-8940229, +-130, +-8947994, +-130, +-8947994, +-129, +-8955819, +-128, +-8963706, +-128, +-8963706, +-127, +-8971186, +-126, +-8979195, +-125, +-8987269, +-125, +-8987269, +-124, +-8995409, +-123, +-9003131, +-123, +-9003131, +-122, +-9011402, +-121, +-9019741, +-121, +-9019741, +-120, +-9028151, +-119, +-9036632, +-119, +-9036632, +-118, +-9044680, +-117, +-9053303, +-117, +-9053303, +-116, +-9062001, +-115, +-9070775, +-115, +-9070775, +-114, +-9079104, +-114, +-9079104, +-113, +-9088031, +-112, +-9097037, +-112, +-9097037, +-111, +-9106126, +-110, +-9115298, +-110, +-9115298, +-109, +-9124008, +-109, +-9124008, +-108, +-9133346, +-107, +-9142772, +-107, +-9142772, +-106, +-9152288, +-106, +-9152288, +-105, +-9161328, +-104, +-9171022, +-104, +-9171022, +-103, +-9180812, +-103, +-9180812, +-102, +-9190699, +-102, +-9190699, +-101, +-9200684, +-100, +-9210174, +-100, +-9210174, +-99, +-9220357, +-99, +-9220357, +-98, +-9230645, +-98, +-9230645, +-97, +-9241039, +-97, +-9241039, +-96, +-9250922, +-95, +-9261530, +-95, +-9261530, +-94, +-9272253, +-94, +-9272253, +-93, +-9283091, +-93, +-9283091, +-92, +-9293401, +-92, +-9293401, +-91, +-9304472, +-91, +-9304472, +-90, +-9315667, +-90, +-9315667, +-89, +-9326990, +-89, +-9326990, +-88, +-9338441, +-88, +-9338441, +-87, +-9349341, +-87, +-9349341, +-86, +-9361053, +-86, +-9361053, +-85, +-9372904, +-85, +-9372904, +-84, +-9384897, +-84, +-9384897, +-83, +-9396317, +-83, +-9396317, +-82, +-9408596, +-82, +-9408596, +-82, +-9408596, +-81, +-9421028, +-81, +-9421028, +-80, +-9433616, +-80, +-9433616, +-79, +-9446365, +-79, +-9446365, +-78, +-9458514, +-78, +-9458514, +-77, +-9471586, +-77, +-9471586, +-77, +-9471586, +-76, +-9484831, +-76, +-9484831, +-75, +-9498254, +-75, +-9498254, +-74, +-9511054, +-74, +-9511054, +-74, +-9511054, +-73, +-9524836, +-73, +-9524836, +-72, +-9538811, +-72, +-9538811, +-72, +-9538811, +-71, +-9552984, +-71, +-9552984, +-70, +-9567360, +-70, +-9567360, +-70, +-9567360, +-69, +-9581083, +-69, +-9581083, +-68, +-9595872, +-68, +-9595872, +-68, +-9595872, +-67, +-9610883, +-67, +-9610883, +-66, +-9626123, +-66, +-9626123, +-66, +-9626123, +-65, +-9640682, +-65, +-9640682, +-65, +-9640682, +-64, +-9656387, +-64, +-9656387, +-63, +-9672342, +-63, +-9672342, +-63, +-9672342, +-62, +-9688556, +-62, +-9688556, +-62, +-9688556, +-61, +-9705038, +-61, +-9705038, +-61, +-9705038, +-60, +-9720801, +-60, +-9720801, +-60, +-9720801, +-59, +-9737827, +-59, +-9737827, +-59, +-9737827, +-58, +-9755148, +-58, +-9755148, +-57, +-9772774, +-57, +-9772774, +-57, +-9772774, +-57, +-9772774, +-56, +-9789652, +-56, +-9789652, +-56, +-9789652, +-55, +-9807903, +-55, +-9807903, +-55, +-9807903, +-54, +-9826493, +-54, +-9826493, +-54, +-9826493, +-53, +-9845435, +-53, +-9845435, +-53, +-9845435, +-52, +-9864743, +-52, +-9864743, +-52, +-9864743, +-51, +-9883262, +-51, +-9883262, +-51, +-9883262, +-51, +-9883262, +-50, +-9903322, +-50, +-9903322, +-50, +-9903322, +-49, +-9923792, +-49, +-9923792, +-49, +-9923792, +-49, +-9923792, +-48, +-9944690, +-48, +-9944690, +-48, +-9944690, +-47, +-9964766, +-47, +-9964766, +-47, +-9964766, +-47, +-9964766, +-46, +-9986548, +-46, +-9986548, +-46, +-9986548, +-46, +-9986548, +-45, +-10008815, +-45, +-10008815, +-45, +-10008815, +-44, +-10031589, +-44, +-10031589, +-44, +-10031589, +-44, +-10031589, +-43, +-10054893, +-43, +-10054893, +-43, +-10054893, +-43, +-10054893, +-42, +-10077335, +-42, +-10077335, +-42, +-10077335, +-42, +-10077335, +-41, +-10101743, +-41, +-10101743, +-41, +-10101743, +-41, +-10101743, +-41, +-10101743, +-40, +-10126763, +-40, +-10126763, +-40, +-10126763, +-40, +-10126763, +-39, +-10152425, +-39, +-10152425, +-39, +-10152425, +-39, +-10152425, +-38, +-10177194, +-38, +-10177194, +-38, +-10177194, +-38, +-10177194, +-38, +-10177194, +-37, +-10204201, +-37, +-10204201, +-37, +-10204201, +-37, +-10204201, +-36, +-10231958, +-36, +-10231958, +-36, +-10231958, +-36, +-10231958, +-36, +-10231958, +-35, +-10260508, +-35, +-10260508, +-35, +-10260508, +-35, +-10260508, +-35, +-10260508, +-34, +-10289896, +-34, +-10289896, +-34, +-10289896, +-34, +-10289896, +-33, +-10318368, +-33, +-10318368, +-33, +-10318368, +-33, +-10318368, +-33, +-10318368, +-33, +-10318368, +-32, +-10349534, +-32, +-10349534, +-32, +-10349534, +-32, +-10349534, +-32, +-10349534, +-31, +-10381704, +-31, +-10381704, +-31, +-10381704, +-31, +-10381704, +-31, +-10381704, +-30, +-10414942, +-30, +-10414942, +-30, +-10414942, +-30, +-10414942, +-30, +-10414942, +-30, +-10414942, +-29, +-10447268, +-29, +-10447268, +-29, +-10447268, +-29, +-10447268, +-29, +-10447268, +-28, +-10482800, +-28, +-10482800, +-28, +-10482800, +-28, +-10482800, +-28, +-10482800, +-28, +-10482800, +-28, +-10482800, +-27, +-10519640, +-27, +-10519640, +-27, +-10519640, +-27, +-10519640, +-27, +-10519640, +-27, +-10519640, +-26, +-10557890, +-26, +-10557890, +-26, +-10557890, +-26, +-10557890, +-26, +-10557890, +-26, +-10557890, +-25, +-10597661, +-25, +-10597661, +-25, +-10597661, +-25, +-10597661, +-25, +-10597661, +-25, +-10597661, +-25, +-10597661, +-24, +-10636596, +-24, +-10636596, +-24, +-10636596, +-24, +-10636596, +-24, +-10636596, +-24, +-10636596, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-23, +-10679695, +-22, +-10724736, +-22, +-10724736, +-22, +-10724736, +-22, +-10724736, +-22, +-10724736, +-22, +-10724736, +-22, +-10724736, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-21, +-10771901, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-20, +-10818421, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-19, +-10870341, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-18, +-10925105, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-17, +-10983043, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-16, +-11044545, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-15, +-11106103, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-14, +-11175947, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-13, +-11251037, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-12, +-11332227, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-11, +-11415177, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-10, +-11511568, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-9, +-11618252, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-8, +-11737693, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-7, +-11873358, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-6, +-12020412, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-5, +-12204716, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-4, +-12430840, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-3, +-12723509, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-2, +-13109172, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13802319, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511, +-1, +-13815511 diff --git a/rce/rcecalib/eudaq/BufferSerializer.cc b/rce/rcecalib/eudaq/BufferSerializer.cc new file mode 100644 index 0000000000000000000000000000000000000000..fe71c3a0b41162b1fa97d5eabca2f3ff3df2d44e --- /dev/null +++ b/rce/rcecalib/eudaq/BufferSerializer.cc @@ -0,0 +1,32 @@ +#include "eudaq/BufferSerializer.hh" + +namespace eudaq { + + BufferSerializer::BufferSerializer(Deserializer & des) : m_offset(0) { + des.read(m_data); + } + + void BufferSerializer::Serialize(Serializer & ser) const { + ser.write(m_data); + } + + void BufferSerializer::Serialize(const unsigned char * data, size_t len) { + m_data.insert(m_data.end(), data, data+len); + } + + void BufferSerializer::Deserialize(unsigned char * data, size_t len) { + if (!len) return; + if (len+m_offset > m_data.size()) { + std::cout<<"Deserialize asked for " + to_string(len) + + ", only have " + to_string(m_data.size()-m_offset)<<std::endl; + } + std::copy(&m_data[m_offset], &m_data[m_offset] + len, data); + //m_data.erase(m_data.begin(), m_data.begin() + len); + m_offset += len; + //std::string tmp(data, data+len); + //std::cout << "Deserialize: " << len << /*" \"" << tmp << "\"" <<*/ std::endl; + //tmp = std::string(begin(), end()); + //std::cout << "Remaining: " << (end()-begin()) << /*" \"" << tmp << "\"" <<*/ std::endl; + } + +} diff --git a/rce/rcecalib/eudaq/BufferSerializer.hh b/rce/rcecalib/eudaq/BufferSerializer.hh new file mode 100644 index 0000000000000000000000000000000000000000..34ae64813a3db688bf030f50854a65151699b4bf --- /dev/null +++ b/rce/rcecalib/eudaq/BufferSerializer.hh @@ -0,0 +1,33 @@ +#ifndef EUDAQ_INCLUDED_BufferSerializer +#define EUDAQ_INCLUDED_BufferSerializer + +#include <deque> +#include <algorithm> +#include <iostream> +#include "eudaq/Serializer.hh" +#include "eudaq/Exception.hh" + +namespace eudaq { + + class BufferSerializer : public Serializer, public Deserializer, public Serializable { + public: + BufferSerializer() : m_offset(0) {} + template<typename InIt> + BufferSerializer(InIt first, InIt last) : m_data(first, last), m_offset(0) { + } + BufferSerializer(Deserializer &); + void clear() { m_data.clear(); m_offset = 0; } + const unsigned char & operator [] (size_t i) const { return m_data[i]; } + size_t size() const { return m_data.size(); } + virtual bool HasData() { return m_data.size() != 0; } + virtual void Serialize(Serializer &) const; + private: + virtual void Serialize(const unsigned char * data, size_t len); + virtual void Deserialize(unsigned char * data, size_t len); + std::vector<unsigned char> m_data; + size_t m_offset; + }; + +} + +#endif // EUDAQ_INCLUDED_BufferSerializer diff --git a/rce/rcecalib/eudaq/CommandReceiver.cc b/rce/rcecalib/eudaq/CommandReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..796afb87f79a5270c109140dd89c32175f134b26 --- /dev/null +++ b/rce/rcecalib/eudaq/CommandReceiver.cc @@ -0,0 +1,154 @@ +#include "eudaq/CommandReceiver.hh" +#include "eudaq/TransportFactory.hh" +#include "eudaq/BufferSerializer.hh" +#include "eudaq/Exception.hh" +#include "eudaq/Utils.hh" +#include <iostream> +#include <ostream> + +namespace eudaq { + + namespace { + + void * CommandReceiver_thread(void * arg) { + CommandReceiver * cr = static_cast<CommandReceiver *>(arg); + try { + cr->CommandThread(); + } catch (const std::exception & e) { + std::cout << "Command Thread exiting due to exception:\n" << e.what() << std::endl; + } catch (...) { + std::cout << "Command Thread exiting due to unknown exception." << std::endl; + } + return 0; + } + + } // anonymous namespace + + CommandReceiver::CommandReceiver(const std::string & type, const std::string & name, + const std::string & runcontrol, bool startthread) + : m_cmdclient(TransportFactory::CreateClient(runcontrol)), + m_done(false), + m_type(type), + m_name(name), + m_threadcreated(false) + { + if (!m_cmdclient->IsNull()) { + std::string packet; + if (!m_cmdclient->ReceivePacket(&packet, 1000000)) EUDAQ_THROW("No response from RunControl server"); + // check packet is OK ("EUDAQ.CMD.RunControl nnn") + size_t i0 = 0, i1 = packet.find(' '); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + std::string part(packet, i0, i1); + if (part != "OK") EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + i0 = i1+1; + i1 = packet.find(' ', i0); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + part = std::string(packet, i0, i1-i0); + if (part != "EUDAQ") EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + i0 = i1+1; + i1 = packet.find(' ', i0); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + part = std::string(packet, i0, i1-i0); + if (part != "CMD") EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + i0 = i1+1; + i1 = packet.find(' ', i0); + part = std::string(packet, i0, i1-i0); + if (part != "RunControl") EUDAQ_THROW("Invalid response from RunControl server: '" + packet + "'"); + + m_cmdclient->SendPacket("OK EUDAQ CMD " + m_type + " " + m_name); + packet = ""; + if (!m_cmdclient->ReceivePacket(&packet, 1000000)) EUDAQ_THROW("No response from RunControl server"); + i1 = packet.find(' '); + if (std::string(packet, 0, i1) != "OK") EUDAQ_THROW("Connection refused by RunControl server: " + packet); + } + + m_cmdclient->SetCallback(TransportCallback(this, &CommandReceiver::CommandHandler)); + + if (startthread) StartThread(); + } + + void CommandReceiver::StartThread() { + size_t stacksize=256000; + pthread_attr_init(&m_threadattr); + pthread_attr_setstacksize(&m_threadattr, stacksize); + if (pthread_create(&m_thread, &m_threadattr, CommandReceiver_thread, this) != 0) { + m_threadcreated = true; + } + } + + void CommandReceiver::SetStatus(Status::Level level, const std::string & info) { + m_status = Status(level, info); + } + + void CommandReceiver::Process(int timeout) { + m_cmdclient->Process(timeout); + } + + void CommandReceiver::OnLog(const std::string & param) { + //EUDAQ_LOG_CONNECT(m_type, m_name, param); + std::cout<<"Logging "<<param<<std::endl; + //return false; + } + + void CommandReceiver::OnIdle() { + mSleep(1); + } + + void CommandReceiver::CommandThread() { + while (!m_done) { + m_cmdclient->Process(); + OnIdle(); + } + } + + void CommandReceiver::CommandHandler(TransportEvent & ev) { + if (ev.etype == TransportEvent::RECEIVE) { + std::string cmd = ev.packet, param; + size_t i = cmd.find('\0'); + if (i != std::string::npos) { + param = std::string(cmd, i+1); + cmd = std::string(cmd, 0, i); + } + //std::cout << "(" << cmd << ")(" << param << ")" << std::endl; + if (cmd == "CONFIG") { + std::string section = m_type; + if (m_name != "") section += "." + m_name; + Configuration conf(param, section); + OnConfigure(conf); + } else if (cmd == "PREPARE") { + OnPrepareRun(from_string(param, 0)); + } else if (cmd == "START") { + OnStartRun(from_string(param, 0)); + } else if (cmd == "STOP") { + OnStopRun(); + } else if (cmd == "TERMINATE") { + OnTerminate(); + } else if (cmd == "RESET") { + OnReset(); + } else if (cmd == "STATUS") { + OnStatus(); + } else if (cmd == "DATA") { + OnData(param); + } else if (cmd == "LOG") { + OnLog(param); + } else if (cmd == "SERVER") { + OnServer(); + } else if (cmd == "GETRUN") { + OnGetRun(); + } else { + OnUnrecognised(cmd, param); + } + //std::cout << "Response = " << m_status << std::endl; + BufferSerializer ser; + m_status.Serialize(ser); + m_cmdclient->SendPacket(ser); + } + } + + CommandReceiver::~CommandReceiver() { + m_done = true; + if (m_threadcreated) pthread_join(m_thread, 0); + delete m_cmdclient; + } + +} diff --git a/rce/rcecalib/eudaq/CommandReceiver.hh b/rce/rcecalib/eudaq/CommandReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..fc042e868a2c94d13e3a17e3ebeab35c02867bb0 --- /dev/null +++ b/rce/rcecalib/eudaq/CommandReceiver.hh @@ -0,0 +1,51 @@ +#ifndef EUDAQ_INCLUDED_CommandReceiver +#define EUDAQ_INCLUDED_CommandReceiver + +#include "eudaq/TransportClient.hh" +#include "eudaq/Configuration.hh" +#include "eudaq/Status.hh" +#include <pthread.h> +#include <string> +#include <iosfwd> + +namespace eudaq { + + class CommandReceiver { + public: + CommandReceiver(const std::string & type, const std::string & name, const std::string & runcontrol, + bool startthread = true); + void SetStatus(Status::Level level, const std::string & info = ""); + virtual ~CommandReceiver(); + + virtual void OnConfigure(const Configuration & param) { std::cout << "Config:\n" << param << std::endl; } + virtual void OnPrepareRun(unsigned /*runnumber*/) {} + virtual void OnStartRun(unsigned /*runnumber*/) {} + virtual void OnStopRun() {} + virtual void OnTerminate() {} + virtual void OnReset() {} + virtual void OnStatus() {} + virtual void OnData(const std::string & /*param*/) {} + virtual void OnLog(const std::string & /*param*/); + virtual void OnServer() {} + virtual void OnGetRun() {} + virtual void OnIdle(); + virtual void OnUnrecognised(const std::string & /*cmd*/, const std::string & /*param*/) {} + + void Process(int timeout); + void CommandThread(); + void StartThread(); + protected: + Status m_status; + TransportClient * m_cmdclient; + private: + bool m_done; + std::string m_type, m_name; + void CommandHandler(TransportEvent &); + pthread_t m_thread; + pthread_attr_t m_threadattr; + bool m_threadcreated; + }; + +} + +#endif // EUDAQ_INCLUDED_CommandReceiver diff --git a/rce/rcecalib/eudaq/Configuration.cc b/rce/rcecalib/eudaq/Configuration.cc new file mode 100644 index 0000000000000000000000000000000000000000..85ecec7c0efeb0c352659490e5eac007311172b2 --- /dev/null +++ b/rce/rcecalib/eudaq/Configuration.cc @@ -0,0 +1,153 @@ +#include "eudaq/Configuration.hh" + +#include <fstream> +#include <iostream> +#include <cstdlib> + +namespace eudaq { + + Configuration::Configuration(const std::string & config, const std::string & section) + : m_cur(&m_config[""]) { + std::istringstream confstr(config); + Load(confstr, section); + } + + Configuration::Configuration(std::istream & conffile, const std::string & section) + : m_cur(&m_config[""]) { + Load(conffile, section); + } + + Configuration::Configuration(const Configuration & other) + : m_config(other.m_config) + { + SetSection(other.m_section); + } + + std::string Configuration::Name() const { + map_t::const_iterator it = m_config.find(""); + if (it == m_config.end()) return ""; + section_t::const_iterator it2 = it->second.find("Name"); + if (it2 == it->second.end()) return ""; + return it2->second; + } + + void Configuration::Save(std::ostream & stream) const { + for (map_t::const_iterator i = m_config.begin(); i != m_config.end(); ++i) { + if (i->first != "") { + stream << "[" << i->first << "]\n"; + } + for (section_t::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { + stream << j->first << " = " << j->second << "\n"; + } + stream << "\n"; + } + } + + Configuration & Configuration::operator = (const Configuration & other) { + m_config = other.m_config; + SetSection(other.m_section); + return *this; + } + + void Configuration::Load(std::istream & stream, const std::string & section) { + map_t config; + section_t * cur_sec = &config[""]; + for (;;) { + std::string line; + std::getline(stream, line); + if (stream.eof()) break; + size_t equals = line.find('='); + if (equals == std::string::npos) { + line = trim(line); + if (line == "" || line[0] == ';' || line[0] == '#') continue; + if (line[0] == '[' && line[line.length()-1] == ']') { + line = std::string(line, 1, line.length()-2); + // TODO: check name is alphanumeric? + //std::cerr << "Section " << line << std::endl; + cur_sec = &config[line]; + } + } else { + std::string key = trim(std::string(line, 0, equals)); + // TODO: check key does not already exist + // handle lines like: blah = "foo said ""bar""; ok." # not "baz" + line = trim(std::string(line, equals+1)); + if ((line[0] == '\'' && line[line.length()-1] == '\'') || + (line[0] == '\"' && line[line.length()-1] == '\"')) { + line = std::string(line, 1, line.length()-2); + } else { + size_t i = line.find_first_of(";#"); + if (i != std::string::npos) line = trim(std::string(line, 0, i)); + } + //std::cerr << "Key " << key << " = " << line << std::endl; + (*cur_sec)[key] = line; + } + } + m_config = config; + SetSection(section); + } + + bool Configuration::SetSection(const std::string & section) const { + map_t::const_iterator i = m_config.find(section); + if (i == m_config.end()) return false; + m_section = section; + m_cur = const_cast<section_t*>(&i->second); + return true; + } + + bool Configuration::SetSection(const std::string & section) { + m_section = section; + m_cur = &m_config[section]; + return true; + } + + std::string Configuration::Get(const std::string & key, const std::string & def) const { + try { + return GetString(key); + } catch (const Exception &) { + // ignore: return default + } + return def; + } + + double Configuration::Get(const std::string & key, double def) const { + try { + return from_string(GetString(key), def); + } catch (const Exception &) { + // ignore: return default + } + return def; + } + + long long Configuration::Get(const std::string & key, long long def) const { + try { + std::string s = GetString(key); + return strtoll(s.c_str(), 0, 0); + } catch (const Exception &) { + // ignore: return default + } + return def; + } + + int Configuration::Get(const std::string & key, int def) const { + try { + std::string s = GetString(key); + return std::strtol(s.c_str(), 0, 0); + } catch (const Exception &) { + // ignore: return default + } + return def; + } + + std::string Configuration::GetString(const std::string & key) const { + section_t::const_iterator i = m_cur->find(key); + if (i != m_cur->end()) { + return i->second; + } + throw Exception("Configuration: key not found"); + } + + void Configuration::SetString(const std::string & key, const std::string & val) { + (*m_cur)[key] = val; + } + +} diff --git a/rce/rcecalib/eudaq/Configuration.hh b/rce/rcecalib/eudaq/Configuration.hh new file mode 100644 index 0000000000000000000000000000000000000000..a62a7d7e771b96f05883e5fd04f1cb482267ae7a --- /dev/null +++ b/rce/rcecalib/eudaq/Configuration.hh @@ -0,0 +1,59 @@ +#ifndef EUDAQ_INCLUDED_Configuration +#define EUDAQ_INCLUDED_Configuration + +#include "eudaq/Utils.hh" +#include "eudaq/Exception.hh" +#include <string> +#include <map> + +namespace eudaq { + + class Configuration { + public: + Configuration(const std::string & config = "", const std::string & section = ""); + Configuration(std::istream & conffile, const std::string & section = ""); + Configuration(const Configuration & other); + void Save(std::ostream & file) const; + void Load(std::istream & file, const std::string & section); + bool SetSection(const std::string & section) const; + bool SetSection(const std::string & section); + std::string operator [] (const std::string & key) const { return GetString(key); } + std::string Get(const std::string & key, const std::string & def) const; + double Get(const std::string & key, double def) const; + long long Get(const std::string & key, long long def) const; + int Get(const std::string & key, int def) const; + template <typename T> + T Get(const std::string & key, const std::string fallback, const T & def) const { + return Get(key, Get(fallback, def)); + } + std::string Get(const std::string & key, const std::string fallback, const char * def) const { + return Get(key, Get(fallback, def)); + } + //std::string Get(const std::string & key, const std::string & def = ""); + template <typename T> + void Set(const std::string & key, const T & val); + std::string Name() const; + Configuration & operator = (const Configuration & other); + private: + std::string GetString(const std::string & key) const; + void SetString(const std::string & key, const std::string & val); + typedef std::map<std::string, std::string> section_t; + typedef std::map<std::string, section_t> map_t; + map_t m_config; + mutable std::string m_section; + mutable section_t * m_cur; + }; + + inline std::ostream & operator << (std::ostream & os, const Configuration & c) { + c.Save(os); + return os; + } + + template <typename T> + inline void Configuration::Set(const std::string & key, const T & val) { + SetString(key, to_string(val)); + } + +} + +#endif // EUDAQ_INCLUDED_Configuration diff --git a/rce/rcecalib/eudaq/DataSender.cc b/rce/rcecalib/eudaq/DataSender.cc new file mode 100644 index 0000000000000000000000000000000000000000..3ef2e920783144727a9cca0d877275333bd59775 --- /dev/null +++ b/rce/rcecalib/eudaq/DataSender.cc @@ -0,0 +1,63 @@ +#include "eudaq/DataSender.hh" +#include "eudaq/TransportFactory.hh" +#include "eudaq/Exception.hh" + +namespace eudaq { + + DataSender::DataSender(const std::string & type, const std::string & name) + : m_type(type), + m_name(name), + m_dataclient(0) {} + + void DataSender::Connect(const std::string & server) { + delete m_dataclient; + m_dataclient = TransportFactory::CreateClient(server); + + std::string packet; + if (!m_dataclient->ReceivePacket(&packet, 1000000)) EUDAQ_THROW("No response from DataCollector server"); + size_t i0 = 0, i1 = packet.find(' '); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from DataCollector server"); + std::string part(packet, i0, i1); + if (part != "OK") EUDAQ_THROW("Invalid response from DataCollector server: " + packet); + i0 = i1+1; + i1 = packet.find(' ', i0); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from DataCollector server"); + part = std::string(packet, i0, i1-i0); + if (part != "EUDAQ") EUDAQ_THROW("Invalid response from DataCollector server, part=" + part); + i0 = i1+1; + i1 = packet.find(' ', i0); + if (i1 == std::string::npos) EUDAQ_THROW("Invalid response from DataCollector server"); + part = std::string(packet, i0, i1-i0); + if (part != "DATA") EUDAQ_THROW("Invalid response from DataCollector server, part=" + part); + i0 = i1+1; + i1 = packet.find(' ', i0); + part = std::string(packet, i0, i1-i0); + if (part != "DataCollector" ) EUDAQ_THROW("Invalid response from DataCollector server, part=" + part); + + m_dataclient->SendPacket("OK EUDAQ DATA " + m_type + " " + m_name); + packet = ""; + if (!m_dataclient->ReceivePacket(&packet, 1000000)) EUDAQ_THROW("No response from DataCollector server"); + i1 = packet.find(' '); + if (std::string(packet, 0, i1) != "OK") EUDAQ_THROW("Connection refused by DataCollector server: " + packet); + } + + void DataSender::SendEvent(const Event &ev) { + if (!m_dataclient) EUDAQ_THROW("Transport not connected error"); + //EUDAQ_DEBUG("Serializing event"); + //BufferSerializer ser; + m_ser.clear(); + ev.Serialize(m_ser); + //EUDAQ_DEBUG("Sending event"); + m_dataclient->SendPacket(m_ser); + //EUDAQ_DEBUG("Sent event"); + } + + void DataSender::SendEvent(unsigned char* data, int size){ + m_dataclient->SendPacket((unsigned char*)data, size); + } + + DataSender::~DataSender() { + delete m_dataclient; + } + +} diff --git a/rce/rcecalib/eudaq/DataSender.hh b/rce/rcecalib/eudaq/DataSender.hh new file mode 100644 index 0000000000000000000000000000000000000000..e3a6b18e35eb238cc131ab1ed8c2b9d7e02b2f0e --- /dev/null +++ b/rce/rcecalib/eudaq/DataSender.hh @@ -0,0 +1,27 @@ +#ifndef EUDAQ_INCLUDED_DataSender +#define EUDAQ_INCLUDED_DataSender + +#include "eudaq/Event.hh" +#include "eudaq/TransportClient.hh" +#include "eudaq/Serializer.hh" +#include "eudaq/BufferSerializer.hh" +#include <string> + +namespace eudaq { + + class DataSender { + public: + DataSender(const std::string & type, const std::string & name); + ~DataSender(); + void Connect(const std::string & server); + void SendEvent(const Event &); + void SendEvent(unsigned char* data, int size); + private: + std::string m_type, m_name; + TransportClient * m_dataclient; + BufferSerializer m_ser; + }; + +} + +#endif // EUDAQ_INCLUDED_DataSender diff --git a/rce/rcecalib/eudaq/DataSenderIF.cc b/rce/rcecalib/eudaq/DataSenderIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..9d2da306596d9d80f9ec858440e1428342f7683c --- /dev/null +++ b/rce/rcecalib/eudaq/DataSenderIF.cc @@ -0,0 +1,25 @@ +#include "rcecalib/eudaq/DataSenderIF.hh" + +#include "rcecalib/eudaq/DataSender.hh" + +eudaq::DataSender * DataSenderIF::m_dataSender = 0; + +void DataSenderIF::setDataSender(eudaq::DataSender * dataSender) +{ m_dataSender = dataSender; return; } + +void DataSenderIF::SendEvent(eudaq::Event * event) +{ + if (m_dataSender != 0) + { + m_dataSender->SendEvent(*event); + } + return; +} +void DataSenderIF::SendEvent(unsigned char *data, int size) +{ + if (m_dataSender != 0) + { + m_dataSender->SendEvent(data, size); + } + return; +} diff --git a/rce/rcecalib/eudaq/DataSenderIF.hh b/rce/rcecalib/eudaq/DataSenderIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..4a4ba58354504cbf311043cd9c11ebb1817a48b9 --- /dev/null +++ b/rce/rcecalib/eudaq/DataSenderIF.hh @@ -0,0 +1,27 @@ +#ifndef DATASENDER_HH +#define DATASENDER_HH + + /* +A static interface to the DataSender eudaq class so that one instance may be easily shared across an +entire object-oritented application. + */ + +namespace eudaq +{ + class Event; + class DataSender; +} + +class DataSenderIF +{ + public: + static void SendEvent(eudaq::Event * event); + static void SendEvent(unsigned char *data, int size); + static void setDataSender(eudaq::DataSender * dataSender); + static bool hasInstance() {return m_dataSender != 0;} + + private: + static eudaq::DataSender * m_dataSender; +}; + +#endif diff --git a/rce/rcecalib/eudaq/DetectorEvent.cc b/rce/rcecalib/eudaq/DetectorEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..a766443e36d45e787dfd61d1b22837daefd8bf4b --- /dev/null +++ b/rce/rcecalib/eudaq/DetectorEvent.cc @@ -0,0 +1,45 @@ +#include "eudaq/DetectorEvent.hh" + +#include <ostream> + +namespace eudaq { + + EUDAQ_DEFINE_EVENT(DetectorEvent, str2id("_DET")); + + DetectorEvent::DetectorEvent(Deserializer & ds) : + Event(ds) + { + unsigned n; + ds.read(n); + //std::cout << "Num=" << n << std::endl; + for (size_t i = 0; i < n; ++i) { + counted_ptr<Event> ev(EventFactory::Create(ds)); + m_events.push_back(ev); + } + } + + void DetectorEvent::AddEvent(counted_ptr<Event> evt) { + if (!evt.get()) std::cout<<"Adding null event!"<<std::endl; + m_events.push_back(evt); + SetFlags(evt->GetFlags()); + } + + void DetectorEvent::Print(std::ostream & os) const { + Event::Print(os); + os << " {\n"; + for (size_t i = 0; i < NumEvents(); ++i) { + os << " " << *GetEvent(i) << std::endl; + } + os << "}"; + } + + void DetectorEvent::Serialize(Serializer & ser) const { + Event::Serialize(ser); + ser.write((unsigned)m_events.size()); + for (size_t i = 0; i < m_events.size(); ++i) { + m_events[i]->Serialize(ser); + } + } + + +} diff --git a/rce/rcecalib/eudaq/DetectorEvent.hh b/rce/rcecalib/eudaq/DetectorEvent.hh new file mode 100644 index 0000000000000000000000000000000000000000..ae15267a4789481685b244098a5ebb227d682daf --- /dev/null +++ b/rce/rcecalib/eudaq/DetectorEvent.hh @@ -0,0 +1,51 @@ +#ifndef EUDAQ_INCLUDED_DetectorEvent +#define EUDAQ_INCLUDED_DetectorEvent + +#include <vector> +#include "eudaq/Event.hh" +#include "eudaq/counted_ptr.hh" + +namespace eudaq { + + class DetectorEvent : public Event { + EUDAQ_DECLARE_EVENT(DetectorEvent); + public: + virtual void Serialize(Serializer &) const; + explicit DetectorEvent(unsigned runnumber, unsigned eventnumber, unsigned long long timestamp) : + Event(runnumber, eventnumber, timestamp) + {} +// explicit DetectorEvent(const TLUEvent & tluev) : +// Event(tluev.GetRunNumber(), tluev.GetEventNumber(), tluev.GetTimestamp()) +// {} + explicit DetectorEvent(Deserializer&); + void AddEvent(counted_ptr<Event> evt); + virtual void Print(std::ostream &) const; + + /// Return "DetectorEvent" as type. + virtual std::string GetType() const {return "DetectorEvent";} + + size_t NumEvents() const { return m_events.size(); } + Event * GetEvent(size_t i) { return m_events[i].get(); } + const Event * GetEvent(size_t i) const { return m_events[i].get(); } + counted_ptr<Event> GetEventPtr(size_t i) { return m_events[i]; } + template <typename T> + const T * GetSubEvent(int n = 0) const { + for (size_t i = 0; i < NumEvents(); i++) { + const T * sev = dynamic_cast<const T*>(GetEvent(i)); + if (sev) { + if (n > 0) { + --n; + } else { + return sev; + } + } + } + return 0; + } + private: + std::vector<counted_ptr<Event> > m_events; + }; + +} + +#endif // EUDAQ_INCLUDED_TLUEvent diff --git a/rce/rcecalib/eudaq/Event.cc b/rce/rcecalib/eudaq/Event.cc new file mode 100644 index 0000000000000000000000000000000000000000..9f4fe07df04cdaa64e4cf72e5b522761b8de99cd --- /dev/null +++ b/rce/rcecalib/eudaq/Event.cc @@ -0,0 +1,117 @@ +#include <ostream> +#include <iostream> + +#include "eudaq/Event.hh" + +namespace eudaq { + + namespace { + + static const char * const FLAGNAMES[] = { + "BORE", + "EORE", + "HITS" + }; + + } + + Event::Event(Deserializer & ds) { + ds.read(m_flags); + ds.read(m_runnumber); + ds.read(m_eventnumber); + ds.read(m_timestamp); + ds.read(m_tags); + } + + void Event::Serialize(Serializer & ser) const { + //std::cout << "Serialize id = " << std::hex << get_id() << std::endl; + ser.write(get_id()); + ser.write(m_flags); + ser.write(m_runnumber); + ser.write(m_eventnumber); + ser.write(m_timestamp); + ser.write(m_tags); + } + + void Event::Print(std::ostream & os) const { + os << "Type=" << id2str(get_id()) << ":" << GetSubType() + << ", Number=" << m_runnumber << "." << m_eventnumber; + if (m_timestamp != NOTIMESTAMP) + os << ", Time=0x" << to_hex(m_timestamp, 16); + if (m_flags) { + unsigned f = m_flags; + bool first = true; + for (size_t i = 0; f > 0; ++i, f >>= 1) { + if (f & 1) { + os << (first ? ", Flags=" : ",") + << (i < sizeof FLAGNAMES / sizeof *FLAGNAMES ? std::string(FLAGNAMES[i]) : to_string(i)); + first = false; + } + } + } + if (m_tags.size() > 0) { + for (map_t::const_iterator i = m_tags.begin(); i != m_tags.end(); ++i) { + os << (i == m_tags.begin() ? ", {" : ", ") << i->first << "=" << i->second; + } + os << "}"; + } + } + + unsigned Event::str2id(const std::string & str) { + unsigned long result = 0; + for (size_t i = 0; i < 4; ++i) { + if (i < str.length()) result |= str[i] << (8*i); + } + //std::cout << "str2id(" << str << ") = " << std::hex << result << std::dec << std::endl; + return result; + } + + std::string Event::id2str(unsigned id) { + //std::cout << "id2str(" << std::hex << id << std::dec << ")" << std::flush; + std::string result(4, '\0'); + for (int i = 0; i < 4; ++i) { + result[i] = (char)(id & 0xff); + id >>= 8; + } + for (int i = 3; i >= 0; --i) { + if (result[i] == '\0') { + result.erase(i); + break; + } + } + //std::cout << " = " << result << std::endl; + return result; + } + + Event & Event::SetTag(const std::string & name, const std::string & val) { + m_tags[name] = val; + return *this; + } + + std::string Event::GetTag(const std::string & name, const std::string & def) const { + std::map<std::string, std::string>::const_iterator i = m_tags.find(name); + if (i == m_tags.end()) return def; + return i->second; + } + + std::ostream & operator << (std::ostream &os, const Event &ev) { + ev.Print(os); + return os; + } + + EventFactory::map_t & EventFactory::get_map() { + static map_t s_map; + return s_map; + } + + void EventFactory::Register(unsigned long id, EventFactory::event_creator func) { + // TODO: check id is not already in map + get_map()[id] = func; + } + + EventFactory::event_creator EventFactory::GetCreator(unsigned long id) { + // TODO: check it exists... + return get_map()[id]; + } + +} diff --git a/rce/rcecalib/eudaq/Event.hh b/rce/rcecalib/eudaq/Event.hh new file mode 100644 index 0000000000000000000000000000000000000000..af074d0ddae3c0d1a9f5d9d1e8b71067a8fd79ca --- /dev/null +++ b/rce/rcecalib/eudaq/Event.hh @@ -0,0 +1,119 @@ +#ifndef EUDAQ_INCLUDED_Event +#define EUDAQ_INCLUDED_Event + +#include <string> +#include <vector> +#include <map> +#include <iosfwd> +#include <iostream> + +#include "eudaq/Serializable.hh" +#include "eudaq/Serializer.hh" +#include "eudaq/Exception.hh" +#include "eudaq/Utils.hh" + +#define EUDAQ_DECLARE_EVENT(type) \ + public: \ + static unsigned eudaq_static_id(); \ + virtual unsigned get_id() const { \ + return eudaq_static_id(); \ + } \ + private: \ + static const int EUDAQ_DUMMY_VAR_DONT_USE = 0 + +#define EUDAQ_DEFINE_EVENT(type, id) \ + unsigned type::eudaq_static_id() { \ + static const unsigned id_(id); \ + return id_; \ + } \ + namespace _eudaq_dummy_ { \ + static RegisterEventType<type> eudaq_reg;\ + } \ + static const int EUDAQ_DUMMY_VAR_DONT_USE = 0 + +namespace eudaq { + + static const unsigned long long NOTIMESTAMP = (unsigned long long)-1; + + class Event : public Serializable { + public: + enum Flags { FLAG_BORE=1, FLAG_EORE=2, FLAG_HITS=4, FLAG_ALL=(unsigned)-1 }; // Matches FLAGNAMES in .cc file + Event(unsigned run, unsigned event, unsigned long long timestamp = NOTIMESTAMP, unsigned flags=0) + : m_flags(flags), m_runnumber(run), m_eventnumber(event), m_timestamp(timestamp) {} + Event(Deserializer & ds); + virtual void Serialize(Serializer &) const = 0; + + unsigned GetRunNumber() const { return m_runnumber; } + unsigned GetEventNumber() const { return m_eventnumber; } + void SetEventNumber(unsigned event){m_eventnumber=event;} + unsigned long long GetTimestamp() const { return m_timestamp; } + + /** Returns the type string of the event implementation. + * Used by the plugin mechanism to identfy the event type. + */ + virtual std::string GetSubType() const { return ""; } + + virtual void Print(std::ostream & os) const = 0; + + Event & SetTag(const std::string & name, const std::string & val); + std::string GetTag(const std::string & name, const std::string & def = "") const; + std::string GetTag(const std::string & name, const char * def) const { return GetTag(name, std::string(def)); } + template <typename T> + T GetTag(const std::string & name, T def) const { + return eudaq::from_string(GetTag(name), def); + } + + bool IsBORE() const { return GetFlags(FLAG_BORE) != 0; } + bool IsEORE() const { return GetFlags(FLAG_EORE) != 0; } + bool HasHits() const { return GetFlags(FLAG_HITS) != 0; } + + static unsigned str2id(const std::string & idstr); + static std::string id2str(unsigned id); + unsigned GetFlags(unsigned f = FLAG_ALL) const { return m_flags & f; } + void SetFlags(unsigned f) { m_flags |= f; } + void ClearFlags(unsigned f = FLAG_ALL) { m_flags &= ~f; } + virtual unsigned get_id() const = 0; + protected: + typedef std::map<std::string, std::string> map_t; + + unsigned m_flags, m_runnumber, m_eventnumber; + unsigned long long m_timestamp; + map_t m_tags; ///< Metadata tags in (name=value) pairs of strings + }; + + std::ostream & operator << (std::ostream &, const Event &); + + class EventFactory { + public: + static Event * Create(Deserializer & ds) { + unsigned id = 0; + ds.read(id); + //std::cout << "Create id = " << std::hex << id << std::dec << std::endl; + event_creator cr = GetCreator(id); + if (!cr) std::cout<<"Unrecognised Event type (" + Event::id2str(id) + ")"<<std::endl; + return cr(ds); + } + + typedef Event * (* event_creator)(Deserializer & ds); + static void Register(unsigned long id, event_creator func); + static event_creator GetCreator(unsigned long id); + + private: + typedef std::map<unsigned long, event_creator> map_t; + static map_t & get_map(); + }; + + /** A utility template class for registering an Event type. + */ + template <typename T_Evt> + struct RegisterEventType { + RegisterEventType() { + EventFactory::Register(T_Evt::eudaq_static_id(), &factory_func); + } + static Event * factory_func(Deserializer & ds) { + return new T_Evt(ds); + } + }; +} + +#endif // EUDAQ_INCLUDED_Event diff --git a/rce/rcecalib/eudaq/Exception.cc b/rce/rcecalib/eudaq/Exception.cc new file mode 100644 index 0000000000000000000000000000000000000000..65fd69c47744c81c064ba5466840c7d6de9fd176 --- /dev/null +++ b/rce/rcecalib/eudaq/Exception.cc @@ -0,0 +1,48 @@ +#include "eudaq/Exception.hh" +#include <iostream> + + +namespace eudaq { + + Exception::Exception(const std::string & msg) + : m_msg(msg), m_line(0) + {} + + const Exception & Exception::SetLocation(const std::string & file, + unsigned line, + const std::string & func) const { + m_file = file; + m_line = line; + m_func = func; + return *this; + } + + void Exception::make_text() const { + m_text = m_msg; + if (m_file.length() > 0) { + m_text += "\n From " + m_file; + if (m_line > 0) { + m_text += ":" + to_string(m_line); + } + } + if (m_func.length() > 0) m_text += "\n In " + m_func; + } + LoggedException::LoggedException(const std::string & msg) + : Exception(msg), m_logged(false) + { + } + + void LoggedException::Log() const { + if (m_logged) return; + // Only log the message once + m_logged = true; + } + + LoggedException::~LoggedException() throw() { + // Make sure the message has been logged before we die + if(m_logged==false) { + // Log(); + } + } +} + diff --git a/rce/rcecalib/eudaq/Exception.hh b/rce/rcecalib/eudaq/Exception.hh new file mode 100644 index 0000000000000000000000000000000000000000..d52629a3858d54e528d5ae8493cf2dc5177aedb7 --- /dev/null +++ b/rce/rcecalib/eudaq/Exception.hh @@ -0,0 +1,84 @@ +#ifndef EUDAQ_INCLUDED_Exception +#define EUDAQ_INCLUDED_Exception + +#include "eudaq/Utils.hh" +#include <exception> +#include <string> +#include <iostream> + +#ifndef EUDAQ_FUNC +# define EUDAQ_FUNC "" +#endif + +#define EUDAQ_THROWX(exc, msg) throw ::eudaq::InitException(exc(msg), __FILE__, __LINE__, EUDAQ_FUNC) +#define EUDAQ_THROW(msg) EUDAQ_THROWX(::eudaq::LoggedException, (msg)) + +#define EUDAQ_EXCEPTIONX(name, base) \ + class name : public base { \ + public: \ + name(const std::string & msg) \ + : base(msg) {} \ + } + +#define EUDAQ_EXCEPTION(name) EUDAQ_EXCEPTIONX(name, ::eudaq::Exception) + +namespace eudaq { + + class Exception : public std::exception { + public: + Exception(const std::string & msg); + const char * what() const throw() { + if (m_text.length() == 0) make_text(); + return m_text.c_str(); + } + // This shouldn't really be const, but it must be callable on temporary objects... + const Exception & SetLocation(const std::string & file = "", + unsigned line = 0, + const std::string & func = "") const; + virtual ~Exception() throw() { + } + protected: + std::string m_msg; + private: + void make_text() const; + mutable std::string m_text; + mutable std::string m_file, m_func; + mutable unsigned m_line; + }; + class LoggedException : public Exception { + public: + LoggedException(const std::string & msg); + void Log() const; + virtual ~LoggedException() throw(); + private: + mutable bool m_logged; + }; + + namespace { + void do_log(const Exception &) { + } + void do_log(const LoggedException & e) { + std::cout<<e.what()<<std::endl; + } + } + + + template <typename T> + const T & InitException(const T & e, const std::string & file, int line = 0, const std::string func = "") { + e.SetLocation(file, line, func); + return e; + } + + // Some useful predefined exceptions + EUDAQ_EXCEPTION(FileNotFoundException); + EUDAQ_EXCEPTION(FileExistsException); + EUDAQ_EXCEPTION(FileNotWritableException); + EUDAQ_EXCEPTION(FileReadException); + EUDAQ_EXCEPTION(FileWriteException); + EUDAQ_EXCEPTION(FileFormatException); + EUDAQ_EXCEPTION(CommunicationException); + EUDAQ_EXCEPTIONX(BusError, CommunicationException); + +} + +#endif // EUDAQ_INCLUDED_Exception diff --git a/rce/rcecalib/eudaq/FileSerializer.cc b/rce/rcecalib/eudaq/FileSerializer.cc new file mode 100644 index 0000000000000000000000000000000000000000..5261ea672f7b7777854291bf477578b65497d3df --- /dev/null +++ b/rce/rcecalib/eudaq/FileSerializer.cc @@ -0,0 +1,123 @@ +#include "eudaq/FileSerializer.hh" +#include "eudaq/Exception.hh" +#include "eudaq/Utils.hh" +#include <sys/types.h> +#include <sys/stat.h> +#include <iostream> + +namespace eudaq { + + FileSerializer::FileSerializer(const std::string & fname, bool overwrite, int wprot) + : m_file(0), m_filebytes(0), m_wprot(wprot) + { + if (!overwrite) { + FILE * fd = fopen(fname.c_str(), "rb"); + if (fd) { + fclose(fd); + EUDAQ_THROWX(FileExistsException, "File already exists: " + fname); + } + } + m_file = fopen(fname.c_str(), "wb"); + if (!m_file) EUDAQ_THROWX(FileNotFoundException, "Unable to open file: " + fname); + if (m_wprot == WP_ONOPEN) { + WriteProtect(); + } + } + + FileSerializer::~FileSerializer() { + if (m_wprot == WP_ONCLOSE) { + WriteProtect(); + } + if (m_file) { + fclose(m_file); + } + } + + void FileSerializer::Serialize(const unsigned char * data, size_t len) { + size_t written = std::fwrite(reinterpret_cast<const char *>(data), 1, len, m_file); + m_filebytes += written; + if (written != len) { + std::cout<<"Error writing to file: " + to_string(errno) + ", " + strerror(errno)<<std::endl; + } + } + + void FileSerializer::Flush() { + fflush(m_file); + } + + void FileSerializer::WriteProtect() { + fchmod(fileno(m_file), S_IRUSR | S_IRGRP | S_IROTH); + } + + FileDeserializer::FileDeserializer(const std::string & fname, bool faileof, size_t buffersize) : + m_file(0), m_faileof(faileof), m_buf(buffersize), m_start(&m_buf[0]), m_stop(m_start) + { + m_file = fopen(fname.c_str(), "rb"); + if (!m_file) EUDAQ_THROWX(FileNotFoundException, "Unable to open file: " + fname); + } + + bool FileDeserializer::HasData() { + if (level() == 0) FillBuffer(); + return level() > 0; + } + + size_t FileDeserializer::FillBuffer(size_t min) { + clearerr(m_file); + if (level() == 0) m_start = m_stop = &m_buf[0]; + unsigned char * end = &m_buf[0] + m_buf.size(); + if (size_t(end - m_stop) < min) { + // not enough space remaining before end of buffer, + // so shift everything back to the beginning of the buffer + std::memmove(m_start, &m_buf[0], level()); + m_stop -= (m_start - &m_buf[0]); + m_start = &m_buf[0]; + if (size_t(end - m_stop) < min) { + // still not enough space? nothing we can do, reduce the required amount + min = end - m_stop; + } + } + size_t read = fread(reinterpret_cast<char *>(m_stop), 1, end - m_stop, m_file); + m_stop += read; + while (read < min) { + if (feof(m_file) && m_faileof) { + throw FileReadException("End of File encountered"); + } else if (int err = ferror(m_file)) { + EUDAQ_THROWX(FileReadException, "Error reading from file: " + to_string(err)); + } else if (m_interrupting) { + m_interrupting = false; + throw InterruptedException(); + } + mSleep(10); + clearerr(m_file); + size_t bytes = fread(reinterpret_cast<char *>(m_stop), 1, end - m_stop, m_file); + read += bytes; + m_stop += bytes; + } + return read; + } + + void FileDeserializer::Deserialize(unsigned char * data, size_t len) { + if (len <= level()) { + // The buffer contains enough data + memcpy(data, m_start, len); + m_start += len; + } else if (level() > 0) { + // The buffer contains some data, so use it up first + size_t tmp = level(); + memcpy(data, m_start, tmp); + m_start = m_stop; + // Then deserialise what remains + Deserialize(data + tmp, len - tmp); + //} else if (len >= m_buf.size()/2) { + // The buffer must be empty, and we have a lot of data to read + // So read directly into the destination + //FillBuffer(data, len); + } else { + // Otherwise fill up the buffer, making sure we have at least enough data + FillBuffer(len); + // Now we have enough data in the buffer, just call deserialize again + Deserialize(data, len); + } + } + +} diff --git a/rce/rcecalib/eudaq/FileSerializer.hh b/rce/rcecalib/eudaq/FileSerializer.hh new file mode 100644 index 0000000000000000000000000000000000000000..8ad5bebab4b450aa4fca1f3bb8c9111072e79168 --- /dev/null +++ b/rce/rcecalib/eudaq/FileSerializer.hh @@ -0,0 +1,52 @@ +#ifndef EUDAQ_INCLUDED_FileSerializer +#define EUDAQ_INCLUDED_FileSerializer + +#include <string> +#include <cstdio> +#include "eudaq/Serializer.hh" +#include "eudaq/Exception.hh" +#include "eudaq/BufferSerializer.hh" + +namespace eudaq { + + class FileSerializer : public Serializer { + public: + enum WPROT { WP_NONE, WP_ONCLOSE, WP_ONOPEN }; + FileSerializer(const std::string & fname, bool overwrite = false, int writeprotect = WP_ONCLOSE); + virtual void Flush(); + unsigned long long FileBytes() const { return m_filebytes; } + void WriteProtect(); + ~FileSerializer(); + private: + virtual void Serialize(const unsigned char * data, size_t len); + FILE * m_file; + unsigned long long m_filebytes; + int m_wprot; + }; + + class FileDeserializer : public Deserializer { + public: + FileDeserializer(const std::string & fname, bool faileof = false, size_t buffersize = 65536); + virtual bool HasData(); + template <typename T> + T peek() { + FillBuffer(); + BufferSerializer buf(m_start, m_stop); + T result; + buf.read(result); + return result; + } + private: + virtual void Deserialize(unsigned char * data, size_t len); + size_t FillBuffer(size_t min = 0); + size_t level() const { return m_stop - m_start; } + typedef unsigned char *ptr_t; + FILE * m_file; + bool m_faileof; + std::vector<unsigned char> m_buf; + ptr_t m_start, m_stop; + }; + +} + +#endif // EUDAQ_INCLUDED_FileSerializer diff --git a/rce/rcecalib/eudaq/Makefile b/rce/rcecalib/eudaq/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3cd076af001b27a1deb669dc2c604a7bd6326844 --- /dev/null +++ b/rce/rcecalib/eudaq/Makefile @@ -0,0 +1,21 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +include $(RELEASE_DIR)/make/sw/rootcint.mk +endif diff --git a/rce/rcecalib/eudaq/Mutex.cc b/rce/rcecalib/eudaq/Mutex.cc new file mode 100644 index 0000000000000000000000000000000000000000..ab08699f459b7e3d498b5c040acd7957151c23a7 --- /dev/null +++ b/rce/rcecalib/eudaq/Mutex.cc @@ -0,0 +1,84 @@ +#include "eudaq/Mutex.hh" +#include "eudaq/Exception.hh" +#include <pthread.h> + +namespace eudaq { + + class Mutex::Impl { + public: + Impl() { + if (pthread_mutexattr_init(&m_attr)) { + EUDAQ_THROW("Unable to create mutex attributes"); + } + // pthread_mutexattr_settype(&m_attr, PTHREAD_MUTEX_RECURSIVE); + if (pthread_mutex_init(&m_mutex, &m_attr)) { + EUDAQ_THROW("Unable to create mutex"); + } + } + ~Impl() { + if (pthread_mutex_destroy(&m_mutex)) { + // error + } + } + pthread_mutexattr_t m_attr; + pthread_mutex_t m_mutex; + }; + + Mutex::Mutex() : m_impl(new Mutex::Impl) {} + + Mutex::~Mutex() { delete m_impl; } + + int Mutex::Lock() { + return pthread_mutex_lock(&m_impl->m_mutex); + } + + int Mutex::TryLock() { + return pthread_mutex_trylock(&m_impl->m_mutex); + } + + int Mutex::UnLock() { + return pthread_mutex_unlock(&m_impl->m_mutex); + } + + MutexLock::MutexLock(Mutex & m, bool lock) : m_mutex(m), m_locked(lock) { + if (lock && m_mutex.TryLock()) { + EUDAQ_THROW("Unable to lock mutex"); + } + } + + void MutexLock::Lock() { + if (m_mutex.TryLock()) { + EUDAQ_THROW("Unable to lock mutex"); + } + m_locked = true; + } + + void MutexLock::Release() { + if (m_locked) m_mutex.UnLock(); + m_locked = false; + } + + MutexLock::~MutexLock() { + Release(); + } + +// MutexTryLock::MutexTryLock(Mutex & m) : m_mutex(m), m_locked(true) { +// if (m_mutex.TryLock()) { +// m_locked = false; +// } +// } + +// void MutexTryLock::Release() { +// m_mutex.UnLock(); +// m_locked = false; +// } + +// MutexTryLock::~MutexTryLock() { +// if (m_locked) Release(); +// } + +// MutexTryLock::operator bool () const { +// return m_locked; +// } + +} diff --git a/rce/rcecalib/eudaq/Mutex.hh b/rce/rcecalib/eudaq/Mutex.hh new file mode 100644 index 0000000000000000000000000000000000000000..9f6199b4f6c61d9cee7f09f1a32c20c85d2b22fe --- /dev/null +++ b/rce/rcecalib/eudaq/Mutex.hh @@ -0,0 +1,42 @@ +#ifndef H_EUDAQ_MUTEX +#define H_EUDAQ_MUTEX + +namespace eudaq { + + class Mutex { + public: + Mutex(); + ~Mutex(); + int Lock(); + int TryLock(); + int UnLock(); + private: + class Impl; + Impl * m_impl; + }; + + class MutexLock { + public: + MutexLock(Mutex & m, bool lock = true); + ~MutexLock(); + void Lock(); + void Release(); + private: + Mutex & m_mutex; + bool m_locked; + }; + +// class MutexTryLock { +// public: +// MutexTryLock(Mutex & m); +// ~MutexTryLock(); +// void Release(); +// operator bool () const; +// private: +// Mutex & m_mutex; +// bool m_locked; +// }; + +} + +#endif // H_EUDAQ_MUTEX diff --git a/rce/rcecalib/eudaq/Producer.cc b/rce/rcecalib/eudaq/Producer.cc new file mode 100644 index 0000000000000000000000000000000000000000..84283f4fc26cfef878511dd3a008d230e3fe9f2c --- /dev/null +++ b/rce/rcecalib/eudaq/Producer.cc @@ -0,0 +1,14 @@ +#include "eudaq/Producer.hh" + +namespace eudaq { + + Producer::Producer(const std::string & name, const std::string & runcontrol) + : CommandReceiver("Producer", name, runcontrol), + DataSender("Producer", name) + { + } + + void Producer::OnData(const std::string & param) { + Connect(param); + } +} diff --git a/rce/rcecalib/eudaq/Producer.hh b/rce/rcecalib/eudaq/Producer.hh new file mode 100644 index 0000000000000000000000000000000000000000..0ef779f039361a3f27a40051be89de282929cb0b --- /dev/null +++ b/rce/rcecalib/eudaq/Producer.hh @@ -0,0 +1,30 @@ +#ifndef EUDAQ_INCLUDED_Producer +#define EUDAQ_INCLUDED_Producer + +#include "eudaq/CommandReceiver.hh" +#include "eudaq/DataSender.hh" +#include <string> + +namespace eudaq { + + /** + * The base class from which all Producers should inherit. + * It is both a CommandReceiver, listening to commands from RunControl, + * and a DataSender, sending data to a DataCollector. + */ + class Producer : public CommandReceiver, public DataSender { + public: + /** + * The constructor. + * \param runcontrol A string containing the address of the RunControl to connect to. + */ + Producer(const std::string & name, const std::string & runcontrol); + virtual ~Producer() {} + + virtual void OnData(const std::string & param); + private: + }; + +} + +#endif // EUDAQ_INCLUDED_Producer diff --git a/rce/rcecalib/eudaq/ProducerIF.cc b/rce/rcecalib/eudaq/ProducerIF.cc new file mode 100644 index 0000000000000000000000000000000000000000..69a130bd635c49363f189a71cbd5f11893411d23 --- /dev/null +++ b/rce/rcecalib/eudaq/ProducerIF.cc @@ -0,0 +1,15 @@ +#include "rcecalib/eudaq/ProducerIF.hh" + +#include "rcecalib/eudaq/Producer.hh" + +eudaq::Producer* ProducerIF::m_producer=0; + +void ProducerIF::setProducer(eudaq::Producer* producer){ + m_producer=producer; +} + +void ProducerIF::sendEvent(eudaq::Event* ev){ + if(m_producer!=0){ + m_producer->SendEvent(*ev); + } +} diff --git a/rce/rcecalib/eudaq/ProducerIF.hh b/rce/rcecalib/eudaq/ProducerIF.hh new file mode 100644 index 0000000000000000000000000000000000000000..0a12ca86e1727cbcfc5f8435424f495fd54b936b --- /dev/null +++ b/rce/rcecalib/eudaq/ProducerIF.hh @@ -0,0 +1,18 @@ +#ifndef PRODUCERIF_HH +#define PRODUCERIF_HH + +namespace eudaq{ + class Event; + class Producer; +} + +class ProducerIF{ +public: + static void sendEvent(eudaq::Event *ev); + static void setProducer(eudaq::Producer* producer); +private: + static eudaq::Producer *m_producer; + +}; + +#endif diff --git a/rce/rcecalib/eudaq/RawDataEvent.cc b/rce/rcecalib/eudaq/RawDataEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..d152f7b4d2873f8e45467191bcfc451be2868c4e --- /dev/null +++ b/rce/rcecalib/eudaq/RawDataEvent.cc @@ -0,0 +1,60 @@ +#include "eudaq/RawDataEvent.hh" + +#include <ostream> + +namespace eudaq { + + EUDAQ_DEFINE_EVENT(RawDataEvent, str2id("_RAW")); + + RawDataEvent::block_t::block_t(Deserializer & des) { + des.read(id); + des.read(data); + } + + void RawDataEvent::block_t::Serialize(Serializer & ser) const { + ser.write(id); + ser.write(data); + } + + void RawDataEvent::block_t::Append(const RawDataEvent::data_t & d) { + data.insert(data.end(), d.begin(), d.end()); + } + + RawDataEvent::RawDataEvent(std::string type, unsigned run, unsigned event) : + Event(run, event), + m_type(type) + { + } + + RawDataEvent::RawDataEvent(Deserializer & ds) : + Event(ds) + { + ds.read(m_type); + ds.read(m_blocks); + } + + unsigned RawDataEvent::GetID(size_t i) const { + return m_blocks.at(i).id; + } + + const RawDataEvent::data_t & RawDataEvent::GetBlock(size_t i) const { + return m_blocks.at(i).data; + } + + RawDataEvent::byte_t RawDataEvent::GetByte(size_t block, size_t index) const { + return GetBlock(block).at(index); + } + + void RawDataEvent::Print(std::ostream & os) const { + Event::Print(os); + std::string tluevstr = "unknown"; + os << ", " << m_blocks.size() << " blocks, tluev=" << tluevstr; + } + + void RawDataEvent::Serialize(Serializer & ser) const { + Event::Serialize(ser); + ser.write(m_type); + ser.write(m_blocks); + } + +} diff --git a/rce/rcecalib/eudaq/RawDataEvent.hh b/rce/rcecalib/eudaq/RawDataEvent.hh new file mode 100644 index 0000000000000000000000000000000000000000..d75fa050a4d4abf493025550f7ee584fe02f64ee --- /dev/null +++ b/rce/rcecalib/eudaq/RawDataEvent.hh @@ -0,0 +1,112 @@ +#ifndef EUDAQ_INCLUDED_RawDataEvent +#define EUDAQ_INCLUDED_RawDataEvent + +#include <sstream> + +#include <vector> +#include "eudaq/Event.hh" + +namespace eudaq { + + /** An Event type consisting of just a vector of bytes. + * + */ + class RawDataEvent : public Event { + EUDAQ_DECLARE_EVENT(RawDataEvent); + public: + typedef unsigned char byte_t; + typedef std::vector<byte_t> data_t; + struct block_t : public Serializable { + block_t(unsigned id = (unsigned)-1, data_t data = data_t()) : id(id), data(data) {} + block_t(Deserializer &); + void Serialize(Serializer &) const; + void Append(const data_t & data); + unsigned id; + data_t data; + }; + + RawDataEvent(std::string type, unsigned run, unsigned event); + RawDataEvent(Deserializer &); + + /// Add an empty block + size_t AddBlock(unsigned id) { + m_blocks.push_back(block_t(id)); + return m_blocks.size() - 1; + } + + /// Add a data block as std::vector + template <typename T> + size_t AddBlock(unsigned id, const std::vector<T> & data) { + m_blocks.push_back(block_t(id, make_vector(data))); + return m_blocks.size() - 1; + } + + /// Add a data block as array with given size + template <typename T> + size_t AddBlock(unsigned id, const T * data, size_t bytes) { + m_blocks.push_back(block_t(id, make_vector(data, bytes))); + return m_blocks.size() - 1; + } + + /// Append data to a block as std::vector + template <typename T> + void AppendBlock(size_t index, const std::vector<T> & data) { + m_blocks[index].Append(make_vector(data)); + } + + /// Append data to a block as array with given size + template <typename T> + void AppendBlock(size_t index, const T * data, size_t bytes) { + m_blocks[index].Append(make_vector(data, bytes)); + } + + unsigned GetID(size_t i) const; + /** Get the data block number i as vector of \c{unsigned char}, which is the byte sequence which + * which has been serialised. This is the recommended way to retrieve your + * data from the RawDataEvent since the other GetBlock functions might + * give different results depending on the endiannes of your mashine. + */ + const data_t & GetBlock(size_t i) const; + byte_t GetByte(size_t block, size_t index) const; + + /// Return the number of data blocks in the RawDataEvent + size_t NumBlocks() const { return m_blocks.size(); } + + virtual void Print(std::ostream &) const; + static RawDataEvent BORE(std::string type, unsigned run) { + return RawDataEvent(type, run, (unsigned)-1, Event::FLAG_BORE); + } + static RawDataEvent EORE(std::string type, unsigned run, unsigned event) { + return RawDataEvent(type, run, event, Event::FLAG_EORE); + } + virtual void Serialize(Serializer &) const; + + /// Return the type string. + virtual std::string GetSubType() const { return m_type; } + + private: + // private constructor to create BORE and EORE + // make sure that event number is 0 for BORE + RawDataEvent(std::string type, unsigned run, unsigned event, Event::Flags flag) + : Event(run, event, NOTIMESTAMP, flag) , m_type(type) + {} + + template <typename T> + static data_t make_vector(const T * data, size_t bytes) { + const unsigned char * ptr = reinterpret_cast<const byte_t *>(data); + return data_t(ptr, ptr + bytes); + } + + template <typename T> + static data_t make_vector(const std::vector<T> & data) { + const unsigned char * ptr = reinterpret_cast<const byte_t *>(&data[0]); + return data_t(ptr, ptr + data.size() * sizeof(T)); + } + + std::string m_type; + std::vector<block_t> m_blocks; + }; + +} + +#endif // EUDAQ_INCLUDED_RawDataEvent diff --git a/rce/rcecalib/eudaq/Serializable.hh b/rce/rcecalib/eudaq/Serializable.hh new file mode 100644 index 0000000000000000000000000000000000000000..bce5dc0c22b5b3890447cfca20f9b4719eff6fca --- /dev/null +++ b/rce/rcecalib/eudaq/Serializable.hh @@ -0,0 +1,22 @@ +#ifndef EUDAQ_INCLUDED_Serializable +#define EUDAQ_INCLUDED_Serializable + +//#include <string> +//#include <vector> +//#include <map> +//#include <iosfwd> + +namespace eudaq { + + class Serializer; + + class Serializable { + public: + virtual void Serialize(Serializer &) const = 0; + virtual ~Serializable() {} + + }; + +} + +#endif // EUDAQ_INCLUDED_Serializable diff --git a/rce/rcecalib/eudaq/Serializer.hh b/rce/rcecalib/eudaq/Serializer.hh new file mode 100644 index 0000000000000000000000000000000000000000..8ef72c6c51b2e21d23e5dc7e95328d439178b247 --- /dev/null +++ b/rce/rcecalib/eudaq/Serializer.hh @@ -0,0 +1,262 @@ +#ifndef EUDAQ_INCLUDED_Serializer +#define EUDAQ_INCLUDED_Serializer + +#include <string> +#include <vector> +#include <map> +#include "eudaq/Serializable.hh" +#include "eudaq/counted_ptr.hh" +#include "eudaq/Time.hh" +#include "eudaq/Exception.hh" + +namespace eudaq { + + class InterruptedException : public std::exception { + const char * what() const throw() { return "InterruptedException"; } + }; + + class Serializer { + public: + virtual void Flush() {} + void write(const Serializable & t) { + t.Serialize(*this); + } + template<typename T> + void write(const T & t); + template<typename T> + void write(const std::vector<T> & t); + template<typename T, typename U> + void write(const std::map<T, U> & t); + + virtual ~Serializer() {} + private: + template <typename T> + friend struct WriteHelper; + virtual void Serialize(const unsigned char *, size_t) = 0; + }; + + template <typename T> + struct WriteHelper { + typedef void (*writer)(Serializer & ser, const T & v); + static writer GetFunc(Serializable *) { return write_ser; } + static writer GetFunc(float *) { return write_float; } + static writer GetFunc(double *) { return write_double; } + static writer GetFunc(...) { return write_int; } + + static void write_ser(Serializer & sr, const T & v) { + v.Serialize(sr); + } + static void write_int(Serializer & sr, const T & v) { + T t = v; + unsigned char buf[sizeof t]; + for (size_t i = 0; i < sizeof t; ++i) { + buf[i] = t & 0xff; + t >>= 8; + } + sr.Serialize(buf, sizeof t); + } + static void write_float(Serializer & sr, const float & v) { + unsigned t = *(unsigned *)&v; + unsigned char buf[sizeof t]; + for (size_t i = 0; i < sizeof t; ++i) { + buf[i] = t & 0xff; + t >>= 8; + } + sr.Serialize(buf, sizeof t); + } + static void write_double(Serializer & sr, const double & v) { + unsigned long long t = *(unsigned long long *)&v; + unsigned char buf[sizeof t]; + for (size_t i = 0; i < sizeof t; ++i) { + buf[i] = t & 0xff; + t >>= 8; + } + sr.Serialize(buf, sizeof t); + } + }; + + template <typename T> + inline void Serializer::write(const T & v) { + WriteHelper<T>::GetFunc(static_cast<T*>(0))(*this, v); + } + + template <> + inline void Serializer::write(const std::string & t) { + write((unsigned)t.length()); + Serialize(reinterpret_cast<const unsigned char *>(&t[0]), t.length()); + } + + template <> + inline void Serializer::write(const Time & t) { + write((int)timeval(t).tv_sec); + write((int)timeval(t).tv_usec); + } + + template <typename T> + inline void Serializer::write(const std::vector<T> & t) { + unsigned len = t.size(); + write(len); + for (size_t i = 0; i < len; ++i) { + write(t[i]); + } + } + + template <> + inline void Serializer::write<unsigned char>(const std::vector<unsigned char> & t) { + write((unsigned)t.size()); + Serialize(&t[0], t.size()); + } + + template <> + inline void Serializer::write<char>(const std::vector<char> & t) { + write((unsigned)t.size()); + Serialize(reinterpret_cast<const unsigned char *>(&t[0]), t.size()); + } + + template <typename T, typename U> + inline void Serializer::write(const std::map<T, U> & t) { + unsigned len = (unsigned)t.size(); + write(len); + for (typename std::map<T, U>::const_iterator i = t.begin(); i != t.end(); ++i) { + write(i->first); + write(i->second); + } + } + + class Deserializer { + public: + Deserializer() : m_interrupting(false) {} + virtual bool HasData() = 0; + void Interrupt() { m_interrupting = true; } + + template <typename T> + void read(T & t); + + template <typename T> + void read(std::vector<T> & t); + + template <typename T, typename U> + void read(std::map<T, U> & t); + + template <typename T> + T read() { + T t; + read(t); + return t; + } + + virtual ~Deserializer() {} + protected: + bool m_interrupting; + private: + template <typename T> + friend struct ReadHelper; + virtual void Deserialize(unsigned char *, size_t) = 0; + }; + + template <typename T> + struct ReadHelper { + typedef T (*reader)(Deserializer & ser); + static reader GetFunc(Serializable *) { return read_ser; } + static reader GetFunc(float *) { return read_float; } + static reader GetFunc(double *) { return read_double; } + static reader GetFunc(...) { return read_int; } + + static T read_ser(Deserializer & ds) { + return T(ds); + } + static T read_int(Deserializer & ds) { + unsigned char buf[sizeof (T)]; + ds.Deserialize(buf, sizeof (T)); + T t = 0; + for (size_t i = 0; i < sizeof t; ++i) { + t <<= 8; + t += buf[sizeof t - 1 - i]; + } + return t; + } + static float read_float(Deserializer & ds) { + unsigned char buf[sizeof (float)]; + ds.Deserialize(buf, sizeof buf); + unsigned t = 0; + for (size_t i = 0; i < sizeof t; ++i) { + t <<= 8; + t += buf[sizeof t - 1 - i]; + } + return *(float *)&t; + } + static double read_double(Deserializer & ds) { + union { double d; unsigned long long i; unsigned char b[sizeof (double)]; } u; + //unsigned char buf[sizeof (double)]; + ds.Deserialize(u.b, sizeof u.b); + unsigned long long t = 0; + for (size_t i = 0; i < sizeof t; ++i) { + t <<= 8; + t += u.b[sizeof t - 1 - i]; + } + u.i = t; + return u.d; + } + }; + + template <typename T> + inline void Deserializer::read(T & t) { + t = ReadHelper<T>::GetFunc(static_cast<T*>(0))(*this); + } + + template <> + inline void Deserializer::read(std::string & t) { + unsigned len = 0; + read(len); + t = std::string(len, ' '); + if (len) Deserialize(reinterpret_cast<unsigned char *>(&t[0]), len); + } + + template <> + inline void Deserializer::read(Time & t) { + int sec, usec; + read(sec); + read(usec); + t = Time(sec, usec); + } + + template <typename T> + inline void Deserializer::read(std::vector<T> & t) { + unsigned len = 0; + read(len); + t.reserve(len); + for (size_t i = 0; i < len; ++i) { + t.push_back(read<T>()); + } + } + + template <> + inline void Deserializer::read<unsigned char>(std::vector<unsigned char> & t) { + unsigned len = 0; + read(len); + t.resize(len); + Deserialize(&t[0], len); + } + + template <> + inline void Deserializer::read<char>(std::vector<char> & t) { + unsigned len = 0; + read(len); + t.resize(len); + Deserialize(reinterpret_cast<unsigned char *>(&t[0]), len); + } + + template<typename T, typename U> + inline void Deserializer::read(std::map<T, U> & t) { + unsigned len = 0; + read(len); + for (size_t i = 0; i < len; ++i) { + std::string name = read<std::string>(); + std::string val = read<std::string>(); + t[name]=val; + } + } + +} + +#endif // EUDAQ_INCLUDED_Serializer diff --git a/rce/rcecalib/eudaq/Status.cc b/rce/rcecalib/eudaq/Status.cc new file mode 100644 index 0000000000000000000000000000000000000000..d58c646668bd9bfdd3175fbf06dce4d77b76c103 --- /dev/null +++ b/rce/rcecalib/eudaq/Status.cc @@ -0,0 +1,63 @@ +#include "eudaq/Status.hh" +#include "eudaq/Exception.hh" +#include "eudaq/Utils.hh" + +namespace eudaq { + + Status::Status(Deserializer & ds) { + ds.read(m_level); + ds.read(m_msg); + ds.read(m_tags); + } + + void Status::Serialize(Serializer & ser) const { + ser.write(m_level); + ser.write(m_msg); + ser.write(m_tags); + } + + std::string Status::Level2String(int level) { + static const char * const strings[] = { + "DEBUG", + "OK", + "THROW", + "EXTRA", + "INFO", + "WARN", + "ERROR", + "USER", + "NONE" + }; + if (level < LVL_DEBUG || level > LVL_NONE) return ""; + return strings[level]; + } + + int Status::String2Level(const std::string & str) { + int lvl = 0; + std::string tmpstr1, tmpstr2 = ucase(str); + while ((tmpstr1 = Level2String(lvl)) != "") { + if (tmpstr1 == tmpstr2) return lvl; + lvl++; + } + EUDAQ_THROW("Unrecognised level: " + str); + } + + Status & Status::SetTag(const std::string & name, const std::string & val) { + m_tags[name] = val; + return *this; + } + + std::string Status::GetTag(const std::string & name, const std::string & def) const { + std::map<std::string, std::string>::const_iterator i = m_tags.find(name); + if (i == m_tags.end()) return def; + return i->second; + } + + void Status::print(std::ostream & os) const { + os << Level2String(m_level); + if (m_msg != "") { + os << ": " << m_msg; + } + } + +} diff --git a/rce/rcecalib/eudaq/Status.hh b/rce/rcecalib/eudaq/Status.hh new file mode 100644 index 0000000000000000000000000000000000000000..5dc0bb79ff1137d386c7a41c0078e6b39924a3b0 --- /dev/null +++ b/rce/rcecalib/eudaq/Status.hh @@ -0,0 +1,51 @@ +#ifndef EUDAQ_INCLUDED_Status +#define EUDAQ_INCLUDED_Status + +#include "eudaq/Serializable.hh" +#include "eudaq/Serializer.hh" +#include <string> +#include <ostream> + +namespace eudaq { + + class Status : public Serializable { + public: + enum Level { + LVL_DEBUG, + LVL_OK, + LVL_THROW, + LVL_EXTRA, + LVL_INFO, + LVL_WARN, + LVL_ERROR, + LVL_USER, + LVL_NONE + }; + Status(int level = LVL_OK, const std::string & msg = "") + : m_level(level), m_msg(msg) {} + Status(Deserializer &); + virtual void Serialize(Serializer &) const; + + Status & SetTag(const std::string & name, const std::string & val); + std::string GetTag(const std::string & name, const std::string & def = "") const; + static std::string Level2String(int level); + static int String2Level(const std::string &); + virtual ~Status() {} + virtual void print(std::ostream &) const; + int GetLevel() const { return m_level; } + protected: + typedef std::map<std::string, std::string> map_t; + int m_level; + std::string m_msg; + map_t m_tags; ///< Metadata tags in (name=value) pairs of strings + }; + + inline std::ostream & operator << (std::ostream & os, const Status & s) { + s.print(os); + return os; + } + + +} + +#endif // EUDAQ_INCLUDED_Status diff --git a/rce/rcecalib/eudaq/TLUEvent.cc b/rce/rcecalib/eudaq/TLUEvent.cc new file mode 100644 index 0000000000000000000000000000000000000000..7147975c00ae3d5b66aac46f21e0909ca83e5b7b --- /dev/null +++ b/rce/rcecalib/eudaq/TLUEvent.cc @@ -0,0 +1,26 @@ +#include "eudaq/TLUEvent.hh" + +#include <ostream> + +namespace eudaq { + + EUDAQ_DEFINE_EVENT(TLUEvent, str2id("_TLU")); + + TLUEvent::TLUEvent(Deserializer & ds) : + Event(ds) + { + ds.read(m_extratimes); + } + + void TLUEvent::Print(std::ostream & os) const { + Event::Print(os); + if (m_extratimes.size() > 0) { + os << " [" << m_extratimes.size() << " extra]"; + } + } + + void TLUEvent::Serialize(Serializer & ser) const { + Event::Serialize(ser); + ser.write(m_extratimes); + } +} diff --git a/rce/rcecalib/eudaq/TLUEvent.hh b/rce/rcecalib/eudaq/TLUEvent.hh new file mode 100644 index 0000000000000000000000000000000000000000..a4aaf987a8cf44cf8d8539195c2fe2b2b11e6a89 --- /dev/null +++ b/rce/rcecalib/eudaq/TLUEvent.hh @@ -0,0 +1,39 @@ +#ifndef EUDAQ_INCLUDED_TLUEvent +#define EUDAQ_INCLUDED_TLUEvent + +#include <vector> +#include "eudaq/Event.hh" + +namespace eudaq { + + class TLUEvent : public Event { + EUDAQ_DECLARE_EVENT(TLUEvent); + public: + typedef std::vector<unsigned long long> vector_t; + virtual void Serialize(Serializer &) const; + explicit TLUEvent(unsigned run, unsigned event, unsigned long long timestamp, + const vector_t & extratimes = vector_t()) : + Event(run, event, timestamp), + m_extratimes(extratimes) {} + explicit TLUEvent(Deserializer &); + virtual void Print(std::ostream &) const; + + /// Return "TLUEvent" as type. + virtual std::string GetType() const {return "TLUEvent";} + + static TLUEvent BORE(unsigned run) { + return TLUEvent(run); + } + static TLUEvent EORE(unsigned run, unsigned event) { + return TLUEvent(run, event); + } + private: + TLUEvent(unsigned run, unsigned event = 0) + : Event(run, event, NOTIMESTAMP, event ? Event::FLAG_EORE : Event::FLAG_BORE) + {} + vector_t m_extratimes; + }; + +} + +#endif // EUDAQ_INCLUDED_TLUEvent diff --git a/rce/rcecalib/eudaq/Time.cc b/rce/rcecalib/eudaq/Time.cc new file mode 100644 index 0000000000000000000000000000000000000000..00331841dd00c8ae28b881a71ffe8893e130b19b --- /dev/null +++ b/rce/rcecalib/eudaq/Time.cc @@ -0,0 +1,60 @@ +#include "eudaq/Time.hh" +#include "eudaq/Exception.hh" +#include <ctime> +#include <iostream> + + +namespace eudaq { + + const std::string Time::DEFAULT_FORMAT = "%Y-%m-%d %H:%M:%S.%3"; + + Time Time::Current() { + timeval tv; + if (gettimeofday(&tv, 0)) { + std::cout<<"Error getting current time: "<< strerror(errno)<<std::endl; + } + return tv; + } + + + Time::Time(int year, int month, int date, int hour, int minute, int sec, int usec) { + struct tm time; + //time.tm_gmtoff = 0; + time.tm_isdst = -1; + time.tm_year = year - 1900; + time.tm_mon = month - 1; + time.tm_mday = date; + time.tm_hour = hour; + time.tm_min = minute; + time.tm_sec = sec + usec / 1000000; + tv_sec = mktime(&time); + tv_usec = usec % 1000000; + } + + std::string Time::Formatted(const std::string & format) const { + char buf[256]; + std::string fmt = format; + size_t i, pos = 0; + while ((i = fmt.find('%', pos)) != std::string::npos) { + //std::cout << "i=" << i << std::endl; + if (i >= fmt.length() - 1) break; + pos = i+2; + //std::cout << "pos=" << pos << std::endl; + int c = fmt[i+1] - '0'; + if (c >= 1 && c <= 6) { + //std::cout << "c=" << c << std::endl; + std::string usecs = to_string(tv_usec, 6); + //std::cout << "fmt=" << fmt << std::endl; + fmt = std::string(fmt, 0, i) + std::string(usecs, 0, c) + std::string(fmt, i+2); + //std::cout << "fmt=" << fmt << std::endl; + pos += c - 2; + //std::cout << "pos=" << pos << std::endl; + } + } + time_t t = tv_sec; + struct tm * tm = std::localtime(&t); + std::strftime(buf, sizeof buf, fmt.c_str(), tm); + return std::string(buf); + } + +} diff --git a/rce/rcecalib/eudaq/Time.hh b/rce/rcecalib/eudaq/Time.hh new file mode 100644 index 0000000000000000000000000000000000000000..2d854da4aa781784bc56447de1fb410502aa4ded --- /dev/null +++ b/rce/rcecalib/eudaq/Time.hh @@ -0,0 +1,89 @@ +#ifndef EUDAQ_INCLUDED_Time +#define EUDAQ_INCLUDED_Time + +#include <errno.h> +#include <ostream> +#include <iomanip> +#include <string> +#include <cstring> + +# include <sys/time.h> + +namespace eudaq { + + class Time { + public: + static const std::string DEFAULT_FORMAT; + explicit Time(long sec, long usec = 0) { + tv_usec = usec % 1000000; + tv_sec = sec + usec / 1000000; + } + Time(int year, int month, int date, int hour = 0, int minute = 0, int sec = 0, int usec = 0); + Time(timeval tv) { + tv_usec = tv.tv_usec % 1000000; + tv_sec = tv.tv_sec + tv.tv_usec / 1000000; + } + double Seconds() const { return tv_sec + tv_usec / 1e6; } + Time & operator += (const timeval & other) { + tv_usec += other.tv_usec; + tv_sec += other.tv_sec + tv_usec / 1000000; + tv_usec %= 1000000; + return *this; + } + Time & operator -= (const timeval & other) { + if (tv_usec < other.tv_usec) { + tv_usec += 1000000 - other.tv_usec; + tv_sec -= other.tv_sec + 1; + } else { + tv_usec -= other.tv_usec; + tv_sec -= other.tv_sec; + } + return *this; + } + bool operator < (const timeval & other) { + return tv_sec < other.tv_sec || + (tv_sec == other.tv_sec && tv_usec < other.tv_usec); + } + bool operator > (const timeval & other) { + return tv_sec > other.tv_sec || + (tv_sec == other.tv_sec && tv_usec > other.tv_usec); + } + operator const timeval () const { + timeval tv; + tv.tv_sec = tv_sec; + tv.tv_usec = tv_usec; + return tv; + } + std::string Formatted(const std::string & format = DEFAULT_FORMAT) const; + static Time Current(); + private: + long tv_sec; + long tv_usec; + }; + + inline Time operator + (const timeval & lhs, const timeval rhs) { + Time t(lhs); + t += rhs; + return t; + } + + inline Time operator - (const timeval & lhs, const timeval rhs) { + Time t(lhs); + t -= rhs; + return t; + } + + inline bool operator == (const timeval & lhs, const timeval rhs) { + return (lhs.tv_sec == rhs.tv_sec) && (lhs.tv_usec == rhs.tv_usec); + } + + inline std::ostream & operator << (std::ostream & os, const timeval & tv) { + if (tv.tv_sec < 0) { + return os << '-' << Time(-tv.tv_sec - 1, 1000000 - tv.tv_usec); + } + return os << tv.tv_sec << '.' << std::setw(6) << std::setfill('0') << tv.tv_usec << std::setfill(' '); + } + +} + +#endif // EUDAQ_INCLUDED_Time diff --git a/rce/rcecalib/eudaq/TransportBase.cc b/rce/rcecalib/eudaq/TransportBase.cc new file mode 100644 index 0000000000000000000000000000000000000000..bfcc2a59915c6f1fd7030fff4e6e93179b457352 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportBase.cc @@ -0,0 +1,103 @@ +#include "eudaq/TransportBase.hh" +#include <ostream> +#include <iostream> + +namespace eudaq { + + const ConnectionInfo ConnectionInfo::ALL("ALL"); + static const int DEFAULT_TIMEOUT = 1000; + + void ConnectionInfo::Print(std::ostream & os) const { + if (m_state == -1) { + os << "(disconnected)"; + } else if (m_state == 0) { + os << "(waiting)"; + } else { + os << m_type; + if (m_name != "") os << "." << m_name; + } + } + + bool ConnectionInfo::Matches(const ConnectionInfo & /*other*/) const { + //std::cout << " [Match: all] " << std::flush; + return true; + } + + TransportBase::TransportBase() + : m_callback(0) + {} + + void TransportBase::SetCallback(const TransportCallback & callback) { + m_callback = callback; + } + + void TransportBase::Process(int timeout) { + if (timeout == -1) timeout = DEFAULT_TIMEOUT; + MutexLock m(m_mutex); + ProcessEvents(timeout); + m.Release(); + for (;;) { + MutexLock m(m_mutex); + if (m_events.empty()) break; + //std::cout << "Got packet" << std::endl; + TransportEvent evt(m_events.front()); + m_events.pop(); + m.Release(); + m_callback(evt); + } + } + + bool TransportBase::ReceivePacket(std::string * packet, int timeout, const ConnectionInfo & conn) { + if (timeout == -1) timeout = DEFAULT_TIMEOUT; + //std::cout << "ReceivePacket()" << std::flush; + while (!m_events.empty() && m_events.front().etype != TransportEvent::RECEIVE) { + m_events.pop(); + } + //std::cout << " current level=" << m_events.size() << std::endl; + if (m_events.empty()) { + //std::cout << "Getting more" << std::endl; + ProcessEvents(timeout); + //std::cout << "Temp level=" << m_events.size() << std::endl; + while (!m_events.empty() && m_events.front().etype != TransportEvent::RECEIVE) { + m_events.pop(); + } + //std::cout << "New level=" << m_events.size() << std::endl; + } + bool ret = false; + if (!m_events.empty() && conn.Matches(m_events.front().id)) { + ret = true; + *packet = m_events.front().packet; + m_events.pop(); + } + //std::cout << "ReceivePacket() return " << (ret ? "true" : "false") << std::endl; + return ret; + } + + bool TransportBase::SendReceivePacket(const std::string & sendpacket, + std::string * recpacket, + const ConnectionInfo & connection, + int timeout) + { + // acquire mutex... + if (timeout == -1) timeout = DEFAULT_TIMEOUT; + //std::cout << "DEBUG: SendReceive: Acquiring mutex" << std::endl; + std::cout<<"Before lock 3"<<std::endl; + MutexLock m(m_mutex, false); + std::cout<<"After lock 3"<<std::endl; + try { + m.Lock(); + } catch (const eudaq::Exception &) { + // swallow it + } + //std::cout << "DEBUG: SendReceive: got mutex" << std::endl; + SendPacket(sendpacket, connection); + //std::cout << "DEBUG: SendReceive sent packet " << sendpacket << std::endl; + bool ret = ReceivePacket(recpacket, timeout, connection); + //std::cout << "SendReceivePacket() return '" << *recpacket << "' " << (ret ? "true" : "false") << std::endl; + return ret; + } + + TransportBase::~TransportBase() { + } + +} diff --git a/rce/rcecalib/eudaq/TransportBase.hh b/rce/rcecalib/eudaq/TransportBase.hh new file mode 100644 index 0000000000000000000000000000000000000000..f31ec1fd1e34f55797f8d76547960b838393661e --- /dev/null +++ b/rce/rcecalib/eudaq/TransportBase.hh @@ -0,0 +1,206 @@ +#ifndef EUDAQ_INCLUDED_TransportBase +#define EUDAQ_INCLUDED_TransportBase + +/** \file TransportBase.hh + * Defines TransportBase along with a number of related classes. + */ + +#include "eudaq/Mutex.hh" +#include "eudaq/Exception.hh" +#include "eudaq/BufferSerializer.hh" +#include <string> +#include <queue> +#include <iosfwd> +#include <cstring> +#include <iostream> + +namespace eudaq { + + /** Represents an individual connection on a Transport. + * + */ + class ConnectionInfo { + public: + explicit ConnectionInfo(const std::string & name = "") : m_state(0), m_name(name) {} + virtual ~ConnectionInfo() {} + virtual void Print(std::ostream &) const; + virtual bool Matches(const ConnectionInfo & other) const; + bool IsEnabled() const { return m_state >= 0; } + int GetState() const { return m_state; } + void SetState(int state) { m_state = state; } + std::string GetType() const { return m_type; } + void SetType(const std::string & type) { m_type = type; } + std::string GetName() const { return m_name; } + void SetName(const std::string & name) { m_name = name; } + virtual std::string GetRemote() const { return ""; } + static const ConnectionInfo ALL; + + virtual ConnectionInfo * Clone() const { return new ConnectionInfo(*this); } + protected: + int m_state; + std::string m_type, m_name; + /* + public: + virtual bool operator = (const ClientID & other) = 0; + virtual std::string Name() const = 0; + */ + }; + + inline std::ostream & operator << (std::ostream & os, const ConnectionInfo & id) { + id.Print(os); + return os; + } + + /** Represents an event such as a connection, or receipt of data on a Transport. + */ + struct TransportEvent { + enum EventType { CONNECT, DISCONNECT, RECEIVE }; + TransportEvent(EventType et, ConnectionInfo & i, const std::string & p = "") + : etype(et), id(i), packet(p) {} + EventType etype; ///< The type of event + ConnectionInfo & id; ///< The id of the connection + std::string packet; ///< The packet of data in case of a RECEIVE event + }; + + /** Represents a callback function for the Transport system. + * It can hold a pointer to a callback function which can be + * either a free function or an object and a member function. + * It is like a simplified and less flexible version of boost::function. + * I didn't use boost::function because I didn't want to rely + * on too many external dependencies. + */ + class TransportCallback { + /** A helper class for TransportCallback. + * It specifies an interface from which the actual helpers inherit. + */ + class Helper { + public: + virtual void call(TransportEvent &) = 0; + virtual ~Helper() { } + virtual Helper * Clone() const = 0; + }; + /** A helper class for TransportCallback for normal function pointers. + * It performs the actual function call for a normal function pointer. + */ + class HelperFunction : public Helper { + public: + typedef void (*FuncType)(TransportEvent &); + HelperFunction(FuncType func) : m_func(func) { } + virtual void call(TransportEvent & ev) { m_func(ev); } + virtual Helper * Clone() const { return new HelperFunction(*this); } + private: + FuncType m_func; ///< A pointer to the function to call + }; + /** A helper class for TransportCallback for member function pointers. + * It performs the actual function call for a member function pointer. + * It also stores a pointer to the object on which to call the member function. + */ + template <typename T> + class HelperMember : public Helper { + public: + typedef T ObjType; + typedef void (ObjType::*FuncType)(TransportEvent &); + HelperMember(ObjType * obj, FuncType func) : m_obj(obj), m_func(func) {} + virtual void call(TransportEvent & ev) { + (m_obj->*m_func)(ev); + } + virtual Helper * Clone() const { return new HelperMember(*this); } + private: + ObjType *m_obj; ///< A pointer to the object + FuncType m_func; ///< A pointer to the member function + }; + public: + TransportCallback() : m_helper(0) {} + TransportCallback(HelperFunction::FuncType funcptr) + : m_helper(new HelperFunction(funcptr)) {} + template <typename T> + TransportCallback(T * obj, typename HelperMember<T>::FuncType func) + : m_helper(new HelperMember<T>(obj, func)) {} + void operator () (TransportEvent & ev) { + if(m_helper) m_helper->call(ev); + } + TransportCallback(const TransportCallback & other) + : m_helper(other.m_helper->Clone()) {} + TransportCallback & operator=(const TransportCallback & other) { + delete m_helper; + m_helper = other.m_helper->Clone(); + return *this; + } + ~TransportCallback() { delete m_helper; } + private: + Helper * m_helper; ///< The helper class to perform the actual function call + }; + + /** A base class from which all types of Transport should inherit. + * They must implement the two pure virtual member functions SendPacket and ProcessEvents. + * A Transport is a means of transferring data or commands from one + * process to another, possibly on another machine. + */ + class TransportBase { + public: + TransportBase(); + virtual ~TransportBase(); + + /** Pure virtual function to send a packet of data. + * This function must be implemented by the concrete Transport class to send a + * packet of data to the remote Transport instance. + */ + virtual void SendPacket(const unsigned char * data, size_t len, + const ConnectionInfo & = ConnectionInfo::ALL, + bool duringconnect = false) = 0; + void SendPacket(const std::string & data, const ConnectionInfo & inf = ConnectionInfo::ALL, bool duringconnect = false) { + //std::cout << "SendPacket (string)" << std::endl; + SendPacket(reinterpret_cast<const unsigned char *>(&data[0]), data.length(), inf, duringconnect); + } + void SendPacket(const char * str, const ConnectionInfo & inf = ConnectionInfo::ALL, bool duringconnect = false) { + //std::cout << "SendPacket (char*)" << std::endl; + SendPacket(reinterpret_cast<const unsigned char *>(str), std::strlen(str), inf, duringconnect); + } + void SendPacket(const BufferSerializer & t, const ConnectionInfo & inf = ConnectionInfo::ALL, bool duringconnect = false) { + SendPacket(&t[0], t.size(), inf, duringconnect); + } + + /** Pure virtual function to close a connection. + * This function should be implemented by the concrete Transport class to close + * the connection to the specified remote Transport instance. + */ + virtual void Close(const ConnectionInfo &) {} + + /** Pure virtual function to receive data. + * This function must be implemented by the concrete Transport class to receive + * all pending data from the remote Transport instance, and fill the queue of + * events so that they may be handled. + */ + virtual void ProcessEvents(int timeout) = 0; + + void Process(int timeout = -1); + bool ReceivePacket(std::string * packet, int timeout = -1, const ConnectionInfo & = ConnectionInfo::ALL); + bool SendReceivePacket(const std::string & sendpacket, + std::string * recpacket, + const ConnectionInfo & connection, + int timeout = -1); + template <typename T> + T SendReceivePacket(const std::string & packet, const ConnectionInfo & connection, int timeout = -1); + void SetCallback(const TransportCallback &); + virtual bool IsNull() const { return false; } + protected: + std::queue<TransportEvent> m_events; ///< A buffer to queue up events until they are handled + TransportCallback m_callback; ///< The callback function to invoke on a transport event + Mutex m_mutex; + }; + + template <typename T> + inline T TransportBase::SendReceivePacket(const std::string & packet, const ConnectionInfo & connection, int timeout) { + std::string buf; + bool ok = SendReceivePacket(packet, &buf, connection, timeout); + if (!ok) EUDAQ_THROW("Timeout: No response in SendReceivePacket"); + BufferSerializer ser(buf.begin(), buf.end()); + T result; + ser.read(result); + return result; + } + + +} + +#endif // EUDAQ_INCLUDED_TransportBase diff --git a/rce/rcecalib/eudaq/TransportClient.cc b/rce/rcecalib/eudaq/TransportClient.cc new file mode 100644 index 0000000000000000000000000000000000000000..ce859fb28e0d4450a173657e4f97426319937ab7 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportClient.cc @@ -0,0 +1,8 @@ +#include "eudaq/TransportFactory.hh" + +namespace eudaq { + + TransportClient::~TransportClient() { + } + +} diff --git a/rce/rcecalib/eudaq/TransportClient.hh b/rce/rcecalib/eudaq/TransportClient.hh new file mode 100644 index 0000000000000000000000000000000000000000..525d15bc28ce063a0c0187c171bc0785a65866a5 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportClient.hh @@ -0,0 +1,19 @@ +#ifndef EUDAQ_INCLUDED_TransportClient +#define EUDAQ_INCLUDED_TransportClient + +#include "eudaq/TransportBase.hh" +#include <string> + +namespace eudaq { + + class TransportClient : public TransportBase { + public: + //virtual void SendPacket(const std::string & packet) = 0; + //virtual bool ReceivePacket(std::string * packet, int timeout = -1) = 0; + + virtual ~TransportClient(); + }; + +} + +#endif // EUDAQ_INCLUDED_TransportClient diff --git a/rce/rcecalib/eudaq/TransportFactory.cc b/rce/rcecalib/eudaq/TransportFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..a0f0f1ca15416777e2f579aba775597059fc8b44 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportFactory.cc @@ -0,0 +1,86 @@ +#include "eudaq/TransportFactory.hh" +#include "eudaq/Exception.hh" +#include <iostream> +#include <ostream> +#include <string> +#include <map> + +// All transport header files must be included here +#include "eudaq/TransportNULL.hh" +#include "eudaq/TransportTCP.hh" + +namespace eudaq { + + /** Stores the name and factory methods for a type of Transport. + */ + struct TransportFactory::TransportInfo { + typedef TransportServer * (*ServerFactory)(const std::string &); + typedef TransportClient * (*ClientFactory)(const std::string &); + TransportInfo() : name(""), serverfactory(0), clientfactory(0) {} + TransportInfo(const std::string & nm, ServerFactory sf, ClientFactory cf): + name(nm), serverfactory(sf), clientfactory(cf) {} + std::string name; + ServerFactory serverfactory; + ClientFactory clientfactory; + }; + + namespace { + + template <typename T_Server, typename T_Client> + struct MakeTransportInfo : public TransportFactory::TransportInfo { + MakeTransportInfo(const std::string & thename) : + TransportInfo(thename, theserverfactory, theclientfactory) { + } + static TransportServer * theserverfactory(const std::string & param) { + return new T_Server(param); + } + static TransportClient * theclientfactory(const std::string & param) { + return new T_Client(param); + } + }; + + typedef std::map<std::string, TransportFactory::TransportInfo> map_t; + + static map_t & TransportMap() { + static bool initialised = false; + if (!initialised) { + initialised = true; + // All transports have to be registered here + TransportFactory::Register(MakeTransportInfo<NULLServer, NULLClient>(NULLServer::name)); + TransportFactory::Register(MakeTransportInfo<TCPServer, TCPClient>(TCPServer::name)); + } + static map_t m; + return m; + } + } + + void TransportFactory::Register(const TransportInfo & info) { + //std::cout << "DEBUG: TransportFactory::Register " << info.name << std::endl; + TransportMap()[info.name] = info; + } + + TransportServer * TransportFactory::CreateServer(const std::string & name) { + std::string proto = "tcp", param = name; + size_t i = name.find("://"); + if (i != std::string::npos) { + proto = std::string(name, 0, i); + param = std::string(name, i+3); + } + map_t::const_iterator it = TransportMap().find(proto); + if (it == TransportMap().end()) EUDAQ_THROW("Unknown protocol: " + proto); + return (it->second.serverfactory)(param); + } + + TransportClient * TransportFactory::CreateClient(const std::string & name) { + std::string proto = "tcp", param = name; + size_t i = name.find("://"); + if (i != std::string::npos) { + proto = std::string(name, 0, i); + param = std::string(name, i+3); + } + map_t::const_iterator it = TransportMap().find(proto); + if (it == TransportMap().end()) EUDAQ_THROW("Unknown protocol: " + proto); + return (it->second.clientfactory)(param); + } + +} diff --git a/rce/rcecalib/eudaq/TransportFactory.hh b/rce/rcecalib/eudaq/TransportFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..9b6059a4d87a08b7e0d9cd01bd5bded3d6bca57f --- /dev/null +++ b/rce/rcecalib/eudaq/TransportFactory.hh @@ -0,0 +1,22 @@ +#ifndef EUDAQ_INCLUDED_TransportFactory +#define EUDAQ_INCLUDED_TransportFactory + +#include "eudaq/TransportClient.hh" +#include "eudaq/TransportServer.hh" + +namespace eudaq { + + /** Creates Transport instances from a name without needing to know the concrete type at compile time. + */ + class TransportFactory { + public: + static TransportServer * CreateServer(const std::string & name); + static TransportClient * CreateClient(const std::string & name); + + struct TransportInfo; + static void Register(const TransportInfo & info); + }; + +} + +#endif // EUDAQ_INCLUDED_TransportFactory diff --git a/rce/rcecalib/eudaq/TransportNULL.cc b/rce/rcecalib/eudaq/TransportNULL.cc new file mode 100644 index 0000000000000000000000000000000000000000..097acc7149d925eea1dd498893ae488e2530d4ae --- /dev/null +++ b/rce/rcecalib/eudaq/TransportNULL.cc @@ -0,0 +1,45 @@ +#include "eudaq/TransportNULL.hh" +#include "eudaq/Utils.hh" + +#include <iostream> + +namespace eudaq { + + const std::string NULLServer::name = "null"; + + NULLServer::NULLServer(const std::string &) { + } + + NULLServer::~NULLServer() { + } + + void NULLServer::Close(const ConnectionInfo &) { + } + + void NULLServer::SendPacket(const unsigned char *, size_t, const ConnectionInfo &, bool) { + } + + void NULLServer::ProcessEvents(int timeout) { + mSleep(timeout); + } + + std::string NULLServer::ConnectionString() const { + return "null://"; + } + + NULLClient::NULLClient(const std::string & /*param*/) { + } + + void NULLClient::SendPacket(const unsigned char *, size_t, const ConnectionInfo &, bool) { + } + + void NULLClient::ProcessEvents(int timeout) { + //std::cout << "NULLClient::ProcessEvents " << timeout << std::endl; + mSleep(timeout); + //std::cout << "ok" << std::endl; + } + + NULLClient::~NULLClient() { + } + +} diff --git a/rce/rcecalib/eudaq/TransportNULL.hh b/rce/rcecalib/eudaq/TransportNULL.hh new file mode 100644 index 0000000000000000000000000000000000000000..ceb6978f832e8af6f3498095715abb45f1eaf8d6 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportNULL.hh @@ -0,0 +1,45 @@ +#ifndef EUDAQ_INCLUDED_TransportNULL +#define EUDAQ_INCLUDED_TransportNULL + +#include "eudaq/TransportFactory.hh" + +#include <vector> +#include <string> +#include <map> + +namespace eudaq { + + class NULLServer : public TransportServer { + public: + NULLServer(const std::string & param); + virtual ~NULLServer(); + + virtual void Close(const ConnectionInfo & id); + virtual void SendPacket(const unsigned char * data, size_t len, + const ConnectionInfo & id = ConnectionInfo::ALL, + bool duringconnect = false); + virtual void ProcessEvents(int timeout); + + virtual std::string ConnectionString() const; + virtual bool IsNull() const { return true; } + static const std::string name; + private: + }; + + class NULLClient: public TransportClient { + public: + NULLClient(const std::string & param); + virtual ~NULLClient(); + + virtual void SendPacket(const unsigned char * data, size_t len, + const ConnectionInfo & id = ConnectionInfo::ALL, + bool = false); + virtual void ProcessEvents(int timeout = -1); + virtual bool IsNull() const { return true; } + private: + ConnectionInfo m_buf; + }; + +} + +#endif // EUDAQ_INCLUDED_TransportNULL diff --git a/rce/rcecalib/eudaq/TransportServer.cc b/rce/rcecalib/eudaq/TransportServer.cc new file mode 100644 index 0000000000000000000000000000000000000000..334fe77f5a608e6b5e251a787965fab2d98b41a7 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportServer.cc @@ -0,0 +1,12 @@ +#include "eudaq/TransportFactory.hh" +#include "eudaq/Utils.hh" + +#include <iostream> +#include <ostream> + +namespace eudaq { + + TransportServer::~TransportServer() { + } + +} diff --git a/rce/rcecalib/eudaq/TransportServer.hh b/rce/rcecalib/eudaq/TransportServer.hh new file mode 100644 index 0000000000000000000000000000000000000000..175761385b76b087317e0a275b65b86def86555d --- /dev/null +++ b/rce/rcecalib/eudaq/TransportServer.hh @@ -0,0 +1,22 @@ +#ifndef EUDAQ_INCLUDED_TransportServer +#define EUDAQ_INCLUDED_TransportServer + +#include "eudaq/TransportBase.hh" +#include "eudaq/counted_ptr.hh" +#include <string> + +namespace eudaq { + + class TransportServer : public TransportBase { + public: + virtual ~TransportServer(); + virtual std::string ConnectionString() const = 0; + size_t NumConnections() const { return m_conn.size(); } + const ConnectionInfo & GetConnection(size_t i) const { return *m_conn[i]; } + protected: + std::vector<counted_ptr<ConnectionInfo> > m_conn; + }; + +} + +#endif // EUDAQ_INCLUDED_TransportServer diff --git a/rce/rcecalib/eudaq/TransportTCP.cc b/rce/rcecalib/eudaq/TransportTCP.cc new file mode 100644 index 0000000000000000000000000000000000000000..f5e4986de31a4a60dbe668e074be80d3e0982502 --- /dev/null +++ b/rce/rcecalib/eudaq/TransportTCP.cc @@ -0,0 +1,473 @@ +#include "eudaq/TransportTCP.hh" +#include "eudaq/Exception.hh" +#include "eudaq/Time.hh" +#include "eudaq/Utils.hh" + +#include <boost/regex.hpp> +# include "eudaq/TransportTCP_POSIX.inc" + +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +//#include <unistd.h> +#ifdef __rtems__ + #define MSG_NOSIGNAL 0 + #include <netinet/in.h> + #include <sys/systm.h> +#endif + +#include <iostream> +#include <ostream> +#include <iostream> +#include "boost/assign.hpp" + +namespace eudaq { + + const std::string TCPServer::name = "tcp"; + + std::map<std::string, std::string> TCPClient::m_hosts=boost::assign::map_list_of + ("rdcds105", "172.21.6.45") + ("eudetmac001", "129.194.52.98") + ("rddev108", "172.21.7.146") + ("mac-atlas-tb-01", "137.138.113.225") + ("pc-atlas-tb-02", "137.138.115.189") + ("eudet","129.194.52.98"); + + namespace { + + static const int MAXPENDING = 16; + static const int MAX_BUFFER_SIZE = 10000; + + static int to_int(char c) { + return static_cast<unsigned char>(c); + } + +#ifdef MSG_NOSIGNAL + // On Linux (and cygwin?) send(...) can be told to + // ignore signals by setting the flag below + static const int FLAGS = MSG_NOSIGNAL; + static void setup_signal() { + } +#else +# include <signal.h> + // On Mac OS X (BSD?) this flag is not available, + // so we have to set the signal handler to ignore + static const int FLAGS = 0; + static void setup_signal() { + // static so that it is only done once + static sig_t sig = signal(SIGPIPE, SIG_IGN); + (void)sig; + } +#endif + + static void do_send_data(SOCKET sock, const unsigned char * data, size_t len) { + //if (len > 500000) std::cout << "Starting send" << std::endl; + size_t sent = 0; + do { + int result = send(sock, + reinterpret_cast<const char*>(data+sent), + static_cast<int>(len-sent), + FLAGS); + if (result > 0) { + sent += result; + } else if (result < 0 && (LastSockError() == EAGAIN || LastSockError() == EINTR)) { + // continue + } else if (result == 0) { + EUDAQ_THROW("Connection reset by peer"); + } else if (result < 0) { + EUDAQ_THROW(LastSockErrorString("Error sending data")); + } + } while (sent < len); + //if (len > 500000) std::cout << "Done send" << std::endl; + } + + static void do_send_packet(SOCKET sock, const unsigned char * data, size_t length) { + //if (length > 500000) std::cout << "Starting send packet" << std::endl; + if (length < 1020) { + size_t len = length; + std::string buffer(len+4, '\0'); + for (int i = 0; i < 4; ++i) { + buffer[i] = static_cast<char>(len & 0xff); + len >>= 8; + } + std::copy(data, data+length, &buffer[4]); + do_send_data(sock, reinterpret_cast<const unsigned char *>(&buffer[0]), buffer.length()); + } else { + size_t len = length; + unsigned char buffer[4] = {0}; + for (int i = 0; i < 4; ++i) { + buffer[i] = static_cast<unsigned char>(len & 0xff); + len >>= 8; + } + do_send_data(sock, buffer, 4); + do_send_data(sock, data, length); + } + //if (length > 500000) std::cout << "Done send packet" << std::endl; + } + +// static void send_data(SOCKET sock, unsigned long data) { +// std::string str; +// for (int i = 0; i < 4; ++i) { +// str += static_cast<char>(data & 0xff); +// data >>= 8; +// } +// send_data(sock, str); +// } + + } // anonymous namespace + + bool ConnectionInfoTCP::Matches(const ConnectionInfo & other) const { + const ConnectionInfoTCP * ptr = dynamic_cast<const ConnectionInfoTCP *>(&other); + //std::cout << " [Match: " << m_fd << " == " << (ptr ? to_string(ptr->m_fd) : "null") << "] " << std::flush; + if (ptr && (ptr->m_fd == m_fd)) return true; + return false; + } + + void ConnectionInfoTCP::Print(std::ostream & os) const { + ConnectionInfo::Print(os); + os << " (" /*<< m_fd << ","*/ << m_host << ")"; + } + + void ConnectionInfoTCP::append(size_t length, const char * data) { + m_buf += std::string(data, length); + update_length(); + //std::cout << *this << " - append: " << m_len << ", " << m_buf.size() << std::endl; + } + + bool ConnectionInfoTCP::havepacket() const { + return m_buf.length() >= m_len + 4; + } + + std::string ConnectionInfoTCP::getpacket() { + if (!havepacket()) EUDAQ_THROW("No packet available"); + std::string packet(m_buf, 4, m_len); + m_buf.erase(0, m_len+4); + update_length(true); + //std::cout << *this << " - getpacket: " << m_len << ", " << m_buf.size() << std::endl; + return packet; + } + + void ConnectionInfoTCP::update_length(bool force) { + //std::cout << "DBG: len=" << m_len << ", buf=" << m_buf.length(); + if (force || m_len == 0) { + m_len = 0; + if (m_buf.length() >= 4) { + for (int i = 0; i < 4; ++i) { + m_len |= to_int(m_buf[i]) << (8*i); + } +// std::cout << " (" << to_hex(m_buf[3], 2) +// << " " << to_hex(m_buf[2], 2) +// << " " << to_hex(m_buf[1], 2) +// << " " << to_hex(m_buf[0], 2) +// << ")"; + } + } + //std::cout << ", len=" << m_len << std::endl; + } + + TCPServer::TCPServer(const std::string & param) + : m_port(from_string(param, 44000)), + m_srvsock(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)), + m_maxfd(m_srvsock) + { + if (m_srvsock == (SOCKET)-1) EUDAQ_THROW(LastSockErrorString("Failed to create socket")); + setup_signal(); + FD_ZERO(&m_fdset); + FD_SET(m_srvsock, &m_fdset); + + setup_socket(m_srvsock); + + sockaddr_in addr; + memset(&addr, 0, sizeof addr); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(m_port); + + if (bind(m_srvsock, (sockaddr *) &addr, sizeof addr)) { + closesocket(m_srvsock); + EUDAQ_THROW(LastSockErrorString("Failed to bind socket: " + param)); + } + if (listen(m_srvsock, MAXPENDING)) { + closesocket(m_srvsock); + EUDAQ_THROW(LastSockErrorString("Failed to listen on socket: " + param)); + } + } + + TCPServer::~TCPServer() { + for (size_t i = 0; i < m_conn.size(); ++i) { + ConnectionInfoTCP * inf = + dynamic_cast<ConnectionInfoTCP *>(m_conn[i].get()); + if (inf && inf->IsEnabled()) { + closesocket(inf->GetFd()); + } + } + closesocket(m_srvsock); + } + + ConnectionInfoTCP & TCPServer::GetInfo(SOCKET fd) const { + const ConnectionInfoTCP tofind(fd); + for (size_t i = 0; i < m_conn.size(); ++i) { + if (tofind.Matches(*m_conn[i]) && m_conn[i]->GetState() >= 0) { + ConnectionInfoTCP * inf = + dynamic_cast<ConnectionInfoTCP *>(m_conn[i].get()); + return *inf; + } + } + EUDAQ_THROW("BUG: please report it"); + } + + void TCPServer::Close(const ConnectionInfo & id) { + for (size_t i = 0; i < m_conn.size(); ++i) { + if (id.Matches(*m_conn[i])) { + ConnectionInfoTCP * inf = + dynamic_cast<ConnectionInfoTCP *>(m_conn[i].get()); + if (inf && inf->IsEnabled()) { + SOCKET fd = inf->GetFd(); + inf->Disable(); + FD_CLR(fd, &m_fdset); + closesocket(fd); + } + } + } + } + + void TCPServer::SendPacket(const unsigned char * data, size_t len, const ConnectionInfo & id, bool duringconnect) { + //std::cout << "SendPacket to " << id << std::endl; + for (size_t i = 0; i < m_conn.size(); ++i) { + //std::cout << "- " << i << ": " << *m_conn[i] << std::flush; + if (id.Matches(*m_conn[i])) { + ConnectionInfoTCP * inf = + dynamic_cast<ConnectionInfoTCP *>(m_conn[i].get()); + if (inf && inf->IsEnabled() && (inf->GetState() > 0 || duringconnect)) { + //std::cout << " ok" << std::endl; + do_send_packet(inf->GetFd(), data, len); + } //else std::cout << " not quite" << std::endl; + } //else std::cout << " nope" << std::endl; + } + } + + void TCPServer::ProcessEvents(int timeout) { + //std::cout << "DEBUG: Process..." << std::endl; + Time t_start = Time::Current(), /*t_curr = t_start,*/ t_remain = Time(0, timeout); + bool done = false; + do { + fd_set tempset; + memcpy(&tempset, &m_fdset, sizeof(tempset)); + //std::cout << "select timeout=" << t_remain << std::endl; + timeval timeremain = t_remain; + int result = select(static_cast<int>(m_maxfd + 1), &tempset, NULL, NULL, &timeremain); + //std::cout << "select done" << std::endl; + + if (result == 0) { + //std::cout << "timeout" << std::endl; + } else if (result < 0 && LastSockError() != EINTR) { + std::cout << LastSockErrorString("Error in select()") << std::endl; + } else if (result > 0) { + + if (FD_ISSET(m_srvsock, &tempset)) { + sockaddr_in addr; + socklen_t len = sizeof(addr); + SOCKET peersock = accept(static_cast<int>(m_srvsock), (sockaddr*)&addr, &len); + if (peersock == INVALID_SOCKET) { + std::cout << LastSockErrorString("Error in accept()") << std::endl; + } else { + //std::cout << "Connect " << peersock << " from " << inet_ntoa(addr.sin_addr) << std::endl; + FD_SET(peersock, &m_fdset); + m_maxfd = (m_maxfd < peersock) ? peersock : m_maxfd; + setup_socket(peersock); + std::string host = inet_ntoa(addr.sin_addr); + host += ":" + to_string(ntohs(addr.sin_port)); + counted_ptr<ConnectionInfo> ptr(new ConnectionInfoTCP(peersock, host)); + bool inserted = false; + for (size_t i = 0; i < m_conn.size(); ++i) { + if (m_conn[i]->GetState() < 0) { + m_conn[i] = ptr; + inserted = true; + } + } + if (!inserted) m_conn.push_back(ptr); + m_events.push(TransportEvent(TransportEvent::CONNECT, *ptr)); + FD_CLR(m_srvsock, &tempset); + } + } + for (SOCKET j=0; j < m_maxfd+1; j++) { + if (FD_ISSET(j, &tempset)) { + char buffer[MAX_BUFFER_SIZE+1]; + + do { + result = recv(j, buffer, MAX_BUFFER_SIZE, 0); + } while (result == -1 && LastSockError() == EINTR); + + if (result > 0) { + buffer[result] = 0; + //std::cout << "Received bits " << j << std::endl; + ConnectionInfoTCP & m = GetInfo(j); + m.append(result, buffer); + while (m.havepacket()) { + done = true; + //std::cout << "Received packet " << j << std::endl; + m_events.push(TransportEvent(TransportEvent::RECEIVE, m, m.getpacket())); + } + } else /*if (result == 0)*/ { + //std::cout << "Disconnect " << j << std::endl; + ConnectionInfoTCP & m = GetInfo(j); + m_events.push(TransportEvent(TransportEvent::DISCONNECT, m)); + m.Disable(); + closesocket(j); + FD_CLR(j, &m_fdset); + /*} else { + std::cout << LastSockErrorString("Error in recv()") << std::endl;*/ + } + } // end if (FD_ISSET(j, &tempset)) + } // end for (j=0;...) + } // end else if (result > 0) + t_remain = Time(0, timeout) + t_start - Time::Current(); + } while (!done && t_remain > Time(0)); + } + + std::string TCPServer::ConnectionString() const { + const char * host = getenv("HOSTNAME"); + if (!host) host = "localhost"; + //gethostname(buf, sizeof buf); + return name + "://" + host + ":" + to_string(m_port); + } + + TCPClient::TCPClient(const std::string & param) + : m_server(param), + m_port(44000), + m_sock(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)), + m_buf(ConnectionInfoTCP(m_sock, param)) + { + if (m_sock == (SOCKET)-1) EUDAQ_THROW(LastSockErrorString("Failed to create socket")); + + size_t i = param.find(':'); + if (i != std::string::npos) { + m_server = trim(std::string(param, 0, i)); + m_port = from_string(std::string(param, i+1), 44000); + } + boost::regex re("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"); + if(boost::regex_match(m_server,re)==0){ + if(m_hosts.find(m_server)!=m_hosts.end()) { + std::cout<<"Did lookup: "<<m_server; + m_server=m_hosts[m_server]; + std::cout<<": "<<m_server<<std::endl; + } + } + if (m_server == "") m_server = "localhost"; + std::cout<<m_server<<" "<<m_port<<std::endl; + + bool success; + do{ + try{ + std::cout<<"Constructor"<<std::endl; + OpenConnection(); + success=true; + std::cout<<"Server has started."<<std::endl; + }catch(::eudaq::LoggedException e){ + std::cout<<"Server is not running. Waiting one second."<<std::endl; + std::cout<<"Constructor loc"<<std::endl; + success=false; + close(m_sock); + m_sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP), + sleep(1); + } + }while (success==false); + } + + void TCPClient::OpenConnection() { + sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(m_port); + + hostent * host = gethostbyname(m_server.c_str()); + std::cout<<m_server<<std::endl; + if (!host) { + closesocket(m_sock); + EUDAQ_THROW(LastSockErrorString("Error looking up address \'" + m_server + "\'")); + } + memcpy((char *) &addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length); + if (connect(m_sock, (sockaddr *) &addr, sizeof(addr)) && + LastSockError() != EINPROGRESS && + LastSockError() != EWOULDBLOCK) { + EUDAQ_THROW("The server is not running."); + //+ to_string(LastSockError()) + " connecting to " + + //m_server + ":" + to_string(m_port))); + } + setup_socket(m_sock); // set to non-blocking + } + + void TCPClient::SendPacket(const unsigned char * data, size_t len, const ConnectionInfo & id, bool) { + //std::cout << "Sending packet to " << id << std::endl; + if (id.Matches(m_buf)) { + //std::cout << " ok" << std::endl; + do_send_packet(m_buf.GetFd(), data, len); + } + //std::cout << "Sent" << std::endl; + } + + void TCPClient::ProcessEvents(int timeout) { + //std::cout << "ProcessEvents()" << std::endl; + Time t_start = Time::Current(), /*t_curr = t_start,*/ t_remain = Time(0, timeout); + bool done = false; + do { + fd_set tempset; + FD_ZERO(&tempset); + FD_SET(m_sock, &tempset); + timeval timeremain = t_remain; + SOCKET result = select(static_cast<int>(m_sock+1), &tempset, NULL, NULL, &timeremain); + //std::cout << "Select result=" << result << std::endl; + + bool donereading = false; + do { + char buffer[MAX_BUFFER_SIZE+1]; + do { + result = recv(m_sock, buffer, MAX_BUFFER_SIZE, 0); + } while (result == (SOCKET)-1 && LastSockError() == EINTR); + if (result == (SOCKET)-1 && LastSockError() == EWOULDBLOCK) { + //std::cout << "no more data" << std::endl; + donereading = true; + } else if (result == 0) { + std::cerr << "WARN: Connection closed (?)" << std::endl; + bool success; + do{ + try{ + std::cout<<"Process events"<<std::endl; + OpenConnection(); + success=true; + std::cout<<"Server has started."<<std::endl; + }catch(::eudaq::LoggedException e){ + std::cout<<"Server is not running. Waiting one second."<<std::endl; + std::cout<<"Process events loc"<<std::endl; + success=false; + close(m_sock); + m_sock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP), + sleep(1); + } + }while (success==false); + donereading = true; + } else if (result == (SOCKET)-1) { + //std::cout << "disconnect or error" << std::endl; + // disconnect || error + EUDAQ_THROW(LastSockErrorString("Socket Error (" + to_string(LastSockError()) + ")")); + } else { + //std::cout << "received bytes: " << escape(std::string(buffer, result)) << std::endl; + m_buf.append(result, buffer); + while (m_buf.havepacket()) { + m_events.push(TransportEvent(TransportEvent::RECEIVE, m_buf, m_buf.getpacket())); + done = true; + } + } + } while (!donereading); + t_remain = Time(0, timeout) + t_start - Time::Current(); + //std::cout << "Remaining: " << t_remain << (t_remain > Time(0) ? " >0" : " <0")<< std::endl; + } while (!done && t_remain > Time(0)); + //std::cout << "done" << std::endl; + } + + TCPClient::~TCPClient() { + closesocket(m_sock); + } + Profiler::Timer TCPClient::m_timer; + +} diff --git a/rce/rcecalib/eudaq/TransportTCP.hh b/rce/rcecalib/eudaq/TransportTCP.hh new file mode 100644 index 0000000000000000000000000000000000000000..5c273af3318b81fd4a661b1ab555194b8834241e --- /dev/null +++ b/rce/rcecalib/eudaq/TransportTCP.hh @@ -0,0 +1,81 @@ +#ifndef EUDAQ_INCLUDED_TransportTCP +#define EUDAQ_INCLUDED_TransportTCP + +#include "eudaq/TransportFactory.hh" +#include "rcecalib/profiler/Profiler.hh" + +# include <sys/select.h> + typedef int SOCKET; + +#include <vector> +#include <string> +#include <map> + +namespace eudaq { + + class ConnectionInfoTCP : public ConnectionInfo { + public: + ConnectionInfoTCP(SOCKET fd, const std::string & host = "") : m_fd(fd), m_host(host), m_len(0), m_buf("") {} + void append(size_t length, const char * data); + bool havepacket() const; + std::string getpacket(); + SOCKET GetFd() const { return m_fd; } + void Disable() { m_state = -1; m_len = 0; m_buf = ""; } + virtual bool Matches(const ConnectionInfo & other) const; + virtual void Print(std::ostream &) const; + virtual std::string GetRemote() const { return m_host; } + virtual ConnectionInfo * Clone() const { return new ConnectionInfoTCP(*this); } + private: + void update_length(bool = false); + SOCKET m_fd; + std::string m_host; + size_t m_len; + std::string m_buf; + }; + + class TCPServer : public TransportServer { + public: + TCPServer(const std::string & param); + virtual ~TCPServer(); + + virtual void Close(const ConnectionInfo & id); + virtual void SendPacket(const unsigned char * data, size_t len, + const ConnectionInfo & id = ConnectionInfo::ALL, + bool duringconnect = false); + virtual void ProcessEvents(int timeout); + + virtual std::string ConnectionString() const; + static const std::string name; + private: + int m_port; + SOCKET m_srvsock; + SOCKET m_maxfd; + fd_set m_fdset; + + ConnectionInfoTCP & GetInfo(SOCKET fd) const; + //typedef std::map<int, TCPConnection> map_t; + //map_t m_map; + }; + + class TCPClient: public TransportClient { + public: + TCPClient(const std::string & param); + virtual ~TCPClient(); + + virtual void SendPacket(const unsigned char * data, size_t len, + const ConnectionInfo & id = ConnectionInfo::ALL, + bool = false); + virtual void ProcessEvents(int timeout = -1); + static Profiler::Timer m_timer; + private: + void OpenConnection(); + std::string m_server; + int m_port; + SOCKET m_sock; + ConnectionInfoTCP m_buf; + static std::map<std::string, std::string> m_hosts; + }; + +} + +#endif // EUDAQ_INCLUDED_TransportTCP diff --git a/rce/rcecalib/eudaq/TransportTCP_POSIX.inc b/rce/rcecalib/eudaq/TransportTCP_POSIX.inc new file mode 100644 index 0000000000000000000000000000000000000000..6f1f9c4ffeb030be2d7a265587f504118fdff7fb --- /dev/null +++ b/rce/rcecalib/eudaq/TransportTCP_POSIX.inc @@ -0,0 +1,51 @@ +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netdb.h> +#include <arpa/inet.h> +#include <fcntl.h> +#include <unistd.h> + +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + +namespace eudaq { + + namespace { + + static inline void closesocket(SOCKET s) { + close(s); + } + + static inline int LastSockError() { + return errno; + } + + static inline std::string LastSockErrorString(const std::string & msg) { + return msg + ": " + strerror(errno); + } + + static void setup_socket(SOCKET sock) { + /// Set non-blocking mode + int iof = fcntl(sock, F_GETFL, 0); + if (iof != -1) + fcntl(sock, F_SETFL, iof | O_NONBLOCK); + + /// Allow the socket to rebind to an address that is still shutting down + /// Useful if the server is quickly shut down then restarted + int one = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + + /// Periodically send packets to keep the connection open + setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); + + /// Try to send any remaining data when a socket is closed + linger ling; + ling.l_onoff = 1; ///< Enable linger mode + ling.l_linger = 1; ///< Linger timeout in seconds + setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof ling); + } + + } + +} diff --git a/rce/rcecalib/eudaq/Utils.cc b/rce/rcecalib/eudaq/Utils.cc new file mode 100644 index 0000000000000000000000000000000000000000..867782b3ead2350fde1de2086e94edf408644f4c --- /dev/null +++ b/rce/rcecalib/eudaq/Utils.cc @@ -0,0 +1,135 @@ +#include "eudaq/Utils.hh" +#include "eudaq/Exception.hh" +#include <cstring> +#include <cstdlib> +#include <iostream> +#include <cctype> + +# include <unistd.h> + +namespace eudaq { + + std::string ucase(const std::string & str) { + std::string result(str); + for (size_t i = 0; i < result.length(); ++i) { + result[i] = std::toupper(result[i]); + } + return result; + } + + std::string lcase(const std::string & str) { + std::string result(str); + for (size_t i = 0; i < result.length(); ++i) { + result[i] = std::tolower(result[i]); + } + return result; + } + + /** Trims the leading and trainling white space from a string + */ + std::string trim(const std::string & s) { + static const std::string spaces = " \t\n\r\v"; + size_t b = s.find_first_not_of(spaces); + size_t e = s.find_last_not_of(spaces); + if (b == std::string::npos || e == std::string::npos) { + return ""; + } + return std::string(s, b, e - b + 1); + } + + std::string escape(const std::string & s) { + std::ostringstream ret; + ret << std::setfill('0') << std::hex; + for (size_t i = 0; i < s.length(); ++i) { + if (s[i] == '\\') + ret << "\\\\"; + else if (s[i] < 32) + ret << "\\x" << std::setw(2) << int(s[i]); + else + ret << s[i]; + } + return ret.str(); + } + + std::string firstline(const std::string & s) { + size_t i = s.find('\n'); + return s.substr(0, i); + } + + std::vector<std::string> split(const std::string & str, const std::string & delim) { + return split(str, delim, false); + } + + std::vector<std::string> split(const std::string & str, const std::string & delim, bool dotrim) { + std::string s(str); + std::vector<std::string> result; + if (str == "") return result; + size_t i; + while ((i = s.find_first_of(delim)) != std::string::npos) { + result.push_back(dotrim ? trim(s.substr(0, i)) : s.substr(0, i)); + s = s.substr(i + 1); + } + result.push_back(s); + return result; + } + + void mSleep(unsigned ms) { + usleep(ms * 1000); + } + + template<> + long from_string(const std::string & x, const long & def) { + if (x == "") return def; + const char * start = x.c_str(); + char * end = 0; + int base = 10; + std::string bases("box"); + if (x.length() > 2 && x[0] == '0' && bases.find(x[1]) != std::string::npos) { + if (x[1] == 'b') base = 2; + else if (x[1] == 'o') base = 8; + else if (x[1] == 'x') base = 16; + start += 2; + } + long result = std::strtol(start, &end, base); + if (*end) throw std::invalid_argument("Invalid argument: " + x); + return result; + } + + template<> + unsigned long from_string(const std::string & x, const unsigned long & def) { + if (x == "") return def; + const char * start = x.c_str(); + char * end = 0; + int base = 10; + std::string bases("box"); + if (x.length() > 2 && x[0] == '0' && bases.find(x[1]) != std::string::npos) { + if (x[1] == 'b') base = 2; + else if (x[1] == 'o') base = 8; + else if (x[1] == 'x') base = 16; + start += 2; + } + unsigned long result = std::strtoul(start, &end, base); + if (*end) throw std::invalid_argument("Invalid argument: " + x); + return result; + } + + void WriteStringToFile(const std::string & fname, const std::string & val) { + std::ofstream file(fname.c_str()); + if (!file.is_open()) std::cout<<"Unable to open file " + fname + " for writing"<<std::endl; + file << val << std::endl; + if (file.fail()) std::cout<<"Error writing to file " + fname<<std::endl; + } + + std::string ReadLineFromFile(const std::string & fname) { + std::ifstream file(fname.c_str()); + std::string result; + if (file.is_open()) { + std::getline(file, result); + if (file.fail()) { + std::cout<<"Error reading from file " + fname<<std::endl; + } + } + return result; + } + +} diff --git a/rce/rcecalib/eudaq/Utils.hh b/rce/rcecalib/eudaq/Utils.hh new file mode 100644 index 0000000000000000000000000000000000000000..751f447532877b3584f3b2ae5cfb0c91de41aa61 --- /dev/null +++ b/rce/rcecalib/eudaq/Utils.hh @@ -0,0 +1,261 @@ +#ifndef EUDAQ_INCLUDED_Utils +#define EUDAQ_INCLUDED_Utils + +/** + * \file Utils.hh + * Contains generally useful utility functions. + */ + +#include <string> +#include <vector> +#include <sstream> +#include <iomanip> +#include <stdexcept> +#include <fstream> +#include <sys/types.h> + +namespace eudaq { + + std::string ucase(const std::string &); + std::string lcase(const std::string &); + std::string trim(const std::string & s); + std::string firstline(const std::string & s); + std::string escape(const std::string &); + std::vector<std::string> split(const std::string & str, const std::string & delim = "\t"); + std::vector<std::string> split(const std::string & str, const std::string & delim, bool dotrim); + + /** Sleep for a specified number of milliseconds. + * \param ms The number of milliseconds + */ + void mSleep(unsigned ms); + + /** Converts any type to a string. + * There must be a compatible streamer defined, which this function will make use of. + * \param x The value to be converted. + * \return A string representing the passed in parameter. + */ + template <typename T> + inline std::string to_string(const T & x, int digits = 0) { + std::ostringstream s; + s << std::setfill('0') << std::setw(digits) << x; + return s.str(); + } + + template <typename T> + inline std::string to_string(const std::vector<T> & x, const std::string & sep, int digits = 0) { + std::ostringstream s; + if (x.size() > 0) s << to_string(x[0], digits); + for (size_t i = 1; i < x.size(); ++i) { + s << sep << to_string(x[i], digits); + } + return s.str(); + } + + template <typename T> + inline std::string to_string(const std::vector<T> & x, int digits = 0) { + return to_string(x, ",", digits); + } + + inline std::string to_string(const std::string & x, int /*digits*/ = 0) { + return x; + } + inline std::string to_string(const char * x, int /*digits*/ = 0) { + return x; + } + + /** Converts any type that has an ostream streamer to a string in hexadecimal. + * \param x The value to be converted. + * \param digits The minimum number of digits, shorter numbers are padded with zeroes. + * \return A string representing the passed in parameter in hex. + */ + template <typename T> + inline std::string to_hex(const T & x, int digits = 0) { + std::ostringstream s; + s << std::hex << std::setfill('0') << std::setw(digits) << x; + return s.str(); + } + + template<> + inline std::string to_hex(const unsigned char & x, int digits) { + return to_hex((int)x, digits); + } + + template<> + inline std::string to_hex(const signed char & x, int digits) { + return to_hex((int)x, digits); + } + + template<> + inline std::string to_hex(const char & x, int digits) { + return to_hex((unsigned char)x, digits); + } + + /** Converts a string to any type. + * \param x The string to be converted. + * \param def The default value to be used in case of an invalid string, + * this can also be useful to select the correct template type + * without having to specify it explicitly. + * \return An object of type T with the value represented in x, or if + * that is not valid then the value of def. + */ + template <typename T> + inline T from_string(const std::string & x, const T & def = 0) { + if (x == "") return def; + T ret = def; + std::istringstream s(x); + s >> ret; + char remain = '\0'; + s >> remain; + if (remain) throw std::invalid_argument("Invalid argument: " + x); + return ret; + } + + template<> + inline std::string from_string(const std::string & x, const std::string & def) { + return x == "" ? def : x; + } + + template<> + long from_string(const std::string & x, const long & def); + template<> + unsigned long from_string(const std::string & x, const unsigned long & def); + template<> + inline int from_string(const std::string & x, const int & def) { + return from_string(x, (long)def); + } + template<> + inline unsigned int from_string(const std::string & x, const unsigned int & def) { + return from_string(x, (unsigned long)def); + } + + template <typename T> + struct Holder { + Holder(T val) : m_val(val) {} + T m_val; + }; + + template <typename T> + struct hexdec_t { + enum { DIGITS = 2 * sizeof (T) }; + hexdec_t(T val, unsigned hexdigits) : m_val(val), m_dig(hexdigits) {} + T m_val; + unsigned m_dig; + }; + + template <typename T> + inline hexdec_t<T> hexdec(T val, unsigned hexdigits = hexdec_t<T>::DIGITS) { + return hexdec_t<T>(val, hexdigits); + } + + template <typename T> + inline std::ostream & operator << (std::ostream & os, const hexdec_t<T> & h) { + return os << "0x" << to_hex(h.m_val, h.m_dig) << " (" << h.m_val << ")"; + } + + template <> + inline std::ostream & operator << (std::ostream & os, const hexdec_t<unsigned char> & h) { + return os << (int)h.m_val << " (0x" << to_hex(h.m_val, h.m_dig) << ")"; + } + + template <> + inline std::ostream & operator << (std::ostream & os, const hexdec_t<signed char> & h) { + return os << (int)h.m_val << " (0x" << to_hex(h.m_val, h.m_dig) << ")"; + } + + template <> + inline std::ostream & operator << (std::ostream & os, const hexdec_t<char> & h) { + return os << (int)(unsigned char)h.m_val + << " (0x" << to_hex(h.m_val, h.m_dig) << ")"; + } + + template <typename T> unsigned char * uchar_cast(T * x) { + return reinterpret_cast<unsigned char *>(x); + } + + template <typename T> unsigned char * uchar_cast(std::vector<T> & x) { + return uchar_cast(&x[0]); + } + + template <typename T> const unsigned char * constuchar_cast(const T * x) { + return reinterpret_cast<const unsigned char *>(x); + } + + template <typename T> const unsigned char * constuchar_cast(const std::vector<T> & x) { + return constuchar_cast(&x[0]); + } + + template <typename T> + inline T getbigendian(const unsigned char * ptr) { +#if (defined( __BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(__DARWIN_BYTE_ORDER) && __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN) + return *reinterpret_cast<const T *>(ptr); +#else + T result = 0; + for (size_t i = 0; i < sizeof (T); ++i) { + result <<= 8; + result += *ptr++; + } + return result; +#endif + } + + template <typename T> + inline T getlittleendian(const unsigned char * ptr) { +#if (defined( __BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__DARWIN_BYTE_ORDER) && __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN) + return *reinterpret_cast<const T *>(ptr); +#else + T result = 0; + for (size_t i = 0; i < sizeof (T); ++i) { + result += *ptr++ << (8*i); + } + return result; +#endif + } + + template <typename T> + inline void setbigendian(unsigned char * ptr, const T & val) { +#if (defined( __BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(__DARWIN_BYTE_ORDER) && __DARWIN_BYTE_ORDER == __DARWIN_BIG_ENDIAN) + *reinterpret_cast<T *>(ptr) = val; +#else + T tmp = val; + ptr += sizeof (T); + for (size_t i = 0; i < sizeof (T); ++i) { + *--ptr = tmp & 0xff; + tmp >>= 8; + } +#endif + } + + template <typename T> + inline void setlittleendian(unsigned char * ptr, const T & val) { +#if (defined( __BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__DARWIN_BYTE_ORDER) && __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN) + *reinterpret_cast<T *>(ptr) = val; +#else + T tmp = val; + for (size_t i = 0; i < sizeof (T); ++i) { + *ptr++ = tmp & 0xff; + tmp >>= 8; + } +#endif + } + + std::string ReadLineFromFile(const std::string & fname); + + template <typename T> + inline T ReadFromFile(const std::string & fname, const T & def = 0) { + return from_string(ReadLineFromFile(fname), def); + } + + void WriteStringToFile(const std::string & fname, const std::string & val); + + template <typename T> + inline void WriteToFile(const std::string & fname, const T & val) { + WriteStringToFile(fname, to_string(val)); + } + +} + +#endif // EUDAQ_INCLUDED_Utils diff --git a/rce/rcecalib/eudaq/constituents.mk b/rce/rcecalib/eudaq/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..4be9e5245b2ab44113a0a3cfcc3103279f54751d --- /dev/null +++ b/rce/rcecalib/eudaq/constituents.mk @@ -0,0 +1,61 @@ +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +modlibnames := eudaq +endif + +libsrcs_eudaq := BufferSerializer.cc \ + DetectorEvent.cc \ + Event.cc \ + Exception.cc \ + FileSerializer.cc \ + RawDataEvent.cc \ + Time.cc \ + Utils.cc \ + Producer.cc \ + CommandReceiver.cc \ + DataSender.cc \ + DataSenderIF.cc \ + TransportClient.cc \ + Configuration.cc \ + Status.cc \ + TransportBase.cc \ + TransportFactory.cc \ + TransportTCP.cc \ + TransportServer.cc \ + TransportNULL.cc \ + ProducerIF.cc \ + Mutex.cc + +libincs_eudaq := rcecalib + + +ifneq ($(findstring linux,$(tgt_os)),) + +libnames := eudaq +tgtnames := testread testreadp testwrite + +tgtsrcs_testread := testread.cc +tgtincs_testread := rcecalib + + +tgtlibs_testread := \ + rcecalib/eudaq +tgtslib_testread := $(boost_regex_lib) + +tgtsrcs_testreadp := testreadp.cc +tgtincs_testreadp := rcecalib + + +tgtlibs_testreadp := \ + rcecalib/eudaq +tgtslib_testreadp := $(boost_regex_lib) + +tgtsrcs_testwrite := testwrite.cc +tgtincs_testwrite := rcecalib + +tgtlibs_testwrite := \ + rcecalib/eudaq +tgtslib_testwrite := $(boost_regex_lib) + +LXFLAGS +=-L$(RELEASE_DIR)/build/root/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lGui -pthread -lm -ldl -rdynamic +endif + diff --git a/rce/rcecalib/eudaq/counted_ptr.hh b/rce/rcecalib/eudaq/counted_ptr.hh new file mode 100644 index 0000000000000000000000000000000000000000..6c8dc11143c85129e7b21178c2efb3394425fe28 --- /dev/null +++ b/rce/rcecalib/eudaq/counted_ptr.hh @@ -0,0 +1,113 @@ +/* + * counted_ptr - simple reference counted pointer. + * + * The is a non-intrusive implementation that allocates an additional + * int and pointer for every counted object. + * + * From: http://ootips.org/yonat/4dev/ + * Thanks to Yonat Sharon for this code + * + */ + +#ifndef COUNTED_PTR_H +#define COUNTED_PTR_H + +#ifdef _GLIBCXX_DEBUG +#include <vector> +#define EUDAQ_DIE std::vector<char>(1)[100] +#endif + +/* For ANSI-challenged compilers, you may want to #define + * NO_MEMBER_TEMPLATES or explicit */ + +template <class X> class counted_ptr +{ +public: + typedef X element_type; + + explicit counted_ptr(X* p = 0) // allocate a new counter + : itsCounter(0) {if (p) itsCounter = new counter(p);} + ~counted_ptr() + {release();} + counted_ptr(const counted_ptr& r) throw() + {acquire(r.itsCounter);} + counted_ptr& operator=(const counted_ptr& r) + { + if (this != &r) { + release(); + acquire(r.itsCounter); + } + return *this; + } + counted_ptr& operator=(X * p) + { + release(); + if (p) itsCounter = new counter(p); + return *this; + } + operator bool () const { + return get(); + } +#ifndef NO_MEMBER_TEMPLATES + template <class Y> friend class counted_ptr; + template <class Y> counted_ptr(const counted_ptr<Y>& r) throw() + {acquire(r.itsCounter);} + template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r) + { + if (this != &r) { + release(); + acquire(r.itsCounter); + } + return *this; + } +#endif // NO_MEMBER_TEMPLATES + + X& operator*() const throw() { +#ifdef _GLIBCXX_DEBUG + if (!itsCounter || !itsCounter->ptr) EUDAQ_DIE; +#endif + return *itsCounter->ptr; + } + X* operator->() const throw() { +#ifdef _GLIBCXX_DEBUG + if (!itsCounter || !itsCounter->ptr) EUDAQ_DIE; +#endif + return itsCounter->ptr; + } + X* get() const throw() { +#ifdef _GLIBCXX_DEBUG + //if (!itsCounter || !itsCounter->ptr) EUDAQ_DIE; +#endif + return itsCounter ? itsCounter->ptr : 0; + } + bool unique() const throw() + {return (itsCounter ? itsCounter->count == 1 : true);} + +private: + + struct counter { + counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {} + X* ptr; + unsigned count; + }* itsCounter; + + void acquire(counter* c) throw() + { // increment the count + itsCounter = c; + if (c) ++c->count; + } + + void release() + { // decrement the count, delete if it is 0 + if (itsCounter) { + if (--itsCounter->count == 0) { + delete itsCounter->ptr; + delete itsCounter; + } + itsCounter = 0; + } + } +}; + +#endif // COUNTED_PTR_H + diff --git a/rce/rcecalib/eudaq/testread.cc b/rce/rcecalib/eudaq/testread.cc new file mode 100644 index 0000000000000000000000000000000000000000..3a5e7b6911b645ace8577fb0c8c039936ca5ba75 --- /dev/null +++ b/rce/rcecalib/eudaq/testread.cc @@ -0,0 +1,245 @@ +#include "eudaq/Event.hh" +#include "config/FormattedRecord.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/FileSerializer.hh" +#include "eudaq/counted_ptr.hh" + +#include <TApplication.h> +#include <TROOT.h> +#include <TStyle.h> +#include <TCanvas.h> +#include <TH2F.h> +#include <TF1.h> +#include <TFile.h> + +unsigned indx=0; + +unsigned nextcurrent(unsigned char* p){ + unsigned current=*(unsigned*)&p[indx]; + //unsigned current=(p[indx]<<24) | (p[indx+1]<<16) | (p[indx+2]<<8) | p[indx+3]; + indx+=4; + return current; +} +unsigned getWord(unsigned char *p, int word){ + return *(unsigned*)&p[word*4]; + //return (p[word*4]<<24) | (p[word*4+1]<<16) | (p[word*4+2]<<8) | p[word*4+3]; +} + +int main(int argc, char **argv){ + int linkmap[]={4,0,0,0,0,0,0,0,0,0,0,0,1,2,3}; + TApplication *tapp; + const char* filename=argv[1]; + int nevt=100000000; + if(argc==3)nevt=atoi(argv[2]); + tapp=new TApplication("bla", &argc, argv); + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(1); + gStyle->SetPalette(1); + gStyle->SetOptFit(111); + gStyle->SetErrorX(0); + + unsigned noisy[5][16][160][18]; + unsigned hitmap[5][16][160][18]; + for(int i=0;i<5;i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<160;k++){ + for(int l=0;l<18;l++){ + hitmap[i][j][k][l]=0; + noisy[i][j][k][l]=0; + } + } + } + } + // std::ifstream nos("noisypixels3.txt"); + //int md, chp, r, c; + //while(!nos.eof()){ + // nos>>md>>chp>>r>>c; + // noisy[md][chp][r][c]=1; + //} + TCanvas *co[5]; + TCanvas *ct[5]; + TH2F* occ[5]; + TH1F* toth[5]; + TCanvas *tdcc; + TH1F* tdc; + char name[128], title[128]; + for (int i=0;i<5;i++){ + sprintf(name,"co%d",i); + co[i]=new TCanvas(name,"Canvas",600,600); + sprintf(name,"occ%d",i); + sprintf(title,"Occupancy module %d",i+1); + //occ[i]=new TH2F(name,title, 18,-.5,17.5,160,-.5,159.5); + if(i==4) + occ[i]=new TH2F(name,title, 80,0,80,336,0, 336); //FEI4 + else + occ[i]=new TH2F(name,title, 8*18,0,8*18,2*160,0, 2*160); + co[i]->Draw(); + occ[i]->Draw("colz"); + occ[i]->SetMinimum(0); + sprintf(name,"ct%d",i); + ct[i]=new TCanvas(name,"Canvas",600,600); + sprintf(name,"tot%d",i); + sprintf(title,"ToT module %d",i+1); + toth[i]=new TH1F(name,title, 256,-.5,255.5); + //sprintf(title,"Timing module %d",i+1); + //toth[i]=new TH1F(name,title, 16,-.5,15.5); + ct[i]->Draw(); + toth[i]->Draw(); + } + tdcc=new TCanvas("TDCC","Canvas",600,600); + tdc=new TH1F("TDC","TDC",64,-.5,63.5); + tdcc->Draw(); + tdc->Draw(); + + int l1id=0; + int link=0; + int bxid=0; + int firstbxid=0; + int highesttot=0; + int ntrg=0; + int nev=0; + eudaq::FileDeserializer fs(filename); + while(fs.HasData()){ + eudaq::DetectorEvent* dev=(eudaq::DetectorEvent*)eudaq::EventFactory::Create(fs); + nev++; + if(nev>nevt)break; + //if(nev==10)break; + // dev->Print(std::cout); + if(dev->IsEORE() || dev->IsBORE())continue; + eudaq::RawDataEvent::data_t pixblock; + int modtot[5]; + for(int i=0;i<5;i++)modtot[i]=0; + for(unsigned k=0;k<dev->NumEvents();k++){ + int oldl1id=-1; + eudaq::RawDataEvent* rev=(eudaq::RawDataEvent*)dev->GetEvent(k); + if(rev->GetSubType()=="APIX-CT"){ + eudaq::RawDataEvent::data_t block0=rev->GetBlock(0); + // std::cout<<"Block 0 size: "<<std::dec<<block0.size()<<std::endl; + //for(int i=0;i<9;i++){ + // std::cout<<std::hex<<getWord(&block0[0],i)<<std::endl; + //} + unsigned counter1=getWord(&block0[0],2); + unsigned counter2=getWord(&block0[0],3); + unsigned long long counter=counter2; + counter=(counter<<32) | counter1; + //printf("%llx\n",counter); + int bitpos=-1; + for (int j=0;j<64;j++){ + if(((counter>>j)&1)==0){ + bitpos=j; + break; + } + } + // if(bitpos!=-1)std::cout<<"Phase is " <<bitpos*.4<<" ns"<<std::endl; + if(bitpos!=-1)tdc->Fill(bitpos); + unsigned trgtime1=getWord(&block0[0],4); + unsigned trgtime2=getWord(&block0[0],5); + unsigned deadtime1=getWord(&block0[0],6); + unsigned deadtime2=getWord(&block0[0],7); + unsigned long long trgtime=trgtime1; + trgtime=(trgtime<<32) | trgtime2; + unsigned long long deadtime=deadtime1; + deadtime=(deadtime<<32) | deadtime2; + // std::cout<<"Trgtime: "<<trgtime<<std::endl; + //std::cout<<"Deadtime: "<<deadtime<<std::endl; + //unsigned eudaqtrg=getWord(&block0[0],8); + // std::cout<<"Eudaq trigger word: "<<eudaqtrg<<std::endl; + + pixblock=rev->GetBlock(1); + }else if(rev->GetSubType()=="CTEL"){ + pixblock=rev->GetBlock(0); + }else{ + //std::cout<<"Unknown data block. Skipping."<<std::endl; + continue; + } + // std::cout<<"Pixblock size "<<pixblock.size()<<std::endl; + indx=0; + while (indx<pixblock.size()){ + unsigned currentu=nextcurrent(&pixblock[0]); + FormattedRecord current(currentu); + if(current.isHeader()){ + ntrg++; + link=current.getLink(); + //std::cout<<"Data from link "<<link<<std::endl; + l1id=current.getL1id(); + bxid=current.getBxid(); + if(l1id!=oldl1id){ + oldl1id=l1id; + firstbxid=bxid; + } + }else if(current.isData()){ + int chip=current.getFE(); + //std::cout<<"Chip "<<chip<<std::endl; + int tot=current.getToT(); + if(tot>highesttot)highesttot=tot; + int col=current.getCol(); + int row=current.getRow(); + //if(col>17)std::cout<<"Bad column "<<col<<" in module "<<link<<" chip "<<chip<<std::endl; + // if(chip!=8 || row<150){ + // if(chip!=6 || col<16){ + int diffbx=bxid-firstbxid; + //std::cout<<diffbx<<std::endl; + if (diffbx<0)diffbx+=256; + // if(chip!=8||col>0){ + // if(row<156){ + //if(diffbx>5&&diffbx<9){ + if(noisy[linkmap[link]][chip][row][col]==0){// && diffbx>5&&diffbx<12){ + float x,y; + if (chip<8){ + x=18*chip+col; + y=row; + } else { + x=(15-chip)*18+17-col; + y= 319-row; + } + // occ[linkmap[link]]->Fill(chip/2*18+col,(chip%2)*160+row); + + occ[linkmap[link]]->Fill(x,y); + hitmap[linkmap[link]][chip][row][col]++; + //std::cout<<chip/2*18+col<<" "<<(chip%2)*160+row<<" "<<tot<<" "<<l1id<<" "<<firstbxid<<" "<<bxid<<std::endl; + if(link==0&&col<78)std::cout<<col<<" "<<row<<" "<<tot<<" "<<l1id<<" "<<firstbxid<<" "<<bxid<<std::endl; + + if(tot!=14&&col<78)modtot[linkmap[link]]+=tot; + //toth[linkmap[link]]->Fill(tot); + //if(col<78)toth[linkmap[link]]->Fill(diffbx); + //if(link==8 && col<6)std::cout<<"Tot "<<diffbx<<std::endl; + //toth->Fill(diffbx); + //std::cout<<chip<<" "<<row<<" "<<col<<" "<<tot<<std::endl; + } + // } + // } + } + } + } + for(int i=0;i<5;i++)if(modtot[i]!=0)toth[i]->Fill(modtot[i]); + } + // std::cout<<"Highest ToT: "<<highesttot<<std::endl; + for (int i=0;i<5;i++){ + occ[i]->Draw("colz"); + toth[i]->Draw(); + //toth[i]->Fit("gaus"); + co[i]->Update(); + ct[i]->Update(); + } + tdc->Draw(); + tdcc->Update(); + std::cout<<nev<<" events and "<<ntrg<<" triggers."<<std::endl; + std::cout<<"Noisy pixels:"<<std::endl; + for(int i=0;i<5;i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<160;k++){ + for(int l=0;l<18;l++){ + if( hitmap[i][j][k][l]>5){ + std::cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<std::endl; + } + } + } + } + } +// TFile a("out.root","recreate"); +// tdc->Write(); + // a.Close(); + tapp->Run(); +} + diff --git a/rce/rcecalib/eudaq/testreadp.cc b/rce/rcecalib/eudaq/testreadp.cc new file mode 100644 index 0000000000000000000000000000000000000000..708bb50220ae57c99cc7abda5d280d36f1c1c138 --- /dev/null +++ b/rce/rcecalib/eudaq/testreadp.cc @@ -0,0 +1,258 @@ +#include "config/FormattedRecord.hh" +#include <stdlib.h> +#include <fstream> + +#include <TApplication.h> +#include <TROOT.h> +#include <TStyle.h> +#include <TCanvas.h> +#include <TH2F.h> +#include <TF1.h> +#include <TFile.h> + +int indx=0; + +unsigned nextcurrent(char* p){ + unsigned current=*(unsigned*)&p[indx]; + //unsigned current=(p[indx]<<24) | (p[indx+1]<<16) | (p[indx+2]<<8) | p[indx+3]; + indx+=4; + return current; +} +unsigned getWord(char *p, int word){ + return *(unsigned*)&p[word*4]; + //return (p[word*4]<<24) | (p[word*4+1]<<16) | (p[word*4+2]<<8) | p[word*4+3]; +} + +int main(int argc, char **argv){ + int linkmap[]={0,1,2,3,4,5,0,0,0,0,0,4,1,2,3}; + TApplication *tapp; + const char* filename=argv[1]; + int nevt=100000000; + if(argc==3)nevt=atoi(argv[2]); + tapp=new TApplication("bla", &argc, argv); + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(1); + gStyle->SetPalette(1); + gStyle->SetOptFit(111); + gStyle->SetErrorX(0); + + unsigned noisy[5][16][160][18]; + unsigned hitmap[5][16][160][18]; + for(int i=0;i<5;i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<160;k++){ + for(int l=0;l<18;l++){ + hitmap[i][j][k][l]=0; + noisy[i][j][k][l]=0; + } + } + } + } + // std::ifstream nos("noisypixels3.txt"); + //int md, chp, r, c; + //while(!nos.eof()){ + // nos>>md>>chp>>r>>c; + // noisy[md][chp][r][c]=1; + //} + TCanvas *co[15]; + TCanvas *ct[15]; + TH2F* occ[15]; + TH1F* toth[15]; + TCanvas *tdcc; + TH1F* tdc; + char name[128], title[128]; + for (int i=0;i<6;i++){ + sprintf(name,"co%d",i); + co[i]=new TCanvas(name,"Canvas",600,600); + sprintf(name,"occ%d",i); + sprintf(title,"Occupancy module %d",i+1); + //occ[i]=new TH2F(name,title, 18,-.5,17.5,160,-.5,159.5); + //if(i!=4) + occ[i]=new TH2F(name,title, 80,0,80,336,0, 336); //FEI4 + //else + //occ[i]=new TH2F(name,title, 8*18,0,8*18,2*160,0, 2*160); + co[i]->Draw(); + occ[i]->Draw("colz"); + occ[i]->SetMinimum(0); + sprintf(name,"ct%d",i); + ct[i]=new TCanvas(name,"Canvas",600,600); + sprintf(name,"tot%d",i); + //sprintf(title,"ToT module %d",i+1); + //toth[i]=new TH1F(name,title, 256,-.5,255.5); + sprintf(title,"Timing module %d",i+1); + toth[i]=new TH1F(name,title, 16,-.5,15.5); + ct[i]->Draw(); + toth[i]->Draw(); + } + tdcc=new TCanvas("TDCC","Canvas",600,600); + tdc=new TH1F("TDC","TDC",64,-.5,63.5); + tdcc->Draw(); + tdc->Draw(); + + int l1id=0; + int link=0; + int bxid=0; + int firstbxid=0; + int highesttot=0; + int ntrg=0; + int nev=0; + std::ifstream fs(filename, std::ios::binary); + char block0[9*sizeof(unsigned)] ; + char* pixblock=0; + unsigned size, evtno; + int modtot[15]; + if(!fs.good()){ + std::cout<<"Error opening file."<<std::endl; + exit(0); + } + unsigned timestamp; + unsigned nRCE; + fs.read((char*)×tamp,4); + std::cout<<"Timestamp at start of file: "<<timestamp<<std::endl; + fs.read((char*)&nRCE,4); + std::cout<<"Number of RCEs: "<<nRCE<<std::endl; + while(fs.good()){ + fs.read((char*)&size, 4); + if(fs.eof())break; + nev++; + if(nev>nevt)break; + //if(nev==10)break; + // dev->Print(std::cout); + for(int i=0;i<6;i++)modtot[i]=0; + int oldl1id=-1; + fs.read((char*)&evtno, 4); + //std::cout<<"Size "<<size<<std::endl; + //std::cout<<"Event number "<<evtno<<std::endl; + unsigned tdcsize; + fs.read((char*)&tdcsize, 4); + std::cout<<"RCE: "<<tdcsize<<std::endl; + fs.read(block0,9*sizeof(unsigned)); + // TDC readout. + unsigned counter1=getWord(&block0[0],2); + unsigned counter2=getWord(&block0[0],3); + unsigned long long counter=counter2; + counter=(counter<<32) | counter1; + //printf("TDC value: %llx\n",counter); + int bitpos=-1; + for (int j=0;j<64;j++){ + if(((counter>>j)&1)==0){ + bitpos=j; + break; + } + } + // if(bitpos!=-1)std::cout<<"Phase is " <<bitpos*.4<<" ns"<<std::endl; + if(bitpos!=-1)tdc->Fill(bitpos); + unsigned trgtime1=getWord(&block0[0],4); + unsigned trgtime2=getWord(&block0[0],5); + unsigned deadtime1=getWord(&block0[0],6); + unsigned deadtime2=getWord(&block0[0],7); + unsigned long long trgtime=trgtime1; + trgtime=(trgtime<<32) | trgtime2; + unsigned long long deadtime=deadtime1; + deadtime=(deadtime<<32) | deadtime2; + std::cout<<"Trgtime: "<<trgtime<<std::endl; + std::cout<<"Deadtime: "<<deadtime<<std::endl; + unsigned eudaqtrg=getWord(&block0[0],8); + //std::cout<<"Eudaq trigger word: "<<std::hex<<eudaqtrg<<std::dec<<std::endl; + + int pixblocksize=size-12*sizeof(unsigned); + pixblock=new char[pixblocksize]; + fs.read(pixblock,pixblocksize); + indx=0; + while (indx<pixblocksize){ + unsigned currentu=nextcurrent(&pixblock[0]); + FormattedRecord current(currentu); + if(current.isHeader()){ + ntrg++; + link=current.getLink(); + //std::cout<<"Data from link "<<link<<std::endl; + l1id=current.getL1id(); + bxid=current.getBxid(); + //std::cout<<l1id<<" "<<bxid<<std::endl; + if(l1id!=oldl1id){ + oldl1id=l1id; + firstbxid=bxid; + } + }else if(current.isHeaderTwo()){ + int rce = current.getRCE(); + std::cout<<"New RCE "<<rce<<std::endl; + }else if(current.isData()){ + int chip=current.getFE(); + //std::cout<<"Chip "<<chip<<std::endl; + int tot=current.getToT(); + if(tot>highesttot)highesttot=tot; + int col=current.getCol(); + int row=current.getRow(); + //std::cout<<"Hit "<<chip<<" "<<row<<" "<<col<<std::endl; + //if(col>17)std::cout<<"Bad column "<<col<<" in module "<<link<<" chip "<<chip<<std::endl; + // if(chip!=8 || row<150){ + // if(chip!=6 || col<16){ + int diffbx=bxid-firstbxid; + //std::cout<<diffbx<<std::endl; + if (diffbx<0)diffbx+=256; + // if(chip!=8||col>0){ + // if(row<156){ + //if(diffbx>5&&diffbx<9){ + //if(diffbx>15)std::cout<<firstbxid<<" "<<bxid<<std::endl; + //if(noisy[linkmap[link]][chip][row][col]==0){// && diffbx>5&&diffbx<12){ + float x,y; + if (chip<8){ + x=18*chip+col; + y=row; + } else { + x=(15-chip)*18+17-col; + y= 319-row; + } + // occ[linkmap[link]]->Fill(chip/2*18+col,(chip%2)*160+row); + + occ[linkmap[link]]->Fill(x,y); + //hitmap[linkmap[link]][chip][row][col]++; + //std::cout<<chip/2*18+col<<" "<<(chip%2)*160+row<<" "<<tot<<" "<<l1id<<" "<<firstbxid<<" "<<bxid<<std::endl; + //if(link==0&&col<78)std::cout<<col<<" "<<row<<" "<<tot<<" "<<l1id<<" "<<firstbxid<<" "<<bxid<<std::endl; + + if(tot!=14&&col<78)modtot[linkmap[link]]+=tot; + //toth[linkmap[link]]->Fill(tot); + toth[linkmap[link]]->Fill(diffbx); + //if(link==8 && col<6)std::cout<<"Tot "<<diffbx<<std::endl; + //toth->Fill(diffbx); + //std::cout<<chip<<" "<<row<<" "<<col<<" "<<tot<<std::endl; + //} + // } + // } + } + } + //for(int i=0;i<5;i++)if(modtot[i]!=0)toth[i]->Fill(modtot[i]); + delete [] pixblock; + } + // std::cout<<"Highest ToT: "<<highesttot<<std::endl; + for (int i=0;i<6;i++){ + occ[i]->Draw("colz"); + //toth[i]->Draw(); + //toth[i]->Fit("gaus"); + //co[i]->Update(); + ct[i]->Update(); + } + tdc->Draw(); + tdcc->Update(); + std::cout<<nev<<" events and "<<ntrg<<" triggers."<<std::endl; + std::cout<<"Noisy pixels:"<<std::endl; + /* + for(int i=0;i<5;i++){ + for(int j=0;j<16;j++){ + for(int k=0;k<160;k++){ + for(int l=0;l<18;l++){ + if( hitmap[i][j][k][l]>5){ + // std::cout<<i<<" "<<j<<" "<<k<<" "<<l<<" "<<std::endl; + } + } + } + } + } + */ + // TFile a("out.root","recreate"); + // tdc->Write(); + // a.Close(); + tapp->Run(); +} + + diff --git a/rce/rcecalib/eudaq/testwrite.cc b/rce/rcecalib/eudaq/testwrite.cc new file mode 100644 index 0000000000000000000000000000000000000000..44257454b79053b0cdb20499b2b2ef68f7ff26e5 --- /dev/null +++ b/rce/rcecalib/eudaq/testwrite.cc @@ -0,0 +1,19 @@ +#include "eudaq/Event.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/FileSerializer.hh" +#include "eudaq/counted_ptr.hh" + + +int main(){ + char data[]="bla"; + eudaq::DetectorEvent dev(100,1,0); + eudaq::RawDataEvent* rev=new eudaq::RawDataEvent("CTEL",100,1); + counted_ptr<eudaq::Event> cp(rev); + rev->AddBlock(0,data,3); + dev.AddEvent(cp); + dev.Print(std::cout); + eudaq::FileSerializer fs("test.out"); + dev.Serialize(fs); + +} diff --git a/rce/rcecalib/flags.mk b/rce/rcecalib/flags.mk new file mode 100644 index 0000000000000000000000000000000000000000..94ac456ba95d9febb01c4a030a58305d9ad4b3ba --- /dev/null +++ b/rce/rcecalib/flags.mk @@ -0,0 +1,86 @@ +include $(RELEASE_DIR)/make/sw/flags.mk + +BOOST_VERSION:=1_42 +ifeq ($(TDAQ_VERSION),4) +CPPFLAGS+=-DTDAQ_RELEASE_4 +BOOST_VERSION=1_44 +endif + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + +DEPFLAGS+= -D__powerpc__ -D__GNU__ -D__GLIBC__=2 -DBOOST_THREAD_POSIX +DEFINES+= -D__powerpc__ -D__GNU__ -D__GLIBC__=2 -DBOOST_THREAD_POSIX +MDEFINES+= -D__powerpc__ -D__GNU__ -D__GLIBC__=2 -DBOOST_THREAD_POSIX -DERS_NO_DEBUG -mlongcall + +endif + +ifneq ($(findstring x86_64-linux,$(tgt_arch)),) +DEFINES+= -D__LITTLE_ENDIAN__ +DEPFLAGS+= -D__LITTLE_ENDIAN__ +endif + +CPPFLAGS += -I$(RELEASE_DIR)/build/rcecalib/obj/$(tgt_arch)/idl +CPPFLAGS += -I$(RELEASE_DIR)/build/rcecalib/modobj/$(tgt_arch)/idl +CPPFLAGS += -I$(RELEASE_DIR)/build/rcecalib/obj/$(tgt_arch)/idl +CPPFLAGS += -I$(RELEASE_DIR)/build/rcecalib/modobj/$(tgt_arch)/idl +CPPFLAGS += -I$(RCE_CORE)/include +CPPFLAGS += -I$(PIXLIBINTERFACE) +LXFLAGS += -L$(RCE_CORE)/$(tgt_arch)/lib + +rdb_lib:= +ers_lib:=$(TDAQC_INST_PATH)/$(tgt_arch)/lib/ers +ers_stream_lib:= +owl_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/owl +ipc_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/ipc +oh_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/oh +ifneq ($(findstring i686,$(tgt_arch)),) +oh_root_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/ohroot +else +oh_root_lib:= +endif +is_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/is +tdaq_cmdline_lib=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/cmdline +ifneq ($(findstring i686,$(tgt_arch)),) +boost_thread_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_thread-gcc43-mt-$(BOOST_VERSION) +boost_date_time_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_date_time-gcc43-mt-$(BOOST_VERSION) +boost_regex_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_regex-gcc43-mt-$(BOOST_VERSION) +else +boost_thread_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_thread +boost_date_time_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_date_time +boost_regex_lib:=$(TDAQ_BOOST)/$(tgt_arch)/lib/boost_regex +endif +omniorb_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/omniORB4 +omnithread_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/omnithread +mysql_lib:=$(TDAQ_MYSQL)/$(tgt_arch)/lib/mysqlclient +#zlib hack for rtems - avoid clash with internal rtems zlib +ifneq ($(findstring i686,$(tgt_arch)),) +z_lib:=$(TDAQC_EXT_PATH)/$(tgt_arch)/lib/z +else +z_lib:=/daq/slc5/sw/lcg/external/zlib/1.2.3p1/ppc-rtems-rce405-opt/lib/zz +ifeq ($(TDAQ_VERSION),4) +rdb_lib:=$(TDAQ_INST_PATH)/$(tgt_arch)/lib/rdb +ers_lib=$(TDAQC_INST_PATH)/$(tgt_arch)/lib/ers +ers_stream_lib:=$(TDAQC_INST_PATH)/$(tgt_arch)/lib/ErsBaseStreams +endif +endif + +ARCH=$(tgt_arch) +ifneq ($(findstring i686,$(tgt_arch)),) +CPPFLAGS+=-I$(TDAQ_BOOST)/$(ARCH)/include/boost-$(BOOST_VERSION) +else +CPPFLAGS+=-I$(TDAQ_BOOST)/$(ARCH)/include +endif +CPPFLAGS+=-I$(TDAQC_INST_PATH)/include +CPPFLAGS+=-I$(TDAQ_INST_PATH)/include -I$(TDAQ_INST_PATH)/$(ARCH)/include +CPPFLAGS+=-I$(TDAQ_INST_PATH)/$(ARCH)/include/ipc +CPPFLAGS+=-I$(ROOTSYS)/include +CPPFLAGS+=-I$(TDAQ_MYSQL)/$(ARCH)/include +IDLFLAGS+=-I$(TDAQ_INST_PATH)/include +ifneq ($(findstring i686,$(tgt_arch)),) +LXFLAGS+=-Wl,-rpath=$(TDAQC_INST_PATH)/$(ARCH) +LXFLAGS+=-Wl,-rpath=$(TDAQ_INST_PATH)/$(ARCH)/lib +LXFLAGS+=-Wl,-rpath=$(TDAQ_BOOST)/$(ARCH)/lib +LXFLAGS+=-Wl,-rpath=$(TDAQ_MYSQL)/$(ARCH)/lib +endif + + diff --git a/rce/rcecalib/idl/AFPHPTDCModuleConfig.idl b/rce/rcecalib/idl/AFPHPTDCModuleConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..2e8f6c58189fcd0421659cdb1297003e381fb15e --- /dev/null +++ b/rce/rcecalib/idl/AFPHPTDCModuleConfig.idl @@ -0,0 +1,120 @@ +#ifndef AFPHPTDCMODULECONFIG_IDL +#define AFPHPTDCMODULECONFIG_IDL + +module ipc{ + + const long IPC_N_CALIBVALS = 1024; + + + struct AFPHPTDCModuleConfig{ + //Module ID string + char idStr[16]; + //Fpga registers + unsigned short test; + octet tdcControl; + octet run; + octet bypassLut; + octet localClockEn; + octet calClockEn; + octet refEn; + octet hitTestEn; + octet inputSel; + octet address; + octet fanspeed; + unsigned short channelEn; + //calibration constants. Inl=0, Dnl=1; + float calib[2][12][IPC_N_CALIBVALS]; + // Tdc Chip setup + octet test_select[3]; + octet enable_error_mark[3]; + octet enable_error_bypass[3]; + unsigned short enable_error[3]; + octet readout_single_cycle_speed[3]; + octet serial_delay[3]; + octet strobe_select[3]; + octet readout_speed_select[3]; + octet token_delay[3]; + octet enable_local_trailer[3]; + octet enable_local_header[3]; + octet enable_global_trailer[3]; + octet enable_global_header[3]; + octet keep_token[3]; + octet master[3]; + octet enable_bytewise[3]; + octet enable_serial[3]; + octet enable_jtag_readout[3]; + octet tdc_id[3]; + octet select_bypass_inputs[3]; + octet readout_fifo_size[3]; + unsigned short reject_count_offset[3]; + unsigned short search_window[3]; + unsigned short match_window[3]; + octet leading_resolution[3]; + unsigned long fixed_pattern[3]; + octet enable_fixed_pattern[3]; + octet max_event_size[3]; + octet reject_readout_fifo_full[3]; + octet enable_readout_occupancy[3]; + octet enable_readout_separator[3]; + octet enable_overflow_detect[3]; + octet enable_relative[3]; + octet enable_automatic_reject[3]; + unsigned short event_count_offset[3]; + unsigned short trigger_count_offset[3]; + octet enable_set_counters_on_bunch_reset[3]; + octet enable_master_reset_code[3]; + octet enable_master_reset_code_on_event_reset[3]; + octet enable_reset_channel_buffer_when_separator[3]; + octet enable_separator_on_event_reset[3]; + octet enable_separator_on_bunch_reset[3]; + octet enable_direct_event_reset[3]; + octet enable_direct_bunch_reset[3]; + octet enable_direct_trigger[3]; + unsigned short offset[32][3]; + unsigned short coarse_count_offset[3]; + unsigned short dll_tap_adjust3_0[3]; + unsigned short dll_tap_adjust7_4[3]; + unsigned short dll_tap_adjust11_8[3]; + unsigned short dll_tap_adjust15_12[3]; + unsigned short dll_tap_adjust19_16[3]; + unsigned short dll_tap_adjust23_20[3]; + unsigned short dll_tap_adjust27_24[3]; + unsigned short dll_tap_adjust31_28[3]; + unsigned short rc_adjust[3]; + octet not_used[3]; + octet low_power_mode[3]; + octet width_select[3]; + octet vernier_offset[3]; + octet dll_control[3]; + octet dead_time[3]; + octet test_invert[3]; + octet test_mode[3]; + octet enable_trailing[3]; + octet enable_leading[3]; + octet mode_rc_compression[3]; + octet mode_rc[3]; + octet dll_mode[3]; + octet pll_control[3]; + octet serial_clock_delay[3]; + octet io_clock_delay[3]; + octet core_clock_delay[3]; + octet dll_clock_delay[3]; + octet serial_clock_source[3]; + octet io_clock_source[3]; + octet core_clock_source[3]; + octet dll_clock_source[3]; + unsigned short roll_over[3]; + octet enable_matching[3]; + octet enable_pair[3]; + octet enable_ttl_serial[3]; + octet enable_ttl_control[3]; + octet enable_ttl_reset[3]; + octet enable_ttl_clock[3]; + octet enable_ttl_hit[3]; +}; + +}; + +#endif /* multiple inclusion protection */ + + diff --git a/rce/rcecalib/idl/Callback.idl b/rce/rcecalib/idl/Callback.idl new file mode 100644 index 0000000000000000000000000000000000000000..89a37307ddc50f1f2e351ba792a3413577adebc3 --- /dev/null +++ b/rce/rcecalib/idl/Callback.idl @@ -0,0 +1,26 @@ +#ifndef CALLBACK_IDL +#define CALLBACK_IDL + +#include <ipc/ipc.idl> + +module ipc +{ + enum Priority{LOW, MEDIUM, HIGH, NONE}; + enum ScanStatus{IDLE, CONFIGURED, SCANNING, FITTING, STOPPED, DOWNLOADING, FAILED}; + + struct CallbackParams{ + long rce; + ScanStatus status; + long maskStage; + long loop0; + long loop1; + }; + + interface Callback + { + oneway void notify ( in CallbackParams msg ); + oneway void stopServer(); + }; +}; + +#endif diff --git a/rce/rcecalib/idl/HitbusModuleConfig.idl b/rce/rcecalib/idl/HitbusModuleConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..00f35526fa16c985bc2dc24967b86f9b1ca90366 --- /dev/null +++ b/rce/rcecalib/idl/HitbusModuleConfig.idl @@ -0,0 +1,25 @@ +#ifndef HITBUSMODULECONFIG_IDL +#define HITBUSMODULECONFIG_IDL + +module ipc{ + +struct HitbusModuleConfig{ + octet bpm ; + octet delay_tam1 ; + octet delay_tam2 ; + octet delay_tam3 ; + octet delay_tbm1 ; + octet delay_tbm2 ; + octet delay_tbm3 ; + octet bypass_delay ; + octet clock ; + octet function_A ; + octet function_B ; + char idStr[16] ;//Module ID string +}; + +}; + +#endif /* multiple inclusion protection */ + + diff --git a/rce/rcecalib/idl/IPCAFPHPTDCAdapter.idl b/rce/rcecalib/idl/IPCAFPHPTDCAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..3a754bdb908eb8faef0c5d9876eb11e5505d73e6 --- /dev/null +++ b/rce/rcecalib/idl/IPCAFPHPTDCAdapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCAFPHPTDCADAPTER_IDL +#define IPCAFPHPTDCADAPTER_IDL + +#include <ipc/ipc.idl> +#include "AFPHPTDCModuleConfig.idl" + +module ipc +{ + interface IPCAFPHPTDCAdapter : ipc::servant + { + long IPCdownloadConfig(in AFPHPTDCModuleConfig config); + + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCConfigIFAdapter.idl b/rce/rcecalib/idl/IPCConfigIFAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..1f3e73505fea6b80bf8c5c84e6b4f6f6fc6ffc10 --- /dev/null +++ b/rce/rcecalib/idl/IPCConfigIFAdapter.idl @@ -0,0 +1,42 @@ +#ifndef IPCCONFIGIF_IDL +#define IPCCONFIGIF_IDL + +#include <ipc/ipc.idl> + +module ipc +{ + struct ModSetup{ + long id; + long inLink; + long outLink; + }; + + typedef sequence<unsigned long> blockdata; + typedef sequence<octet> chardata; + + interface IPCConfigIFAdapter : ipc::servant + { + oneway void IPCsendTrigger(); + //oneway void IPCsetupParameter(in string name, in long val); + unsigned long IPCsetupParameter(in string name, in long val); + oneway void IPCsetupMaskStage(in long stage); + oneway void IPCenableTrigger(); + oneway void IPCdisableTrigger(); + oneway void IPCresetFE(); + oneway void IPCconfigureModulesHW(); + unsigned long IPCwriteHWregister(in unsigned long addr, in unsigned long val); + unsigned long IPCreadHWregister(in unsigned long addr, out unsigned long val); + unsigned long IPCsendHWcommand(in octet opcode); + unsigned long IPCwriteHWblockData(in blockdata data); + unsigned long IPCreadHWblockData(in blockdata data, out blockdata retv); + unsigned long IPCreadHWbuffers(out chardata retv); + long IPCverifyModuleConfigHW(in long id); + long IPCdeleteModules(); + long IPCnTrigger(); + long IPCsetupTriggerIF(in string type); + long IPCsetupModule(in string name, in string type, in ModSetup par, in string formatter); + + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCFEI3Adapter.idl b/rce/rcecalib/idl/IPCFEI3Adapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..6305f3f3f7f0c83e6abc528e76476465822d0891 --- /dev/null +++ b/rce/rcecalib/idl/IPCFEI3Adapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCFEI3ADAPTER_IDL +#define IPCFEI3ADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelModuleConfig.idl" + +module ipc +{ + interface IPCFEI3Adapter : ipc::servant + { + long IPCdownloadConfig(in PixelModuleConfig config); + + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCFEI4AAdapter.idl b/rce/rcecalib/idl/IPCFEI4AAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..2ceb0576d16a88862740e7e3d2ef5b619708095f --- /dev/null +++ b/rce/rcecalib/idl/IPCFEI4AAdapter.idl @@ -0,0 +1,20 @@ +#ifndef IPCFEI4AADAPTER_IDL +#define IPCFEI4AADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelFEI4AConfig.idl" + +module ipc +{ + interface IPCFEI4AAdapter : ipc::servant + { + long IPCdownloadConfig(in PixelFEI4AConfig config); + oneway void IPCsetChipAddress(in unsigned long val); + unsigned long IPCwriteHWglobalRegister(in long reg, in unsigned short val); + unsigned long IPCreadHWglobalRegister(in long reg, out unsigned short val); + unsigned long IPCwriteDoubleColumnHW(in unsigned long bit, in unsigned long dcol, in uvec data, out uvec readback); + unsigned long IPCreadDoubleColumnHW(in unsigned long bit, in unsigned long dcol, out uvec readback); + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCFEI4BAdapter.idl b/rce/rcecalib/idl/IPCFEI4BAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..798e8b4cc33417db15cd01335ae3df31a8204a4c --- /dev/null +++ b/rce/rcecalib/idl/IPCFEI4BAdapter.idl @@ -0,0 +1,20 @@ +#ifndef IPCFEI4BADAPTER_IDL +#define IPCFEI4BADAPTER_IDL + +#include <ipc/ipc.idl> +#include "PixelFEI4BConfig.idl" + +module ipc +{ + interface IPCFEI4BAdapter : ipc::servant + { + long IPCdownloadConfig(in PixelFEI4BConfig config); + oneway void IPCsetChipAddress(in unsigned long val); + unsigned long IPCwriteHWglobalRegister(in long reg, in unsigned short val); + unsigned long IPCreadHWglobalRegister(in long reg, out unsigned short val); + unsigned long IPCwriteDoubleColumnHW(in unsigned long bit, in unsigned long dcol, in uvec data, out uvec readback); + unsigned long IPCreadDoubleColumnHW(in unsigned long bit, in unsigned long dcol, out uvec readback); + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCHitbusAdapter.idl b/rce/rcecalib/idl/IPCHitbusAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..eb0ac8e8482ca4f7bb6c81df2d068fddc877a7c5 --- /dev/null +++ b/rce/rcecalib/idl/IPCHitbusAdapter.idl @@ -0,0 +1,16 @@ +#ifndef IPCHITBUSADAPTER_IDL +#define IPCHITBUSADAPTER_IDL + +#include <ipc/ipc.idl> +#include "HitbusModuleConfig.idl" + +module ipc +{ + interface IPCHitbusAdapter : ipc::servant + { + long IPCdownloadConfig(in HitbusModuleConfig config); + + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCScanAdapter.idl b/rce/rcecalib/idl/IPCScanAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..ab7e3688f28b41174065c7707cf2f78120df8cf7 --- /dev/null +++ b/rce/rcecalib/idl/IPCScanAdapter.idl @@ -0,0 +1,21 @@ +#ifndef IPCSCANADAPTER_IDL +#define IPCSCANADAPTER_IDL + +#include <ipc/ipc.idl> +#include "ScanOptions.idl" + +module ipc +{ + interface IPCScanAdapter : ipc::servant + { + oneway void IPCstartScan(); + oneway void IPCpause(); + oneway void IPCresume(); + oneway void IPCwaitForData(); + oneway void IPCstopWaiting(); + long IPCgetStatus(); + oneway void IPCabort(); + }; +}; + +#endif diff --git a/rce/rcecalib/idl/IPCScanRootAdapter.idl b/rce/rcecalib/idl/IPCScanRootAdapter.idl new file mode 100644 index 0000000000000000000000000000000000000000..a6e5d89715f3d8ac2c9e4ae90fbcd24c678c1251 --- /dev/null +++ b/rce/rcecalib/idl/IPCScanRootAdapter.idl @@ -0,0 +1,23 @@ +#ifndef IPCSCANROOTADAPTER_IDL +#define IPCSCANROOTADAPTER_IDL + +#include <ipc/ipc.idl> +#include "ScanOptions.idl" +#include "Callback.idl" + +module ipc +{ + typedef sequence<string> StringVect; + + interface IPCScanRootAdapter : ipc::servant + { + long IPCconfigureScan(in ScanOptions options); + StringVect IPCgetHistoNames(in string reg); + StringVect IPCgetPublishedHistoNames(); + unsigned long IPCnEvents(); + oneway void IPCresynch(); + oneway void IPCconfigureCallback(in Callback cb, in Priority pr); + }; +}; + +#endif diff --git a/rce/rcecalib/idl/Makefile b/rce/rcecalib/idl/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..150904876567c0fd09c23933ce7ec67684c59627 --- /dev/null +++ b/rce/rcecalib/idl/Makefile @@ -0,0 +1,21 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +include $(RELEASE_DIR)/make/sw/idl.mk +endif diff --git a/rce/rcecalib/idl/PixelFEI4AConfig.idl b/rce/rcecalib/idl/PixelFEI4AConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..ea9da12ef62cfb621cb78c083345f67afd2de8c0 --- /dev/null +++ b/rce/rcecalib/idl/PixelFEI4AConfig.idl @@ -0,0 +1,117 @@ +#ifndef PixelFEI4AConfig_IDL +#define PixelFEI4AConfig_IDL + +#include "PixelFEI4GenConfig.idl" + +module ipc{ + +struct PixelFEI4AGlobal{ //FE global register + unsigned short TrigCnt; + unsigned short Conf_AddrEnable; + unsigned short Reg2Spare; + unsigned short ErrMask0; + unsigned short ErrMask1; + unsigned short PrmpVbpRight; + unsigned short Vthin; + unsigned short DisVbn_CPPM; + unsigned short PrmpVbp; + unsigned short TdacVbp; + unsigned short DisVbn; + unsigned short Amp2Vbn; + unsigned short Amp2VbpFol; + unsigned short PrmpVbpTop; + unsigned short Amp2Vbp; + unsigned short FdacVbn; + unsigned short Amp2Vbpf; + unsigned short PrmpVbnFol; + unsigned short PrmpVbpLeft; + unsigned short PrmpVbpf; + unsigned short PrmpVbnLcc; + unsigned short Reg13Spare; + unsigned short PxStrobes; + unsigned short S0; + unsigned short S1; + unsigned short LVDSDrvIref; + unsigned short BonnDac; + unsigned short PllIbias; + unsigned short LVDSDrvVos; + unsigned short TempSensBias; + unsigned short PllIcp; + unsigned short Reg17Spare; + unsigned short PlsrIdacRamp; + unsigned short Reg18Spare; + unsigned short PlsrVgOPamp; + unsigned short PlsrDacBias; + unsigned short Reg19Spare; + unsigned short Vthin_AltCoarse; + unsigned short Vthin_AltFine; + unsigned short PlsrDAC; + unsigned short DIGHITIN_Sel; + unsigned short DINJ_Override; + unsigned short HITLD_In; + unsigned short Reg21Spare; + unsigned short Reg22Spare2; + unsigned short Colpr_Addr; + unsigned short Colpr_Mode; + unsigned short Reg22Spare1; + unsigned short DisableColumnCnfg0; + unsigned short DisableColumnCnfg1; + unsigned short DisableColumnCnfg2; + unsigned short TrigLat; + unsigned short CMDcnt; + unsigned short StopModeCnfg; + unsigned short HitDiscCnfg; + unsigned short EN_PLL; + unsigned short Efuse_sense; + unsigned short Stop_Clk; + unsigned short ReadErrorReq; + unsigned short ReadSkipped; + unsigned short Reg27Spare; + unsigned short GateHitOr; + unsigned short CalEn; + unsigned short SR_clr; + unsigned short Latch_en; + unsigned short SR_Clock; + unsigned short LVDSDrvSet06; + unsigned short Reg28Spare; + unsigned short EN40M; + unsigned short EN80M; + unsigned short CLK1; + unsigned short CLK0; + unsigned short EN160M; + unsigned short EN320M; + unsigned short Reg29Spare1; + unsigned short no8b10b; + unsigned short Clk2OutCnfg; + unsigned short EmptyRecord; + unsigned short Reg29Spare2; + unsigned short LVDSDrvEn; + unsigned short LVDSDrvSet30; + unsigned short LVDSDrvSet12; + unsigned short PlsrRiseUpTau; + unsigned short PlsrPwr; + unsigned short PlsrDelay; + unsigned short ExtDigCalSW; + unsigned short ExtAnaCalSW; + unsigned short Reg31Spare; + unsigned short SELB0; + unsigned short SELB1; + unsigned short SELB2; + unsigned short EfuseCref; + unsigned short EfuseVref; + unsigned short Chip_SN; +} ; + +struct PixelFEI4AConfig{ //FE level parameters + char idStr[16]; //Module ID string + unsigned long FEIndex; + PixelFECommand FECommand; + PixelFEI4AGlobal FEGlobal; + octet FEMasks[IPC_N_I4_PIXEL_COLUMNS][IPC_N_I4_PIXEL_ROWS]; // all masks combined, i.e. 4 bits per pixel + PixelFEI4Trims FETrims; + PixelFECalibFEI4 FECalib; +} ; + +}; + +#endif diff --git a/rce/rcecalib/idl/PixelFEI4BConfig.idl b/rce/rcecalib/idl/PixelFEI4BConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..84c3b1066930e0adc0639a3ae28f57687651ce6c --- /dev/null +++ b/rce/rcecalib/idl/PixelFEI4BConfig.idl @@ -0,0 +1,128 @@ +#ifndef PixelFEI4BConfig_IDL +#define PixelFEI4BConfig_IDL + +#include "PixelFEI4GenConfig.idl" + +module ipc{ + +struct PixelFEI4BGlobal{ //FE global register + unsigned short TrigCnt; + unsigned short Conf_AddrEnable; + unsigned short Reg2Spare; + unsigned short ErrMask0; + unsigned short ErrMask1; + unsigned short PrmpVbpRight; + unsigned short BufVgOpAmp; + unsigned short Reg6Spare; + unsigned short PrmpVbp; + unsigned short TdacVbp; + unsigned short DisVbn; + unsigned short Amp2Vbn; + unsigned short Amp2VbpFol; + unsigned short Reg9Spare; + unsigned short Amp2Vbp; + unsigned short FdacVbn; + unsigned short Amp2Vbpf; + unsigned short PrmpVbnFol; + unsigned short PrmpVbpLeft; + unsigned short PrmpVbpf; + unsigned short PrmpVbnLcc; + unsigned short Reg13Spare; + unsigned short PxStrobes; + unsigned short S0; + unsigned short S1; + unsigned short LVDSDrvIref; + unsigned short GADCOpAmp; + unsigned short PllIbias; + unsigned short LVDSDrvVos; + unsigned short TempSensBias; + unsigned short PllIcp; + unsigned short Reg17Spare; + unsigned short PlsrIdacRamp; + unsigned short VrefDigTune; + unsigned short PlsrVgOPamp; + unsigned short PlsrDacBias; + unsigned short VrefAnTune; + unsigned short Vthin_AltCoarse; + unsigned short Vthin_AltFine; + unsigned short PlsrDAC; + unsigned short DIGHITIN_Sel; + unsigned short DINJ_Override; + unsigned short HITLD_In; + unsigned short Reg21Spare; + unsigned short Reg22Spare2; + unsigned short Colpr_Addr; + unsigned short Colpr_Mode; + unsigned short Reg22Spare1; + unsigned short DisableColumnCnfg0; + unsigned short DisableColumnCnfg1; + unsigned short DisableColumnCnfg2; + unsigned short TrigLat; + unsigned short CMDcnt; + unsigned short StopModeCnfg; + unsigned short HitDiscCnfg; + unsigned short EN_PLL; + unsigned short Efuse_sense; + unsigned short Stop_Clk; + unsigned short ReadErrorReq; + unsigned short Reg27Spare1; + unsigned short GADC_Enable; + unsigned short ShiftReadBack; + unsigned short Reg27Spare2; + unsigned short GateHitOr; + unsigned short CalEn; + unsigned short SR_clr; + unsigned short Latch_en; + unsigned short SR_Clock; + unsigned short LVDSDrvSet06; + unsigned short Reg28Spare; + unsigned short EN40M; + unsigned short EN80M; + unsigned short CLK1; + unsigned short CLK0; + unsigned short EN160M; + unsigned short EN320M; + unsigned short Reg29Spare1; + unsigned short no8b10b; + unsigned short Clk2OutCnfg; + unsigned short EmptyRecord; + unsigned short Reg29Spare2; + unsigned short LVDSDrvEn; + unsigned short LVDSDrvSet30; + unsigned short LVDSDrvSet12; + unsigned short TempSensDiodeSel; + unsigned short TempSensDisable; + unsigned short IleakRange; + unsigned short Reg30Spare; + unsigned short PlsrRiseUpTau; + unsigned short PlsrPwr; + unsigned short PlsrDelay; + unsigned short ExtDigCalSW; + unsigned short ExtAnaCalSW; + unsigned short Reg31Spare; + unsigned short GADCSel; + unsigned short SELB0; + unsigned short SELB1; + unsigned short SELB2; + unsigned short Reg34Spare1; + unsigned short PrmpVbpMsnEn; + unsigned short Reg34Spare2; + unsigned short Chip_SN; + unsigned short Reg1Spare; + unsigned short SmallHitErase; + unsigned short Eventlimit; +} ; + +struct PixelFEI4BConfig{ //FE level parameters + char idStr[16]; //Module ID string + unsigned long FEIndex; + PixelFECommand FECommand; + PixelFEI4BGlobal FEGlobal; + octet FEMasks[IPC_N_I4_PIXEL_COLUMNS][IPC_N_I4_PIXEL_ROWS]; // all masks combined, i.e. 4 bits per pixel + PixelFEI4Trims FETrims; + PixelFECalibFEI4 FECalib; +} ; + +}; + +#endif diff --git a/rce/rcecalib/idl/PixelFEI4GenConfig.idl b/rce/rcecalib/idl/PixelFEI4GenConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..b6b5210dd67596e560b51c84855c46081d668a36 --- /dev/null +++ b/rce/rcecalib/idl/PixelFEI4GenConfig.idl @@ -0,0 +1,40 @@ +#ifndef PixelFEI4Config_IDL +#define PixelFEI4Config_IDL + +module ipc{ + + typedef sequence<unsigned long> uvec; + + const long IPC_N_I4_PIXEL_COLUMNS = 80; + const long IPC_N_I4_PIXEL_ROWS = 336; + const long enable = 0; + const long largeCap = 1; + const long smallCap = 2; + const long hitbus = 3; + +struct PixelFECommand{ //FE Command register + octet address; /* 5 bits */ + unsigned long command; /* 32 bits */ +} ; + +struct PixelFECalibFEI4{ +/* Sub-structure for calibration of injection-capacitors, VCAL-DAC and + leakage current measurement */ + float cinjLo; + float cinjHi; + float vcalCoeff[4]; + float chargeCoeffClo; + float chargeCoeffChi; + float chargeOffsetClo; + float chargeOffsetChi; + float monleakCoeff; +} ; + +struct PixelFEI4Trims{ //Trim DACs: + octet dacThresholdTrim[IPC_N_I4_PIXEL_COLUMNS][IPC_N_I4_PIXEL_ROWS]; /* 5 bits per pixel */ + octet dacFeedbackTrim [IPC_N_I4_PIXEL_COLUMNS][IPC_N_I4_PIXEL_ROWS]; /* 4 bits per pixel */ +} ; + +}; + +#endif diff --git a/rce/rcecalib/idl/PixelModuleConfig.idl b/rce/rcecalib/idl/PixelModuleConfig.idl new file mode 100644 index 0000000000000000000000000000000000000000..a2fce8d62c10815943c14fa787b35ba3c02cb23d --- /dev/null +++ b/rce/rcecalib/idl/PixelModuleConfig.idl @@ -0,0 +1,216 @@ +/************************************************************************** + * + * Title: Master/PIX moduleConfigStructures.h + * Version: 11th November 2002 + * + * Description: + * ROD Master DSP Pixel module configuration structures + * and constant definitions. + **************************************************************************/ +#ifndef PIXELMODULECONFIG_IDL +#define PIXELMODULECONFIG_IDL + +module ipc{ + + const long IPC_N_PIXEL_COLUMNS =18; + const long IPC_N_PIXEL_ROWS =160; + const long IPC_N_PIXEL_FE_CHIPS=16; + + const long IPC_FE_I1 =1; + const long IPC_FE_I2 =2; + const long IPC_MCC_I1 =1; + const long IPC_MCC_I2 =2; + + /* MCC options */ + + const long IPC_MCC_SINGLE_40 =0; + const long IPC_MCC_DOUBLE_40 =1; + const long IPC_MCC_SINGLE_80 =2; + const long IPC_MCC_DOUBLE_80 =3; + + +struct PixelFEGlobal{ //FE global register + //This is valid for both FE-I1 & 2, since the FE-I1 is a sub-set. + octet latency ; + octet dacIVDD2 ; + octet dacIP2 ; + octet dacID ; + + octet dacIP ; + octet dacITRIMTH ; + octet dacIF ; + octet dacITH1 ; + + octet dacITH2 ; + octet dacIL ; + octet dacIL2 ; + octet dacITRIMIF ; + + octet dacSpare ; + octet threshTOTMinimum ; + octet threshTOTDouble ; + octet hitbusScaler ; + + octet capMeasure ; + octet gdac ; + octet selfWidth ; + octet selfLatency ; + octet muxTestPixel ; + octet aregTrim ; + octet aregMeas ; + octet dregTrim ; + octet dregMeas ; + octet parity ; + + octet dacMonLeakADC ; + /* was defined as octet, but needs 10 bits */ + unsigned long dacVCAL ; /* extended to 10 bit for FE2/3 */ + octet widthSelfTrigger ; + octet muxDO ; /* note: dynamically defined */ + octet muxMonHit ; + octet muxEOC ; + + octet frequencyCEU ; + octet modeTOTThresh ; + octet enableTimestamp ; + octet enableSelfTrigger ; + octet enableHitParity ; + octet monMonLeakADC ; + octet monADCRef ; + octet enableMonLeak ; + octet statusMonLeak ; + octet enableCapTest ; + octet enableBuffer ; + octet enableVcalMeasure ; + octet enableLeakMeasure ; + octet enableBufferBoost ; + octet enableCP8 ; + octet monIVDD2 ; + octet monID ; + octet enableCP7 ; + octet monIP2 ; + octet monIP ; + octet enableCP6 ; + octet monITRIMTH ; + octet monIF ; + octet enableCP5 ; + octet monITRIMIF ; + octet monVCAL ; + octet enableCP4 ; + octet enableCinjHigh ; + octet enableExternal ; + octet enableTestAnalogRef ; + + octet enableDigital ; + octet enableCP3 ; + octet monITH1 ; + octet monITH2 ; + octet enableCP2 ; + octet monIL ; + octet monIL2 ; + octet enableCP1 ; + octet enableCP0 ; + octet enableHitbus ; + octet monSpare ; + octet enableAregMeas ; + octet enableAreg ; + octet enableLvdsRegMeas ; + octet enableDregMeas ; + octet enableTune ; + octet enableBiasComp ; + octet enableIpMonitor ; +} ; + + +struct PixelFEMasks{ //Pixel-level control bits + unsigned long maskEnable[5][IPC_N_PIXEL_COLUMNS]; /* 32 bits, one bit per pixel thus 5 words per column */ + unsigned long maskSelect[5][IPC_N_PIXEL_COLUMNS]; + unsigned long maskPreamp[5][IPC_N_PIXEL_COLUMNS]; + unsigned long maskHitbus[5][IPC_N_PIXEL_COLUMNS]; +} ; + + +struct PixelFETrims{ //Trim DACs: + octet dacThresholdTrim[IPC_N_PIXEL_ROWS][IPC_N_PIXEL_COLUMNS]; + octet dacFeedbackTrim[IPC_N_PIXEL_ROWS][IPC_N_PIXEL_COLUMNS]; +} ; + + +struct PixelFECalib{ +/* Sub-structure for calibration of injection-capacitors, VCAL-DAC and + leakage current measurement */ + float cinjLo; + float cinjHi; + float vcalCoeff[4]; + float chargeCoeffClo; + float chargeCoeffChi; + float chargeOffsetClo; + float chargeOffsetChi; + float monleakCoeff; +} ; + + +struct PixelMCCRegisters{ //MCC registers + unsigned short regCSR; + unsigned short regLV1; + unsigned short regFEEN; + unsigned short regWFE; + + unsigned short regWMCC; + unsigned short regCNT; + unsigned short regCAL; + unsigned short regPEF; + + unsigned short regWBITD; + unsigned short regWRECD; + unsigned short regSBSR; + + /* Strobe duration is a virtual register (shared with CNT); when preparing the + modules for data this value is substituted for the count. */ + unsigned short regSTR; +} ; + +struct PixelFEConfig{ //FE level parameters + unsigned long FEIndex; + PixelFEGlobal FEGlobal; + PixelFEMasks FEMasks; + PixelFETrims FETrims; + PixelFECalib FECalib; +} ; + + +struct PixelModuleConfig{ + /* FE module-level options: */ + unsigned short maskEnableFEConfig; /* 16 bits, one per FE */ + unsigned short maskEnableFEScan; + unsigned short maskEnableFEDacs; + octet feFlavour; + octet mccFlavour; + + /* FE configurations: */ + PixelFEConfig FEConfig[IPC_N_PIXEL_FE_CHIPS]; + + /* MCC configuration */ + PixelMCCRegisters MCCRegisters; + + char idStr[256]; /* Module identification string */ + octet present; /* Module is physically present. Does not need setting + externally; handled by the Master DSP. */ + + octet active; /* 1 -> participates in scans */ + /* 0 -> registers unchanged during scanning */ + octet moduleIdx; /* Copy of the module's index for access from a pointer */ + octet groupId; /* The ID of the module's group. This is used to indicate + which slave DSP will receive the module's data (if group + based distribution is set), and also to allow different + module groups to be triggered independently (for + cross-talk studies). valid range: [0,7] */ + octet pTTC; /* primary TX channel */ + octet rx; /* data link used by module */ + +} ; /* declare N_PIXEL_CONFIG_SETS structure for each of N_PIXEL_MODULES */ +}; + +#endif /* multiple inclusion protection */ + + diff --git a/rce/rcecalib/idl/ScanOptions.idl b/rce/rcecalib/idl/ScanOptions.idl new file mode 100644 index 0000000000000000000000000000000000000000..a2af15600c0005ba9e1b6a585a9e71bcc45ade90 --- /dev/null +++ b/rce/rcecalib/idl/ScanOptions.idl @@ -0,0 +1,96 @@ +#ifndef SCANOPTIONS_IDL +#define SCANOPTIONS_IDL + +module ipc{ + +typedef sequence<string> StringList; + +/* Trigger setup */ +/* bit mask optionsMask selects TriggerOptions */ +/* Override of global VCAL and delays with individual values */ +/* from ModuleConfig via special USE_MODULECONFIG_DEFAULT value */ +/* custom bitstream for cal trigger command sequence */ +/* define Triggermodes compatible with RODregisters */ + +struct TriggerOptions{ + string triggerMode; + unsigned short triggerMask; + unsigned short moduleTrgMask; + unsigned long nEvents; + octet triggerDataOn; + octet nL1AperEvent; + octet nTriggersPerGroup; + octet Lvl1_Latency; + octet Lvl1_Latency_Secondary; + octet injectForTrigger; + octet hitbusConfig; + unsigned short strobeDuration; + unsigned short deadtime; + unsigned long strobeMCCDelay; + unsigned long strobeMCCDelayRange; + unsigned long CalL1ADelay; + unsigned long eventInterval; + unsigned long vcal_charge; + unsigned short threshold; + unsigned long nTriggers; + StringList optionsMask; /* this is TriggOptions */ +}; + +struct PixelScanFE { + octet phi; + octet totThresholdMode; + octet totMinimum; + octet totTwalk; + octet totLeMode; + octet hitbus; + +}; + +/* Action to be performed after the scan, provision for different fit functions */ + +struct ActionOptions { + string Action; + string fitFunction; + unsigned long targetThreshold; +}; + + +struct ScanLoopDef{ + string scanParameter; + ActionOptions endofLoopAction; + unsigned long nPoints; + sequence<long> dataPoints; +}; + +typedef sequence<ScanLoopDef> ScanLoops; + +struct timeoutstruct{ + unsigned long seconds; + unsigned long nanoseconds; + long allowedTimeouts; +}; + + +struct ScanOptions{ + string stagingMode; + string maskStages; + unsigned short nMaskStages; + unsigned short firstStage; + unsigned short stepStage; + octet nLoops; + unsigned long runNumber; + TriggerOptions trigOpt; + PixelScanFE feOpt; + ScanLoops scanLoop; + string scanType; + string receiver; + string dataHandler; + string dataProc; + string name; + timeoutstruct timeout; + StringList histos; +}; + +}; + +#endif diff --git a/rce/rcecalib/idl/constituents.mk b/rce/rcecalib/idl/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..8416544802d7ddbb7649a4a9cd392f974ee5950b --- /dev/null +++ b/rce/rcecalib/idl/constituents.mk @@ -0,0 +1,33 @@ + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := idl +endif +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + modlibnames := idl +endif + + +libsrcs_idl := ScanOptionsSK.cc \ + CallbackSK.cc \ + PixelModuleConfigSK.cc \ + PixelFEI4GenConfigSK.cc \ + PixelFEI4AConfigSK.cc \ + PixelFEI4BConfigSK.cc \ + HitbusModuleConfigSK.cc \ + AFPHPTDCModuleConfigSK.cc \ + IPCScanRootAdapterSK.cc \ + IPCFEI3AdapterSK.cc \ + IPCFEI4AAdapterSK.cc \ + IPCFEI4BAdapterSK.cc \ + IPCHitbusAdapterSK.cc \ + IPCAFPHPTDCAdapterSK.cc \ + IPCScanAdapterSK.cc \ + IPCConfigIFAdapterSK.cc + + + + +libincs_idl := $(ipc_include_path) \ + $(omniorb_include_path) + + diff --git a/rce/rcecalib/namespace_aliases.hh b/rce/rcecalib/namespace_aliases.hh new file mode 100644 index 0000000000000000000000000000000000000000..f84c5291d5fcf3387dde5af8787ec9d5c6327b65 --- /dev/null +++ b/rce/rcecalib/namespace_aliases.hh @@ -0,0 +1,61 @@ +#ifndef __NAMESPACE_ALIASES_H__ +#define __NAMESPACE_ALIASES_H__ +#ifdef RCE_V2 +namespace service { + namespace fci { + class Exception; + } + namespace debug { + + } + namespace dynalink { + class RunnableModule; + class Linker; + class LinkingError; + } +} + +namespace oldPpi{ + namespace pic { + class Pool; + class Tds; + class Params; + } + + + namespace net { + class ipAddress; + } + namespace pgp { + class Driver; + } +} + +/* define aliases to map new core 2.2 namespaces to core 1.4 */ +namespace RcePic=oldPpi::pic; +namespace RcePgp=oldPpi::pgp; +namespace RceSvc=service::fci; +namespace RceNet=oldPpi::net; +namespace RceDebug=service::debug; +namespace RCE { + namespace ELF=service::dynalink; + namespace Dynalink=service::dynalink; +} +#else +/* forward declaration for old core 1.4 */ +namespace RcePic { + class Pool; + class Tds; + class Params; +} +namespace RceNet { + class ipAddress; +} +namespace RcePgp { + class Driver; +} +namespace RceSvc { + class Exception; +} +#endif +#endif diff --git a/rce/rcecalib/packages.mk b/rce/rcecalib/packages.mk new file mode 100644 index 0000000000000000000000000000000000000000..235117dcc0e2dde5589ecf9c402b7ada16c87a2b --- /dev/null +++ b/rce/rcecalib/packages.mk @@ -0,0 +1,5 @@ +# List of packages (low level first) +#ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +packages := idl profiler util HW dataproc scanctrl config eudaq analysis server +#endif + diff --git a/rce/rcecalib/profiler/Makefile b/rce/rcecalib/profiler/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3cd076af001b27a1deb669dc2c604a7bd6326844 --- /dev/null +++ b/rce/rcecalib/profiler/Makefile @@ -0,0 +1,21 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +include $(RELEASE_DIR)/make/sw/rootcint.mk +endif diff --git a/rce/rcecalib/profiler/Profiler.cc b/rce/rcecalib/profiler/Profiler.cc new file mode 100644 index 0000000000000000000000000000000000000000..6477e14e3aad4f6d74a39d3b9fe2313a8b634ef4 --- /dev/null +++ b/rce/rcecalib/profiler/Profiler.cc @@ -0,0 +1,1221 @@ +#define __PROFILER_CONSOLIDATE_THREADS__ + +#define css_outline_color "#848484" +#define css_thread_style "background-color:#EEEEEE;margin-top:8px;" +#define css_title_row "<tr class=\"header\"><td class=\"left\">Function</td><td>Calls</td><td>MCycles</td><td>Avg</td><td>Self MCycles</td><td class=\"right\">Self Avg</td></tr>\n" +#define css_totals_row "<tr class=\"header\"><td class=\"left\">Function</td><td>Calls</td><td>Self MCycles</td><td class=\"right\">Self Avg</td></tr>\n" + +#if defined(_WIN32) + #define _CRT_SECURE_NO_WARNINGS + #define copystring _strdup + #include <windows.h> +#else + #define copystring strdup + #include <unistd.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <malloc.h> +#include <time.h> + +#include "Profiler.hh" + +#if defined(__ICC) || defined(__ICL) + #pragma warning( disable: 1684 ) // (size_t )name >> 5 + #pragma warning( disable: 1011 ) // missing return statement at end of non-void function +#endif + +#undef threadlocal + +#if defined(_MSC_VER) + #define YIELD() Sleep(0); + #define PRINTFU64() "%I64u" + #define PATHSLASH() '\\' + #define threadlocal __declspec(thread) + #define snprintf _snprintf + + #undef inline + #define inline __forceinline +#else + #include <sched.h> + #define YIELD() sched_yield(); + #define PRINTFU64() "%llu" + #define PATHSLASH() '/' + #define threadlocal __thread +#endif + +#if !defined(__PROFILER_SMP__) + #undef threadlocal + #define threadlocal +#endif + +namespace Profiler { + + #if defined(__PROFILER_SMP__) + #if defined(_MSC_VER) + + template< class type > + inline bool CAS( volatile type &ptr_, const type old_, const type new_ ) { + __asm { + mov eax, [old_] + mov edx, [new_] + mov ecx, [ptr_] + lock cmpxchg dword ptr [ecx], edx + sete al + } + } + + #elif defined(__GNUC__) || defined(__ICC) + + template< class type > + inline bool CAS( volatile type &ptr_, const type old_, const type new_ ) { + u8 ret; + __asm__ __volatile__ ( + " lock\n" + " cmpxchgl %2,%1\n" + " sete %0\n" + : "=q" (ret), "=m" (ptr_) + : "r" (new_), "m" (ptr_), "a" (old_) + : "memory" + ); + return ret; + } + + #else + #error Define a compare-and-swap / full memory barrier implementation! + #endif + + struct CASLock { + void Acquire() { while ( !CAS( mLock, u32(0), u32(1) ) ) YIELD() } + void Release() { while ( !CAS( mLock, u32(1), u32(0) ) ) YIELD() } + bool TryAcquire() { return CAS( mLock, u32(0), u32(1) ); } + bool TryRelease() { return CAS( mLock, u32(1), u32(0) ); } + u32 Value() const { return mLock; } + //protected: + volatile u32 mLock; + }; + #else + struct CASLock { + void Acquire() {} + void Release() {} + bool TryAcquire() { return false; } + bool TryRelease() { return false; } + u32 Value() const { return 0; } + u32 dummy; + }; + #endif + + u32 nextpow2( u32 x ) { + x |= ( x >> 1 ); + x |= ( x >> 2 ); + x |= ( x >> 4 ); + x |= ( x >> 8 ); + x |= ( x >> 16 ); + return ( x + 1 ); + } + + template< class type > + inline void zeroarray( type *array, size_t count ) { + memset( array, 0, count * sizeof( type ) ); + } + + template< class type > + inline type *makepointer( type *base, size_t byteoffset ) { + return (type *)((const char *)base + byteoffset); + } + + template< class type > + inline void swapitems( type &a, type &b ) { + type tmp = a; + a = b; + b = tmp; + } + + #undef min + #undef max + + template< class type > + inline const type &min( const type &a, const type &b ) { + return ( a < b ) ? a : b; + } + + template< class type > + inline const type &max( const type &a, const type &b ) { + return ( a < b ) ? b : a; + } + + /* + ============= + Buffer - Don't use for anything with a constructor/destructor. Doesn't shrink on popping + ============= + */ + + template< class type > + struct Buffer { + Buffer() : mBuffer(NULL), mAlloc(0), mItems(0) { Resize( 4 ); } + Buffer( u32 size ) : mBuffer(NULL), mAlloc(0), mItems(0) { Resize( size ); } + ~Buffer() { free( mBuffer ); } + + void Clear() { mItems = ( 0 ); } + type *Data() { return ( mBuffer ); } + void EnsureCapacity( u32 capacity ) { if ( capacity >= mAlloc ) Resize( capacity * 2 ); } + type *Last() { return ( &mBuffer[ mItems - 1 ] ); } + void Push( const type &item ) { EnsureCapacity( mItems + 1 ); mBuffer[ mItems++ ] = ( item ); } + type &Pop() { return ( mBuffer[ --mItems ] ); } + + void Resize( u32 newsize ) { + mAlloc = nextpow2( newsize ); + mBuffer = (type *)realloc( mBuffer, mAlloc * sizeof( type ) ); + } + + u32 Size() const { return mItems; } + + template< class Compare > + void Sort( Compare comp ) { + if ( mItems <= 1 ) + return; + + Buffer scratch( mItems ); + + // merge sort with scratch buffer + type *src = Data(), *dst = scratch.Data(); + for( u32 log = 2; log < mItems * 2; log *= 2 ) { + type *out = dst; + for( u32 i = 0; i < mItems; i += log ) { + u32 lo = i, lo2 = min( i + log / 2, mItems ); + u32 hi = lo2, hi2 = min( lo + log, mItems ); + while ( ( lo < lo2 ) && ( hi < hi2 ) ) + *out++ = ( comp( src[lo], src[hi] ) ) ? src[lo++] : src[hi++]; + while ( lo < lo2 ) *out++ = src[lo++]; + while ( hi < hi2 ) *out++ = src[hi++]; + } + + swapitems( src, dst ); + } + + if ( src != mBuffer ) + swapitems( mBuffer, scratch.mBuffer ); + } + + template< class Mapto > + void ForEachByRef( Mapto &mapto, u32 limit ) { + limit = ( limit < mItems ) ? limit : mItems; + u32 last = limit - 1; + for ( u32 i = 0; i < limit; ++i ) + mapto( mBuffer[ i ], i == last ); + } + + template< class Mapto > void ForEach( Mapto mapto, u32 limit ) { ForEachByRef( mapto, limit ); } + template< class Mapto > void ForEach( Mapto mapto ) { ForEachByRef( mapto, mItems ); } + + type &operator[] ( u32 index ) { return ( mBuffer[ index ] ); } + const type &operator[] ( u32 index ) const { return ( mBuffer[ index ] ); } + + protected: + type *mBuffer; + u32 mAlloc, mItems; + }; + + + /* + =================== + ColorRamp for HTML + =================== + */ +#ifdef ENABLE_HTML + struct ColorF { + ColorF() {} + ColorF( f32 r_, f32 g_, f32 b_ ) : r(r_), g(g_), b(b_) {} + f32 r, g, b; + }; + + struct ColorRamp { + struct Marker { + Marker() {} + Marker( const ColorF &color_, f32 value_ ) : color(color_), value(value_) {} + ColorF color; + f32 value; + }; + + ColorRamp() {} + + void clear() { + mColors.Clear(); + } + + const char *value( f32 pos ) const { + ColorF base(0, 0, 0); + u32 pre = 0, post = 0; + for ( pre = 0; pre < mColors.Size() - 1; pre++ ) + if ( mColors[pre+1].value >= pos ) + break; + post = pre + 1; + if ( ( pre < mColors.Size() ) && ( post < mColors.Size() ) ) { + const Marker &a = mColors[pre], &b = mColors[post]; + f32 dist = ( b.value - a.value ), posw = ( pos - a.value ), bw = ( posw / dist ), aw = 1 - bw; + base = ColorF( a.color.r * aw + b.color.r * bw, a.color.g * aw + b.color.g * bw, a.color.b * aw + b.color.b * bw ); + } + u8 r = u8(base.r * 255.0f), g = u8(base.g * 255.0f), b = u8(base.b * 255.0f); + static threadlocal char buffer[8][32], bufferon = 0; + sprintf( buffer[bufferon&7], "#%02x%02x%02x", r, g, b ); + return buffer[bufferon++&7]; + } + + ColorRamp &push( const ColorF &color, f32 value ) { mColors.Push( Marker( color, value ) ); return *this; } + + Buffer<Marker> mColors; + }; +#endif + /* + ============= + Caller + ============= + */ + + #pragma pack(push,1) + struct Caller { + struct foreach { + // Adds each Caller to the specified buckets + struct AddToNewBuckets { + AddToNewBuckets( Caller **buckets, u32 bucket_count ) : mBuckets(buckets), mBucketCount(bucket_count) {} + void operator()( Caller *item ) { + FindEmptyChildSlot( mBuckets, mBucketCount, item->mName ) = item; + } + Caller **mBuckets; + u32 mBucketCount; + }; + + + // Destructs a Caller + struct Deleter { + void operator()( Caller *item ) { + delete item; + } + }; + + // Merges a Caller with the root + struct Merger { + Merger( Caller *root ) : mRoot(root) {} + void addFrom( Caller *item ) { (*this)( item ); } + void operator()( Caller *item ) { + Caller *child = mRoot->FindOrCreate( item->GetName() ); + child->GetTimer() += item->GetTimer(); + child->SetParent( item->GetParent() ); + item->ForEachNonEmpty( Merger( child ) ); + } + Caller *mRoot; + }; + + // Prints a Caller + struct Printer { + Printer( u32 indent ) : mIndent(indent) { } + void operator()( Caller *item, bool islast ) const { + item->Print( mIndent, islast ); + } + u32 mIndent; + }; +#ifdef ENABLE_HTML + struct PrinterHtml { + PrinterHtml( FILE *f, u32 indent ) : mFile(f), mIndent(indent) { } + void operator()( Caller *item, bool islast ) const { + item->PrintHtml( mFile, mIndent, islast ); + } + FILE *mFile; + u32 mIndent; + }; +#endif + struct SoftReset { + void operator()( Caller *item ) { + item->GetTimer().SoftReset(); + item->ForEach( SoftReset() ); + } + }; + + // Sums Caller's ticks + struct SumTicks { + SumTicks() : sum(0) {} + void operator()( Caller *item ) { + sum += ( item->mTimer.ticks ); + } + u64 sum; + }; + + struct UpdateTopMaxStats { + UpdateTopMaxStats() { maxStats.reset(); } + void operator()( Caller *item, bool islast ) { + if ( !item->GetParent() ) + return; + maxStats.check( Max::Calls, item->mTimer.calls ); + maxStats.check( Max::Ms, Timer::ms( item->mTimer.ticks ) ); + maxStats.check( Max::Avg, item->mTimer.avgms() ); + } + }; + }; // foreach + + + struct compare { + struct Ticks { + bool operator()( const Caller *a, const Caller *b ) const { + return ( a->mTimer.ticks > b->mTimer.ticks ); + } + }; + + struct SelfTicks { + bool operator()( const Caller *a, const Caller *b ) const { + return ( ( a->mTimer.ticks - a->mChildTicks ) > ( b->mTimer.ticks - b->mChildTicks ) ); + } + }; + + struct Calls { + bool operator()( const Caller *a, const Caller *b ) const { + return ( a->mTimer.calls > b->mTimer.calls ); + } + }; + }; // sort + + + /* + Since Caller.mTimer.ticks is inclusive of all children, summing the first level + children of a Caller to Caller.mChildTicks is an accurate total of the complete + child tree. + + mTotals is used to keep track of total ticks by Caller excluding children + */ + struct ComputeChildTicks { + ComputeChildTicks( Caller &totals ) : mTotals(totals) { maxStats.reset(); } + void operator()( Caller *item ) { + foreach::SumTicks sumchildren; + item->ForEachByRefNonEmpty( sumchildren ); + item->mChildTicks = ( sumchildren.sum ); + + u64 selfticks = ( item->mTimer.ticks >= item->mChildTicks ) ? ( item->mTimer.ticks - item->mChildTicks ) : 0; + Caller &totalitem = ( *mTotals.FindOrCreate( item->mName ) ); + totalitem.mTimer.ticks += selfticks; + totalitem.mTimer.calls += item->mTimer.calls; + totalitem.SetParent( item->GetParent() ); + + // don't include the root node in the max stats + if ( item->GetParent() ) { + maxStats.check( Max::SelfMs, Timer::ms( selfticks ) ); + maxStats.check( Max::Calls, item->mTimer.calls ); + maxStats.check( Max::Ms, Timer::ms( item->mTimer.ticks ) ); + maxStats.check( Max::Avg, item->mTimer.avgms() ); + maxStats.check( Max::SelfAvg, average( Timer::ms( selfticks ), item->mTimer.calls ) ); + } + + // compute child ticks for all children of children of this caller + item->ForEachByRefNonEmpty( *this ); + } + Caller &mTotals; + }; + + /* + Format a Caller's information. ComputeChildTicks will need to be used on the Root + to generate mChildTicks for all Callers + */ + struct Format { + Format( const char *prefix ) : mPrefix(prefix) {} + void operator()( Caller *item, bool islast ) const { + u64 ticks = item->mTimer.ticks; + f64 ms = Timer::ms( ticks ); + printf( "%s "PRINTFF64(".2")" mcycles, %d calls, "PRINTFF64(".0")" cycles avg, "PRINTFF64(".2")"%%: %s\n", + mPrefix, ms, item->mTimer.calls, item->mTimer.avg(), average( ticks * 100, mGlobalDuration ), item->mName ); + } + const char *mPrefix; + }; +#ifdef ENABLE_HTML + struct FormatHtml { + FormatHtml( FILE *f, Buffer<const char *> &prefix ) : mFile(f), mPrefix(prefix) {} + void operator()( Caller *item ) const { + fprintf( mFile, "\t<tr %s><td><table class=\"tree\"><tr>", !item->GetParent() ? "style=\"" css_thread_style "\"": "class=\"h\"" ); + for ( u32 i = 0; i < mPrefix.Size(); i++ ) + fprintf( mFile, "<td><img src=\"%s\" /></td>", mPrefix[i] ); + u64 ticks = item->mTimer.ticks; + f64 ms = Timer::ms( ticks ), globalpct = average( ticks * 100, mGlobalDuration ); + f64 childms = Timer::ms( item->mChildTicks ), selfms = ( ms - childms ), avg = item->mTimer.avgms(), selfavg = average( selfms, item->mTimer.calls ); + if ( !item->GetParent() ) + fprintf( mFile, "<td class=\"text\">%s</td></tr></table></td><td class=\"number\">%u</td><td class=\"number\">"PRINTFF64("0.4")" ("PRINTFF64("3.0")"%%)</td><td class=\"number\">"PRINTFF64("0.4")"</td><td class=\"number\">"PRINTFF64("0.4")"</td><td class=\"number\">"PRINTFF64("0.4")"</td></tr>\n", + item->mName, + item->mTimer.calls, + ms, + globalpct, + avg, + selfms, + selfavg + ); + else + fprintf( mFile, "<td class=\"text\">%s</td></tr></table></td><td class=\"number\" style=\"background-color:%s\">%u</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")" ("PRINTFF64("0.3")"%%)</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")"</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")"</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")"</td></tr>\n", + item->mName, + maxStats.color( Max::Calls, item->mTimer.calls ), item->mTimer.calls, + maxStats.color( Max::Ms, ms ), ms, + globalpct, + maxStats.color( Max::Avg, avg ), avg, + maxStats.color( Max::SelfMs, selfms ), selfms, + maxStats.color( Max::SelfAvg, selfavg ), selfavg + ); + } + FILE *mFile; + Buffer<const char *> &mPrefix; + }; + + struct FormatHtmlTop { + FormatHtmlTop( FILE *f ) : mFile(f) {} + void operator()( Caller *item, bool islast ) const { + fprintf( mFile, "\t<tr %s><td><table class=\"tree\"><tr>", !item->GetParent() ? "style=\"" css_thread_style "\"": "class=\"h\"" ); + fprintf( mFile, "<td><img src=\"%s\" /></td>", islast ? "img/last-empty.gif" : "img/empty.gif" ); + u64 ticks = item->mTimer.ticks; + f64 ms = Timer::ms( ticks ), globalpct = average( ticks * 100, mGlobalDuration ), avg = item->mTimer.avgms(); + if ( !item->GetParent() ) { + fprintf( mFile, "<td class=\"text\">%s</td></tr></table></td><td class=\"number\">%u</td><td class=\"number\">"PRINTFF64("0.4f")" ("PRINTFF64(".0")"%%)</td><td class=\"number\">"PRINTFF64(".4")"</td></tr>\n", + item->mName, + item->mTimer.calls, + ms, + globalpct, + avg + ); + } else { + fprintf( mFile, "<td class=\"text\">%s</td></tr></table></td><td class=\"number\" style=\"background-color:%s\">%u</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")" ("PRINTFF64("0")"%%)</td><td class=\"number\" style=\"background-color:%s\">"PRINTFF64("0.4")"</td></tr>\n", + item->mName, + maxStats.color( Max::Calls, item->mTimer.calls ), item->mTimer.calls, + maxStats.color( Max::Ms, ms ), ms, + globalpct, + maxStats.color( Max::Avg, avg ), avg + ); + } + } + FILE *mFile; + }; +#endif + /* + Methods + */ + + // we're guaranteed to be null because of calloc. ONLY create Callers with "new"! + Caller( const char *name, Caller *parent = NULL ) { + mName = name; + mParent = parent; + Resize( 2 ); // mBuckets must always exist and mBucketCount >= 2! + } + + ~Caller() { + ForEach( foreach::Deleter() ); + free( mBuckets ); + } + + void CopyToListNonEmpty( Buffer<Caller *> &list ) { + list.Clear(); + + for ( u32 i = 0; i < mBucketCount; ++i ) + if ( mBuckets[ i ] && !mBuckets[ i ]->GetTimer().IsEmpty() ) + list.Push( mBuckets[ i ] ); + } + + inline Caller *FindOrCreate( const char *name ) { + u32 index = ( GetBucket( name, mBucketCount ) ), mask = ( mBucketCount - 1 ); + for ( Caller *caller = mBuckets[index]; caller; caller = mBuckets[index & mask] ) { + if ( caller->mName == name ) + return caller; + + index = ( index + 1 ); + } + + // didn't find the caller, lock this thread and mutate + AcquirePerThreadLock(); + EnsureCapacity( ++mNumChildren ); + Caller *&slot = FindEmptyChildSlot( mBuckets, mBucketCount, name ); + slot = new Caller( name, this ); + ReleasePerThreadLock(); + return slot; + } + + template< class Mapto > + void ForEachByRef( Mapto &mapto ) { + for ( u32 i = 0; i < mBucketCount; ++i ) + if ( mBuckets[ i ] ) + mapto( mBuckets[ i ] ); + } + + template< class Mapto > + void ForEachByRefNonEmpty( Mapto &mapto ) { + for ( u32 i = 0; i < mBucketCount; ++i ) + if ( mBuckets[ i ] && !mBuckets[ i ]->GetTimer().IsEmpty() ) + mapto( mBuckets[ i ] ); + } + + template< class Mapto > + void ForEach( Mapto mapto ) { + ForEachByRef( mapto ); + } + + template< class Mapto > + void ForEachNonEmpty( Mapto mapto ) { + ForEachByRefNonEmpty( mapto ); + } + + inline Caller *GetParent() { + return mParent; + } + + Timer &GetTimer() { + return mTimer; + } + + const char *GetName() const { + return mName; + } + + bool IsActive() const { + return mActive; + } + + void Print( u32 indent = 0, bool islast = false ) { + Buffer<Caller *> children( mNumChildren ); + CopyToListNonEmpty( children ); + + mFormatter.EnsureCapacity( indent + 3 ); + char *fmt = ( &mFormatter[indent] ); + + if ( indent ) { + fmt[-2] = ( islast ) ? ' ' : '|'; + fmt[-1] = ( islast ) ? '\\' : ' '; + } + fmt[0] = ( children.Size() ) ? '+' : '-'; + fmt[1] = ( '-' ); + fmt[2] = ( 0 ); + + Format(mFormatter.Data())( this, islast ); + + if ( indent && islast ) + fmt[-2] = fmt[-1] = ' '; + + if ( children.Size() ) { + children.Sort( compare::Ticks() ); + children.ForEach( foreach::Printer(indent+2) ); + } + } +#ifdef ENABLE_HTML + void PrintHtml( FILE *f, u32 indent = 0, bool islast = false ) { + Buffer<Caller *> children( mNumChildren ); + CopyToListNonEmpty( children ); + + if ( !indent ) { + mHTMLFormatter.Push( "img/root.gif" ); + } else if ( children.Size() ) { + mHTMLFormatter.Push( ( ( islast ) || ( children.Size() == 1 ) ) ? "img/last-child-open.gif" : "img/open.gif" ); + } else { + mHTMLFormatter.Push( ( islast ) ? "img/last-empty.gif" : "img/empty.gif" ); + } + + FormatHtml(f, mHTMLFormatter)( this ); + + mHTMLFormatter[indent] = ( islast || !indent ) ? "img/blank.gif" : "img/vertical.gif"; + + if ( children.Size() ) { + children.Sort( compare::Ticks() ); + children.ForEach( foreach::PrinterHtml(f,indent+1) ); + } + + mHTMLFormatter.Pop(); + } +#endif + void PrintTopStats( u32 nitems ) { + nitems = ( nitems > mNumChildren ) ? mNumChildren : nitems; + printf( "\ntop %d functions (self time)\n", (u32 )nitems ); + Buffer<Caller *> sorted( mNumChildren ); + CopyToListNonEmpty( sorted ); + sorted.Sort( compare::SelfTicks() ); + sorted.ForEach( Format(">"), nitems ); + } + + void Resize( u32 new_size ) { + new_size = ( new_size < mBucketCount ) ? mBucketCount << 1 : nextpow2( new_size - 1 ); + Caller **new_buckets = (Caller **)calloc( new_size, sizeof( Caller* ) ); + ForEach( foreach::AddToNewBuckets( new_buckets, new_size ) ); + + free( mBuckets ); + mBuckets = ( new_buckets ); + mBucketCount = ( new_size ); + } + + void Reset() { + ForEach( foreach::Deleter() ); + zeroarray( mBuckets, mBucketCount ); + mNumChildren = ( 0 ); + mTimer.Reset(); + } + + void SetActive( bool active ) { + mActive = active; + } + + void SetParent( Caller *parent ) { + mParent = parent; + } + + void SoftReset() { + mTimer.SoftReset(); + ForEach( foreach::SoftReset() ); + } + + void Start() { + mTimer.Start(); + } + + void Stop() { + mTimer.Stop(); + } + + void *operator new ( size_t size ) { + return calloc( size, 1 ); + } + + void operator delete ( void *p ) { + free( p ); + } + + + /* Acquire the caller lock for this thread */ + + inline static void AcquirePerThreadLock() { +#if defined(__PROFILER_SMP__) + if ( thisThread.requireThreadLock ) + thisThread.threadLock.Acquire(); +#endif + } + + inline static void ReleasePerThreadLock() { +#if defined(__PROFILER_SMP__) + if ( thisThread.requireThreadLock ) + thisThread.threadLock.Release(); +#endif + } + + protected: + static inline Caller *&FindEmptyChildSlot( Caller **buckets, u32 bucket_count, const char *name ) { + u32 index = ( GetBucket( name, bucket_count ) ), mask = ( bucket_count - 1 ); + Caller **caller = &buckets[index]; + for ( ; *caller; caller = &buckets[index & mask] ) + index = ( index + 1 ); + return *caller; + } + + inline static u32 GetBucket( const char *name, u32 bucket_count ) { + return u32( ( ( (size_t )name >> 5 ) /* * 2654435761 */ ) & ( bucket_count - 1 ) ); + } + + inline void EnsureCapacity( u32 capacity ) { + if ( capacity < ( mBucketCount / 2 ) ) + return; + Resize( capacity ); + } + + protected: + const char *mName; + Timer mTimer; + u32 mBucketCount, mNumChildren; + Caller **mBuckets, *mParent; + + bool mActive; + u64 mChildTicks; + + public: + // caller + static Buffer<char> mFormatter; +#ifdef ENABLE_HTML + static Buffer<const char *> mHTMLFormatter; + static ColorRamp mColors; +#endif + // global + static f64 mTimerOverhead, mRdtscOverhead; + static u64 mGlobalDuration; + static struct Max { + enum f64Enum { SelfMs = 0, Ms, Avg, SelfAvg, f64Enums }; + enum u64Enum { Calls = 0, TotalCalls, u64Enums }; + + void reset() { + memset( this, 0, sizeof( *this ) ); + } + + void check( u64Enum e, u64 u ) { if ( u64fields[e] < u ) u64fields[e] = u; if ( e == Calls ) u64fields[TotalCalls] += u; } + void check( f64Enum e, f64 f ) { if ( f64fields[e] < f ) f64fields[e] = f; } +#ifdef ENABLE_HTML + const char *color( u64Enum e, u64 u ) const { return mColors.value( f32(f64(u)/f64(u64fields[e])) ); } + const char *color( f64Enum e, f64 f ) const { return mColors.value( f32(f/f64fields[e]) ); } +#endif + const u64 &operator() ( u64Enum e ) const { return u64fields[e]; } + const f64 &operator() ( f64Enum e ) const { return f64fields[e]; } + + protected: + u64 u64fields[u64Enums]; + f64 f64fields[f64Enums]; + } maxStats; + + // per thread state + struct ThreadState { + CASLock threadLock; + bool requireThreadLock; + Caller *activeCaller; + }; + + static threadlocal ThreadState thisThread; + }; + #pragma pack(pop) + + + + + + +#if defined(__PROFILER_ENABLED__) + threadlocal Caller::ThreadState Caller::thisThread = { {0}, 0, 0 }; + f64 Caller::mTimerOverhead = 0, Caller::mRdtscOverhead = 0; + u64 Caller::mGlobalDuration = 0; + Caller::Max Caller::maxStats; + Buffer<char> Caller::mFormatter( 64 ); +#ifdef ENABLE_HTML + Buffer<const char *> Caller::mHTMLFormatter( 64 ); + ColorRamp Caller::mColors; +#endif + char *programName = NULL, *commandLine = NULL; + + void detectByArgs( int argc, const char *argv[] ) { + const char *path = argv[0], *finalSlash = path, *iter = path; + for ( ; *iter; ++iter ) + finalSlash = ( *iter == PATHSLASH() ) ? iter + 1 : finalSlash; + if ( !*finalSlash ) + finalSlash = path; + programName = copystring( finalSlash ); + + size_t width = 0; + for ( int i = 1; i < argc; i++ ) { + size_t len = strlen( argv[i] ); + commandLine = (char *)realloc( commandLine, width + len + 1 ); + memcpy( commandLine + width, argv[i], len ); + commandLine[width + len] = ' '; + width += len + 1; + } + if ( width ) + commandLine[width - 1] = '\x0'; + } + + void detectWinMain( const char *cmdLine ) { +#if defined(_MSC_VER) + char path[1024], *finalSlash = path, *iter = path; + GetModuleFileName( NULL, path, 1023 ); + for ( ; *iter; ++iter ) + finalSlash = ( *iter == PATHSLASH() ) ? iter + 1 : finalSlash; + if ( !*finalSlash ) + finalSlash = path; + programName = copystring( finalSlash ); + commandLine = copystring( cmdLine ); +#else + programName = copystring( "only_for_win32" ); + commandLine = copystring( "" ); +#endif + } + + /* + ============ + Root - Holds the root caller and the thread state for a thread + ============ + */ + + struct Root { + Root( Caller *caller, Caller::ThreadState *ts ) : root(caller), threadState(ts) {} + Caller *root; + Caller::ThreadState *threadState; + }; + + struct GlobalThreadList { + ~GlobalThreadList() { + if ( list ) { + Buffer<Root> &threadsref = *list; + u32 cnt = threadsref.Size(); + for ( u32 i = 0; i < cnt; i++ ) + delete threadsref[i].root; + } + delete list; + } + + void AcquireGlobalLock() { + threadsLock.Acquire(); + if ( !list ) + list = new Buffer<Root>; + } + + void ReleaseGlobalLock() { + threadsLock.Release(); + } + + Buffer<Root> *list; + CASLock threadsLock; + }; + + u64 globalStart = Timer::getticks(); + GlobalThreadList threads = { NULL, {0} }; + threadlocal Caller *root = NULL; + + + /* + Thread Dumping + */ + + struct PrintfDumper { + void Init() { + } + + void GlobalInfo( u64 rawCycles ) { + printf( "> Raw run time "PRINTFF64(".2")" mcycles\n", Timer::ms( rawCycles ) ); + } + + void ThreadsInfo( u64 totalCalls, f64 timerOverhead, f64 rdtscOverhead ) { + printf( "> Total calls " PRINTFU64() ", per call overhead "PRINTFF64(".0")" cycles, rdtsc overhead "PRINTFF64(".0")" cycles, estimated overhead "PRINTFF64(".2")" mcycles\n\n", + totalCalls, timerOverhead, rdtscOverhead, Timer::ms( timerOverhead * totalCalls ) ); + } + + void PrintThread( Caller *root ) { + root->Print(); + printf( "\n\n" ); + } + + void PrintAccumulated( Caller *accumulated ) { + accumulated->PrintTopStats( 50 ); + } + + void Finish() { + } + }; +#ifdef ENABLE_HTML + struct HTMLDumper { + void Init() { + Caller::mColors.clear(); + Caller::mColors.push( ColorF( 255.0f/255.0f, 255.0f/255.0f, 255.0f/255.0f ), 0.00f ); + //Caller::mColors.push( ColorF( 255.0f/255.0f, 212.0f/255.0f, 129.0f/255.0f ), 0.50f ); + Caller::mColors.push( ColorF( 255.0f/255.0f, 203.0f/255.0f, 203.0f/255.0f ), 0.20f ); + Caller::mColors.push( ColorF( 255.0f/255.0f, 128.0f/255.0f, 128.0f/255.0f ), 1.00f ); + + time_t now; + time( &now ); + tm *now_tm = localtime( &now ); + strftime( timeFormat, 255, "%Y%m%d_%H%M%S", now_tm ); + snprintf( fileFormat, 255, "%s-profile-%s.html", programName ? programName : "no-info-given", timeFormat ); + strftime( timeFormat, 255, "%#c", now_tm ); + f = fopen( fileFormat, "wb+" ); + + Caller::mHTMLFormatter.Clear(); + fputs( + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" + "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" class=\"\">\n" + "<head>\n" + " <style type=\"text/css\">\n" + " body {font-family: arial;font-size: 11px;}\n" + " table {padding: 0px;margin: 0px;border-spacing: 0pt 0pt;}\n" + " table.tree td {padding: 0px; margin: 0px;}\n" + " tr {padding: 0px;margin: 0px;}\n" + " tr.h:hover {background-color: #EEEEEE; color:blue;}\n" + " tr.header {background-image: url(img/tile.gif); background-position: left bottom; background-repeat: repeat-x; height: 24px;}\n" + " tr.header td { padding-left: 8px; padding-right:8px; border-right:1px solid " css_outline_color "; border-top:1px solid " css_outline_color "; }\n" + " tr.header td.left { border-left:1px solid " css_outline_color "; }\n" + " tr.header td.right { border-right:1px solid " css_outline_color "; }\n" + " tr.spacer {height: 24px;}\n" + " td {padding: 0px;padding-left:3px;padding-right:3px;margin: 0px;}\n" + " td.text {text-align: left;}\n" + " td.number {text-align: right;}\n" + " div.overall { background-color: #F0F0F0; width: 98%; color: #A31212; font-size: 16px; padding: 5px; padding-left: 20px; margin-bottom: 15px; }\n" + " div.thread { margin-bottom: 15px; }\n" + " div.overall td.title { padding-left: 10px; font-weight: bold; }\n" + " </style>\n" + "</head>\n" + "<body>\n\n", + f + ); + } + + void GlobalInfo( u64 rawCycles ) { + fputs( "<div class=\"overall\"><table>", f ); + if ( programName ) { + fprintf( f, "<tr><td class=\"title\">Command Line: </td><td>%s", programName ); + if ( commandLine ) + fprintf( f, " %s", commandLine ); + fputs( "</td></tr>", f ); + } + fprintf( f, "<tr><td class=\"title\">Date: </td><td>%s</td></tr><tr><td class=\"title\">Raw run time: </td><td>"PRINTFF64(".2")" mcycles</td></tr>\n", + timeFormat, Timer::ms( rawCycles ) ); + } + + void ThreadsInfo( u64 totalCalls, f64 timerOverhead, f64 rdtscOverhead ) { + fprintf( f, "<tr><td class=\"title\">Total calls: </td><td>" PRINTFU64() "</td></tr>\n", totalCalls ); + fprintf( f, "<tr><td class=\"title\">rdtsc overhead: </td><td>"PRINTFF64(".2")" cycles</td></tr>\n", rdtscOverhead ); + fprintf( f, "<tr><td class=\"title\">Per call overhead: </td><td>"PRINTFF64(".0")" cycles</td></tr>\n", timerOverhead ); + fprintf( f, "<tr><td class=\"title\">Estimated overhead: </td><td>"PRINTFF64(".4")" mcycles</td></tr>\n", Timer::ms( totalCalls * timerOverhead ) ); + fprintf( f, "</table></div>\n" ); + } + + void PrintThread( Caller *root ) { + fputs( "<div class=\"thread\"><table>\n", f ); + fputs( css_title_row, f ); + root->PrintHtml( f ); + fputs( "</table></div>\n", f ); + } + + void PrintAccumulated( Caller *accumulated ) { + fputs( "<div class=\"thread\"><table>\n", f ); + fputs( css_totals_row, f ); + fputs( "<tr style=\"" css_thread_style "\"><td><table><tr><td><img src=\"img/root.gif\" /></td><td>Functions sorted by self time</td></tr></table></td><td></td><td></td><td></td></tr>\n", f ); + Buffer<Caller *> sorted; + accumulated->CopyToListNonEmpty( sorted ); + sorted.ForEach( Caller::foreach::UpdateTopMaxStats() ); + sorted.Sort( Caller::compare::SelfTicks() ); + sorted.ForEach( Caller::FormatHtmlTop(f) ); + fputs( "</table></div>\n", f ); + } + + void Finish() { + fputs( "</div>\n", f ); + fputs( "</body></html>", f ); + fclose( f ); + } + + protected: + FILE *f; + char timeFormat[256], fileFormat[256]; + }; +#endif + + template< class Dumper > + void dumpThreads( Dumper dumper ) { + u64 rawDuration = ( Timer::getticks() - globalStart ); + + Caller *accumulate = new Caller( "/Top Callers" ), *packer = new Caller( "/Thread Packer" ); + Buffer<Caller *> packedThreads; + + dumper.Init(); + dumper.GlobalInfo( rawDuration ); + + threads.AcquireGlobalLock(); + + // crawl the list of theads and store their data in to packer + Buffer<Root> &threadsref = *threads.list; + for ( u32 i = 0; i < threadsref.Size(); i++ ) { + Root &thread = threadsref[i]; + + // if the thread is no longer active, the lock won't be valid + bool active = ( thread.root->IsActive() ); + if ( active ) { + thread.threadState->threadLock.Acquire(); + // disable requiring our local lock in case the caller is in our thread, accumulate will try to set it otherwise + Caller::thisThread.requireThreadLock = false; + for ( Caller *walk = thread.threadState->activeCaller; walk; walk = walk->GetParent() ) + walk->GetTimer().SoftStop(); + } + +#if defined(__PROFILER_CONSOLIDATE_THREADS__) + // merge the thread into the packer object, will result in 1 caller per thread name, not 1 caller per thread instance + Caller::foreach::Merger( packer ).addFrom( thread.root ); + Caller *child = packer->FindOrCreate( thread.root->GetName() ); + + // add the child to the list of threads to dump (use the active flag to indicate if it's been added) + if ( !child->IsActive() ) { + packedThreads.Push( child ); + child->SetActive( true ); + } +#else + // create a dummy entry for each thread (fake a name with the address of the thread root) + Caller *stub = packer->FindOrCreate( (const char *)thread.root ); + Caller::foreach::Merger( stub ).addFrom( thread.root ); + Caller *stubroot = stub->FindOrCreate( thread.root->GetName() ); + stubroot->SetParent( NULL ); // for proper crawling + packedThreads.Push( stubroot ); +#endif + + if ( active ) { + Caller::thisThread.requireThreadLock = true; + thread.threadState->threadLock.Release(); + } + } + + // working on local data now, don't need the threads lock any more + threads.ReleaseGlobalLock(); + + // do the pre-computations on the gathered threads + Caller::ComputeChildTicks preprocessor( *accumulate ); + for ( u32 i = 0; i < packedThreads.Size(); i++ ) + preprocessor( packedThreads[i] ); + + dumper.ThreadsInfo( Caller::maxStats( Caller::Max::TotalCalls ), Caller::mTimerOverhead, Caller::mRdtscOverhead ); + + // print the gathered threads + u64 sumTicks = 0; + for ( u32 i = 0; i < packedThreads.Size(); i++ ) { + Caller *root = packedThreads[i]; + u64 threadTicks = root->GetTimer().ticks; + sumTicks += threadTicks; + Caller::mGlobalDuration = threadTicks; + dumper.PrintThread( root ); + } + + // print the totals, use the summed total of ticks to adjust percentages + Caller::mGlobalDuration = sumTicks; + dumper.PrintAccumulated( accumulate ); + dumper.Finish(); + + delete accumulate; + delete packer; + } + + void resetThreads() { + globalStart = Timer::getticks(); + +#if defined(__PROFILER_SMP__) + threads.AcquireGlobalLock(); + + Buffer<Root> &threadsref = *threads.list; + u32 cnt = threadsref.Size(), last = cnt - 1; + for ( u32 i = 0; i < cnt; i++ ) { + Root &thread = threadsref[i]; + if ( !thread.root->IsActive() ) { + // thread isn't active, remove it + delete thread.root; + Root removed = threadsref.Pop(); + if ( i != last ) + thread = removed; + last--; + cnt--; + i--; + } else { + thread.threadState->threadLock.Acquire(); + thread.root->SoftReset(); + thread.threadState->threadLock.Release(); + } + } + + threads.ReleaseGlobalLock(); +#else + if ( root ) + root->SoftReset(); +#endif + } + + void enterThread( const char *name ) { + Caller *tmp = new Caller( name ); + + threads.AcquireGlobalLock(); + threads.list->Push( Root( tmp, &Caller::thisThread ) ); + + Caller::AcquirePerThreadLock(); + Caller::thisThread.activeCaller = tmp; + tmp->Start(); + tmp->SetActive( true ); + root = tmp; + Caller::ReleasePerThreadLock(); + + threads.ReleaseGlobalLock(); + } + + void exitThread() { + threads.AcquireGlobalLock(); + + Caller::AcquirePerThreadLock(); + root->Stop(); + root->SetActive( false ); + Caller::thisThread.activeCaller = NULL; + Caller::ReleasePerThreadLock(); + + threads.ReleaseGlobalLock(); + } + + inline void fastcall enterCaller( const char *name ) { + Caller *parent = Caller::thisThread.activeCaller; + if ( !parent ) + return; + + Caller *active = parent->FindOrCreate( name ); + active->Start(); + Caller::thisThread.activeCaller = active; + } + + inline void exitCaller() { + Caller *active = Caller::thisThread.activeCaller; + if ( !active ) + return; + + active->Stop(); + Caller::thisThread.activeCaller = active->GetParent(); + } + + inline void pauseCaller() { + u64 curticks = Timer::getticks(); + Caller *iter = Caller::thisThread.activeCaller; + for ( ; iter; iter = iter->GetParent() ) + iter->GetTimer().Pause( curticks ); + } + + inline void unpauseCaller() { + u64 curticks = Timer::getticks(); + Caller *iter = Caller::thisThread.activeCaller; + for ( ; iter; iter = iter->GetParent() ) + iter->GetTimer().Unpause( curticks ); + } + + // enter the main thread automatically + struct MakeRoot { + MakeRoot() { + // get an idea of how long timer calls / rdtsc takes + const u32 reps = 1000; + Caller::mTimerOverhead = Caller::mRdtscOverhead = 1000000; + for ( u32 tries = 0; tries < 20; tries++ ) { + Timer t, t2; + t.Start(); + for ( u32 i = 0; i < reps; i++ ) { + t2.Start(); + t2.Stop(); + } + t.Stop(); + f64 avg = f64(t2.ticks)/f64(reps); + if ( avg < Caller::mRdtscOverhead ) + Caller::mRdtscOverhead = avg; + avg = f64(t.ticks)/f64(reps); + if ( avg < Caller::mTimerOverhead ) + Caller::mTimerOverhead = avg; + } + + enterThread( "/Main" ); + } + + ~MakeRoot() { + free( programName ); + free( commandLine ); + } + } makeRoot; + + void detect( int argc, const char *argv[] ) { detectByArgs( argc, argv ); } + void detect( const char *commandLine ) { detectWinMain( commandLine ); } + void dump() { dumpThreads( PrintfDumper() ); } +#ifdef ENABLE_HTML + void dumphtml() { dumpThreads( HTMLDumper() ); } +#else + void dumphtml() {}; +#endif + void fastcall enter( const char *name ) { enterCaller( name ); } + void fastcall exit() { exitCaller(); } + void fastcall pause() { pauseCaller(); } + void fastcall unpause() { unpauseCaller(); } + void threadenter( const char *name ) { enterThread( name ); } + void threadexit() { exitThread(); } + void reset() { resetThreads(); } +#else + void detect( int argc, const char *argv[] ) {} + void detect( const char *commandLine ) {} + void dump() {} + void dumphtml() {} + void fastcall enter( const char *name ) {} + void fastcall exit() {} + void fastcall pause() {} + void fastcall unpause() {} + void threadenter( const char *name ) {} + void threadexit() {} + void reset() {} +#endif + +}; // namespace Profiler diff --git a/rce/rcecalib/profiler/Profiler.hh b/rce/rcecalib/profiler/Profiler.hh new file mode 100644 index 0000000000000000000000000000000000000000..26e463c647c21dee49c979cd59ed4da8c57bc48e --- /dev/null +++ b/rce/rcecalib/profiler/Profiler.hh @@ -0,0 +1,258 @@ +#ifndef __PROFILER_H__ +#define __PROFILER_H__ + +#include <iostream> + +//#define __PROFILER_ENABLED__ +#define __PROFILER_FULL_TYPE_EXPANSION__ + +#undef noinline +#undef fastcall + +#if ! defined(__rtems__) || ! defined(__PPC__) +#define __PROFILER_SMP__ +#endif +#if !defined(NO_FLOAT) && defined(__PPC__) +#define NO_FLOAT +#endif + + +#if defined(_MSC_VER) + #undef __PRETTY_FUNCTION__ + #define __PRETTY_FUNCTION__ __FUNCSIG__ + #define PROFILE_CONCAT( a, b ) a "/" b + + #define noinline __declspec(noinline) + #define fastcall __fastcall +#else + #define PROFILE_CONCAT( a, b ) b + + #define noinline __attribute__ ((noinline)) + #define fastcall +#endif + +#if defined(__PROFILER_FULL_TYPE_EXPANSION__) + #define PROFILE_FUNCTION() __PRETTY_FUNCTION__ +#else + #define PROFILE_FUNCTION() __FUNCTION__ +#endif + +#if defined(__PROFILER_ENABLED__) + // thread + #define PROFILE_THREAD_START_RAW( text ) Profiler::threadenter( text ) + #define PROFILE_THREAD_START() PROFILE_THREAD_START_RAW( PROFILE_FUNCTION() ) + #define PROFILE_THREAD_START_DESC( desc ) PROFILE_THREAD_START_RAW( PROFILE_CONCAT( PROFILE_FUNCTION(), desc ) ) + + #define PROFILE_THREAD_SCOPED_RAW( text ) Profiler::ScopedThread profiler##__LINE__ ( text ) + #define PROFILE_THREAD_SCOPED() PROFILE_THREAD_SCOPED_RAW( PROFILE_FUNCTION() ) + #define PROFILE_THREAD_SCOPED_DESC( desc ) PROFILE_THREAD_SCOPED_RAW( PROFILE_CONCAT( PROFILE_FUNCTION(), desc ) ) + + #define PROFILE_THREAD_STOP() Profiler::threadexit() + + // function + #define PROFILE_PAUSE() Profiler::pause() + #define PROFILE_UNPAUSE() Profiler::unpause() + #define PROFILE_PAUSE_SCOPED() Profiler::ScopedPause profilerpause##__LINE__ + + #define PROFILE_START_RAW( text ) Profiler::enter( text ); + #define PROFILE_START() PROFILE_START_RAW( PROFILE_FUNCTION() ) + #define PROFILE_START_DESC( desc ) PROFILE_START_RAW( PROFILE_CONCAT( PROFILE_FUNCTION(), desc ) ) + + #define PROFILE_SCOPED_RAW( text ) Profiler::Scoped profiler##__LINE__ ( text ) + #define PROFILE_SCOPED() PROFILE_SCOPED_RAW( PROFILE_FUNCTION() ) + #define PROFILE_SCOPED_DESC( desc ) PROFILE_SCOPED_RAW( PROFILE_CONCAT( PROFILE_FUNCTION(), desc ) ) + + #define PROFILE_STOP() Profiler::exit() + #define PROFILE_RESET() Profiler::reset() + #define PROFILE_DUMP() Profiler::dump() +#else + #define PROFILE_THREAD_START_RAW( text ) + #define PROFILE_THREAD_START() + #define PROFILE_THREAD_START_DESC( desc ) + + #define PROFILE_THREAD_SCOPED_RAW( text ) + #define PROFILE_THREAD_SCOPED() + #define PROFILE_THREAD_SCOPED_DESC( desc ) + + #define PROFILE_THREAD_STOP() + + #define PROFILE_PAUSE() + #define PROFILE_UNPAUSE() + #define PROFILE_PAUSE_SCOPED() + + #define PROFILE_START_RAW( text ) + #define PROFILE_START() + #define PROFILE_START_DESC( desc ) + + #define PROFILE_SCOPED_RAW( text ) + #define PROFILE_SCOPED() + #define PROFILE_SCOPED_DESC( desc ) + + #define PROFILE_STOP() + #define PROFILE_RESET() + #define PROFILE_DUMP() +#endif + +namespace Profiler { + /* + ============= + Types that won't conflict with the rest of the system + ============= + */ + + + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; + #if defined(_MSC_VER) + typedef unsigned __int64 u64; + #else + typedef unsigned long long u64; + #endif +#ifdef NO_FLOAT + typedef u64 f64; + #define MCYCLE 1 + #define PRINTFF64(x) "%lld" +#else + typedef double f64; + #define MCYCLE 1000000.0 + #define PRINTFF64(x) "%" x "f" +#endif + + template< class type1, class type2 > + f64 average( type1 sum, type2 count ) { + return ( count ) ? f64(sum)/f64(count) : 0; + } + + /* + ============= + Timer + ============= + */ + #pragma pack(push,1) + struct Timer { + Timer() { Reset(); } + void Print(const char* title){ + std::cout<<"Timing for module "<<title<<std::endl; + std::cout<<"Timer recorded a total of "<<calls<<" calls and "<<ticks<<" ticks."<<" or "<<(float)ticks/350000<<" milliseconds"<<std::endl; + //std::cout<<"Timer recorded a total of "<<calls<<" calls and "<<ticks<<" ticks."<<std::endl; + std::cout<<"The average number of ticks was "<<avg()<<" or "<<(float)avg()/350000.<<" milliseconds."<<std::endl; + //std::cout<<"The average number of ticks was "<<avg()<<" or "<<(float)(unsigned)avg()/350000.<<" milliseconds."<<std::endl; + } + inline bool IsEmpty() const { return ticks == 0; } + inline bool IsPaused() const { return paused; } + inline void Unpause( u64 curticks ) { started = curticks; paused = false; } + inline void Unpause() { Unpause( getticks() ); } + inline void Pause( u64 curticks ) { ticks += ( curticks - started ); paused = true; } + inline void Pause() { Pause( getticks() ); } + inline void Start() { ++calls; started = getticks(); } + inline void Stop() { ticks += ( getticks() - started ); } + inline void Reset() { ticks = started = calls = 0; paused = false; } + inline void SoftStop() { if ( !paused ) { u64 t = getticks(); ticks += ( t - started ); started = t; } } + inline void SoftReset() { ticks = 0; calls = 1; started = getticks(); } + + template< class type > static f64 ms( const type &t ) { return f64( t ) / MCYCLE; } + f64 millicycles() { return ms( ticks ); } + f64 currentmillicycles() { return ms( ticks + ( getticks() - started ) ); } + f64 avg() { return average( ticks, calls ); } + f64 avgms() { return ms( average( ticks, calls ) ); } + + void operator+= ( const Timer &b ) { + ticks += b.ticks; + calls += b.calls; + } + + static inline u64 getticks_serial() { + #if defined(__i386__) || defined(__x86_64__) + #if defined(__GNUC__) + asm volatile("cpuid" : : : "%eax", "%ebx", "%ecx", "%edx" ); + #else + __asm cpuid; + #endif + return getticks(); + #endif + return getticks(); + } + #if defined(__i386__) || defined(__x86_64__) + #if defined(__GNUC__) + static inline u64 getticks() { + u32 __a,__d; + asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); + return ( u64(__a) | u64(__d) << 32 ); + } + #elif defined(__ICC) || defined(__ICL) + static inline u64 getticks() { return _rdtsc(); } + #else + static inline u64 getticks() { __asm { rdtsc }; } + #endif + #elif defined(__PPC__) + static inline u64 getticks() { + union {struct { u32 upper,lower;}; u64 U64;} result; + u32 upper0,upper1; +// read time base registers + __asm__ volatile("\ + mfspr %[upper0], 269 \n \ + mfspr %[lower] , 268 \n \ + mfspr %[upper1], 269 " + : [lower] "=r" (result.lower), // result.lower is output. + [upper0] "=r" (upper0), // upper0 is output. + [upper1] "=r" (upper1) // upper1 is output. + ); + u32 mask = (int) result.lower >> 31; + result.upper = upper1 ^ ((upper0 ^ upper1) & mask); + return result.U64; + } + #else + #error Unsupported CPU Architecture + #endif + + u64 ticks, started; + u32 calls; + bool paused; + }; + #pragma pack(pop) + + + /* + ============= + Interface functions + ============= + */ + + void detect( int argc, const char *argv[] ); + void detect( const char *commandLine ); + void dump(); + void dumphtml(); + void fastcall enter( const char *name ); + void fastcall exit(); + void fastcall pause(); + void fastcall unpause(); + void threadenter( const char *name ); + void threadexit(); + void reset(); + + struct Scoped { + Scoped( const char *name ) { PROFILE_START_RAW( name ); } + ~Scoped() { PROFILE_STOP(); } + }; + + struct ScopedPause { + ScopedPause() { PROFILE_PAUSE(); } + ~ScopedPause() { PROFILE_UNPAUSE(); } + }; + + struct ScopedThread { + ScopedThread( const char *name ) { PROFILE_THREAD_START_RAW( name ); } + ~ScopedThread() { PROFILE_THREAD_STOP(); } + }; +}; // namespace Profiler + + +struct ScopedTimer { + ScopedTimer( Profiler::Timer &t ) : mTimer(t) { mTimer.Start(); } + ~ScopedTimer() { mTimer.Stop(); } +protected: + Profiler::Timer &mTimer; +}; + +#endif // __PROFILER_H__ diff --git a/rce/rcecalib/profiler/README b/rce/rcecalib/profiler/README new file mode 100644 index 0000000000000000000000000000000000000000..172fe55bd33c6577ce4de0cc2689327db6b890e8 --- /dev/null +++ b/rce/rcecalib/profiler/README @@ -0,0 +1,64 @@ +---- +INFO +---- + +My site: http://www.team5150.com/~andrew/ +Project site: http://code.google.com/p/high-performance-cplusplus-profiler/ + + +------------ +WHAT IS THIS +------------ + +A high performance multi-threaded C++ profiler, currently for x86 (32bit) +under Windows and Linux. + + +---------- +QUICKSTART +---------- + +Add Profiler.cpp to your project, and #include "Profiler.h" to any file +you wish to profile. + +(OPTIONAL) +Call Profiler::detect( argc, argv ) under any OS or +Profiler::detect( commandLine ) under Win32 non-console apps to autodetect +program name and startup parameters (only used for html dumps). + +Use PROFILE_SCOPED() at the start of any function you wish to profile. + +Use PROFILE_THREAD_SCOPED() at the entry point of any thread you wish to +profile. The main thread is instantiated automatically. + +Use Profiler::reset(); to reset the profile stats at any time + +Use Profiler::dump(); to generate an ASCII report of the current profile + +Use Profiler::dumphtml(); to generate an HTML report of the current profile +to the current directory. + + +--------------- +Minimal Example +--------------- + +#include <stdlib.h> +#include "Profiler.h" + +int test() { + PROFILE_SCOPED() + + int i = 1; + while ( i < 1000 ) + i *= ( rand() & 7 ) + 1; + return i; +} + +int main( int argc, const char *argv[] ) { + Profiler::detect( argc, argv ); + for ( int i = 0; i < 100; i++ ) + test(); + Profiler::dump(); + return 0; +} diff --git a/rce/rcecalib/profiler/constituents.mk b/rce/rcecalib/profiler/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..b5b8b028b0629ea777af1adcb23ccaaa35e9219e --- /dev/null +++ b/rce/rcecalib/profiler/constituents.mk @@ -0,0 +1,13 @@ + +CPPFLAGS+='-D__PROFILER_ENABLED__' + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +modlibnames := profiler +libsrcs_profiler := Profiler.cc +endif + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := profiler +libsrcs_profiler := Profiler.cc +endif + diff --git a/rce/rcecalib/projects.mk.template b/rce/rcecalib/projects.mk.template new file mode 100644 index 0000000000000000000000000000000000000000..110d0f705d32fea7172dc59d77ed4ab022e0a29e --- /dev/null +++ b/rce/rcecalib/projects.mk.template @@ -0,0 +1,34 @@ +# List of projects (low level first) +projects := rtems \ + boost \ + omniorb \ + tdaq \ + root \ + rce \ + rceusr \ + rceapp \ + rceers \ + rceowl \ + rceipc \ + rceis \ + rceoh \ + rcecalib + + + +rtems_use := /reg/common/package/rtems/4.9.2 + +rce_use := release +rceusr_use := release +rceapp_use := release +rcehw_use := release +rceowl_use := release +rceers_use := release +rceipc_use := release +rceis_use := release +rceoh_use := release +rcecalib_use := release +root_use := /reg/g/atlas/root_5_22_00b +boost_use := /reg/g/atlas/boost_1_41_0 +omniorb_use := /reg/g/atlas/omniorb +tdaq_use := /reg/g/atlas/tdaq diff --git a/rce/rcecalib/scanctrl/AbsScan.hh b/rce/rcecalib/scanctrl/AbsScan.hh new file mode 100644 index 0000000000000000000000000000000000000000..ce5b0830bc5ace5c061048c21f76683ff7fa9505 --- /dev/null +++ b/rce/rcecalib/scanctrl/AbsScan.hh @@ -0,0 +1,29 @@ +#ifndef ABSSCAN_HH +#define ABSSCAN_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include <iostream> +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/config/ConfigIF.hh" + +class AbsDataProcessor; + +class AbsScan{ + +public: + AbsScan(ConfigIF* cif): m_configIF(cif){}; + virtual ~AbsScan(){} + virtual int configureScan(boost::property_tree::ptree* scanOptions)=0; + virtual int pause()=0; + virtual int resume()=0; + virtual int abort()=0; + virtual int startScan()=0; + //virtual std::vector<Histo*> getHistos(const char* type, int module)=0; + +protected: + ConfigIF* m_configIF; + //AbsDataProcessor* m_dataprocessor; + NestedLoop m_loops; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/ActionFactory.cc b/rce/rcecalib/scanctrl/ActionFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..94c77027991d96f8fda5ac9e742200bc7a3c29eb --- /dev/null +++ b/rce/rcecalib/scanctrl/ActionFactory.cc @@ -0,0 +1,90 @@ + +#include "rcecalib/scanctrl/ActionFactory.hh" + +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/scanctrl/Scan.hh" + + +// Loop actions +#include "rcecalib/scanctrl/SetupMaskStageAction.hh" +#include "rcecalib/scanctrl/SetupParamAction.hh" +#include "rcecalib/scanctrl/ChangeBinAction.hh" +#include "rcecalib/scanctrl/SendTriggerAction.hh" +#include "rcecalib/scanctrl/EnableTriggerAction.hh" +#include "rcecalib/scanctrl/DisableTriggerAction.hh" +#include "rcecalib/scanctrl/DisableAllChannelsAction.hh" +#include "rcecalib/scanctrl/ConfigureModulesAction.hh" +#include "rcecalib/scanctrl/ConfigureModulesNEAction.hh" +#include "rcecalib/scanctrl/CosmicSetInputDelayAction.hh" +#include "rcecalib/scanctrl/CosmicEnableTDCAction.hh" +#include "rcecalib/scanctrl/SetupTriggerAction.hh" +#include "rcecalib/scanctrl/CosmicEnableScintillatorTriggerAction.hh" +#include "rcecalib/scanctrl/PauseAction.hh" +#include "rcecalib/scanctrl/IfWaitAction.hh" +#include "rcecalib/scanctrl/SetChannelMaskAction.hh" + +// End of loop actions +#include "rcecalib/scanctrl/FitEoLAction.hh" +#include "rcecalib/scanctrl/CloseFileEoLAction.hh" +#include "rcecalib/scanctrl/DisableTriggerEoLAction.hh" +#include "rcecalib/scanctrl/DisableAllChannelsEoLAction.hh" +#include "rcecalib/scanctrl/ResetFEEoLAction.hh" + +LoopAction* ActionFactory::createLoopAction(std::string action, boost::property_tree::ptree* pt){ + // create various loop actions based on action string + if(action=="SETUP_MASK") + return new SetupMaskStageAction(action,m_configIF,m_dataProc, pt); + else if (action=="SETUP_PARAM") + return new SetupParamAction(action,m_configIF, pt); + else if (action=="CHANGE_BIN") + return new ChangeBinAction(action,m_dataProc); + else if (action == "SEND_TRIGGER") + return new SendTriggerAction(action,m_configIF); + else if (action == "SETUP_CHANNELMASK") + return new SetChannelMaskAction(action,m_configIF); + else if (action == "DISABLE_ALL_CHANNELS") + return new DisableAllChannelsAction(action,m_configIF); + else if (action == "CONFIGURE_MODULES") + return new ConfigureModulesAction(action,m_configIF); + else if (action == "CONFIGURE_MODULES_NO_ENABLE") + return new ConfigureModulesNEAction(action,m_configIF); + else if (action == "ENABLE_TRIGGER") + return new EnableTriggerAction(action,m_configIF); + else if (action == "DISABLE_TRIGGER") + return new DisableTriggerAction(action,m_configIF); + else if (action == "PAUSE") + return new PauseAction(action,m_scan); + else if (action == "COSMIC_SET_INPUT_DELAY") + return new CosmicSetInputDelayAction(action,m_configIF,pt); + else if (action == "COSMIC_ENABLE_TDC") + return new CosmicEnableTDCAction(action,m_configIF); + else if (action == "COSMIC_ENABLE_SCINTILLATOR_TRIGGER") + return new CosmicEnableScintillatorTriggerAction(action,m_configIF); + else if (action == "SETUP_TRIGGER") + return new SetupTriggerAction(action,m_configIF, pt); + else if (action == "IF_WAIT") + return new IfWaitAction(action); + else{ + std::cerr<<"Unknown Action"<<std::endl; + return 0; + } +} + +EndOfLoopAction* ActionFactory::createEndOfLoopAction(std::string action, std::string fitfunc){ + if(action=="FIT") + return new FitEoLAction(action,m_dataProc,fitfunc); + if(action=="CALCULATE_MEAN_SIGMA") + return new FitEoLAction(action,m_dataProc,fitfunc); + if(action=="CLOSE_FILE") + return new CloseFileEoLAction(action,m_dataProc); + if(action=="DISABLE_TRIGGER") + return new DisableTriggerEoLAction(action,m_configIF); + if(action=="DISABLE_ALL_CHANNELS") + return new DisableAllChannelsEoLAction(action,m_configIF); + if(action=="RESET_FE") + return new ResetFEEoLAction(action,m_configIF); + else if(action=="NO_ACTION") + return 0; + else return 0; +} diff --git a/rce/rcecalib/scanctrl/ActionFactory.hh b/rce/rcecalib/scanctrl/ActionFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..fe34b0dce1f1b116cb75b00e674a69d8c0280cfe --- /dev/null +++ b/rce/rcecalib/scanctrl/ActionFactory.hh @@ -0,0 +1,26 @@ +#ifndef ACTIONFACTORY_HH +#define ACTIONFACTORY_HH + +#include <string> +#include <boost/property_tree/ptree_fwd.hpp> + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" + +class Scan; +class ConfigIF; +class AbsDataProc; + +class ActionFactory{ +public: + ActionFactory(ConfigIF* cif, AbsDataProc* proc,Scan* scan): + m_configIF(cif),m_dataProc(proc),m_scan(scan){} + ~ActionFactory(){}; + LoopAction* createLoopAction(std::string action,boost::property_tree::ptree* pt=0); + EndOfLoopAction* createEndOfLoopAction(std::string action, std::string fitfunc); +private: + ConfigIF *m_configIF; + AbsDataProc *m_dataProc; + Scan* m_scan; +}; +#endif diff --git a/rce/rcecalib/scanctrl/ChangeBinAction.hh b/rce/rcecalib/scanctrl/ChangeBinAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..1b2f999b660e77273b4f3358e4a8a017be83a861 --- /dev/null +++ b/rce/rcecalib/scanctrl/ChangeBinAction.hh @@ -0,0 +1,19 @@ +#ifndef CHANGEBINACTION_HH +#define CHANGEBINACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" + +class ChangeBinAction: public LoopAction{ +public: + ChangeBinAction(std::string name, AbsDataProc* proc): + LoopAction(name),m_dataProc(proc){} + int execute(int i){ + //std::cout<<"Changed bin"<<std::endl; + return m_dataProc->changeBin(i); + } +private: + AbsDataProc* m_dataProc; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/CloseFileEoLAction.hh b/rce/rcecalib/scanctrl/CloseFileEoLAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..6d80f0b996fa31686c3680a9b86085d4ad081a96 --- /dev/null +++ b/rce/rcecalib/scanctrl/CloseFileEoLAction.hh @@ -0,0 +1,19 @@ +#ifndef CLOSEFILEEOLACTION_HH +#define CLOSEFILEEOLACTION_HH + +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" + +class CloseFileEoLAction: public EndOfLoopAction{ +public: + CloseFileEoLAction(std::string name, AbsDataProc* proc): + EndOfLoopAction(name),m_dataProc(proc){} + int execute(){ + std::cout<<"Closing file"<<std::endl; + return m_dataProc->fit("CloseFile"); + } +private: + AbsDataProc* m_dataProc; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/ConfigureModulesAction.hh b/rce/rcecalib/scanctrl/ConfigureModulesAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..62c019d79f3a2931210b84d10625f87f53cb77ac --- /dev/null +++ b/rce/rcecalib/scanctrl/ConfigureModulesAction.hh @@ -0,0 +1,19 @@ +#ifndef CONFIGUREMODULESACTION_HH +#define CONFIGUREMODULESACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class ConfigureModulesAction: public LoopAction{ +public: + ConfigureModulesAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + m_configIF->configureModulesHW(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/ConfigureModulesNEAction.hh b/rce/rcecalib/scanctrl/ConfigureModulesNEAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..8863ca4e8447a5f1a71aacd392bb65894ecd3d93 --- /dev/null +++ b/rce/rcecalib/scanctrl/ConfigureModulesNEAction.hh @@ -0,0 +1,19 @@ +#ifndef CONFIGUREMODULESNEACTION_HH +#define CONFIGUREMODULESNEACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class ConfigureModulesNEAction: public LoopAction{ +public: + ConfigureModulesNEAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + m_configIF->configureModulesHW(false); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/CosmicDataSetup.cc b/rce/rcecalib/scanctrl/CosmicDataSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..e1b2f98fa2d8e282d016e9376565b7d83c1569f2 --- /dev/null +++ b/rce/rcecalib/scanctrl/CosmicDataSetup.cc @@ -0,0 +1,45 @@ +#include "rcecalib/scanctrl/CosmicDataSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +int CosmicDataSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Data Taking has a single loop with one entry + ScanLoop *scanloop=new ScanLoop("data",1); + LoopAction* conf=af->createLoopAction("CONFIGURE_MODULES"); + scanloop->addLoopAction(conf); + LoopAction* linkmask=af->createLoopAction("SETUP_TRIGGER", scanOptions); + scanloop->addLoopAction(linkmask); + LoopAction* enabletdc=0; + if(scanOptions->get<int>("trigOpt.triggerDataOn")){ + enabletdc=af->createLoopAction("COSMIC_ENABLE_TDC"); + scanloop->addLoopAction(enabletdc); + } + LoopAction* enable=af->createLoopAction("ENABLE_TRIGGER"); + scanloop->addLoopAction(enable); + // End of loop actions + EndOfLoopAction* disabletrigger=af->createEndOfLoopAction("DISABLE_TRIGGER",""); + scanloop->addEndOfLoopAction(disabletrigger); + EndOfLoopAction* closefile=af->createEndOfLoopAction("CLOSE_FILE",""); + scanloop->addEndOfLoopAction(closefile); + EndOfLoopAction* resetfe=af->createEndOfLoopAction("RESET_FE",""); + scanloop->addEndOfLoopAction(resetfe); + EndOfLoopAction* disablechannels=af->createEndOfLoopAction("DISABLE_ALL_CHANNELS",""); + scanloop->addEndOfLoopAction(disablechannels); + // loop is the nested loop object + loop.addNewInnermostLoop(scanloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/CosmicDataSetup.hh b/rce/rcecalib/scanctrl/CosmicDataSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..d00bfd0a2aa67d8e84c2be074ca914a66eea905a --- /dev/null +++ b/rce/rcecalib/scanctrl/CosmicDataSetup.hh @@ -0,0 +1,18 @@ +#ifndef COSMICDATASETUP_HH +#define COSMICDATASETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class CosmicDataSetup: public LoopSetup{ +public: + CosmicDataSetup():LoopSetup(){}; + virtual ~CosmicDataSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/CosmicEnableScintillatorTriggerAction.hh b/rce/rcecalib/scanctrl/CosmicEnableScintillatorTriggerAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..94ee756e3105cefe02f24f7bbafaf6b740e5fbee --- /dev/null +++ b/rce/rcecalib/scanctrl/CosmicEnableScintillatorTriggerAction.hh @@ -0,0 +1,21 @@ +#ifndef COSMICENABLESCINTILLATORTRIGGER_HH +#define COSMICENABLESCINTILLATORTRIGGER_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class CosmicEnableScintillatorTriggerAction: public LoopAction{ +public: + CosmicEnableScintillatorTriggerAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + unsigned serstat= m_configIF->writeHWregister(11,1); + assert(serstat==0); + // std::cout<<"Enabled scintillator trigger"<<std::endl; + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/CosmicEnableTDCAction.hh b/rce/rcecalib/scanctrl/CosmicEnableTDCAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..766d2b0022a07ae50ae6128196091cf60130fe71 --- /dev/null +++ b/rce/rcecalib/scanctrl/CosmicEnableTDCAction.hh @@ -0,0 +1,20 @@ +#ifndef COSMICENABLETDC_HH +#define COSMICENABLETDC_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class CosmicEnableTDCAction: public LoopAction{ +public: + CosmicEnableTDCAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + unsigned serstat= m_configIF->writeHWregister(4,1); + assert(serstat==0); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/CosmicSetInputDelayAction.hh b/rce/rcecalib/scanctrl/CosmicSetInputDelayAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..1ba8b0adbc6f48514f5c4a50138bf4b8124a4dc3 --- /dev/null +++ b/rce/rcecalib/scanctrl/CosmicSetInputDelayAction.hh @@ -0,0 +1,51 @@ +#ifndef COSMICSETINPUTDELAYACTION_HH +#define COSMICSETINPUTDELAYACTION_HH + +#include <boost/property_tree/ptree.hpp> +#include <boost/foreach.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <string> +#include <vector> + +class CosmicSetInputDelayAction: public LoopAction{ +public: + CosmicSetInputDelayAction(std::string name, ConfigIF* cif, boost::property_tree::ptree *pt ): + LoopAction(name),m_configIF(cif){ + try{ + int nPoints=pt->get<int>("nPoints"); + BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt->get_child("dataPoints")){ + ERS_DEBUG(2, v.second.data()); + int data = boost::lexical_cast<int>(v.second.data()); + dataPoints.push_back(data); + } + ERS_ASSERT_MSG((int)dataPoints.size()==nPoints,"of an inconsistency in the number of scan points."); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + } + + int execute(int i){ + ERS_DEBUG(2,"CosmicSetInputDelayAction "<<i); + //std::cout<<"Set input delay "<<i<<std::endl; + unsigned serstat; + serstat=m_configIF->writeHWregister(7,0);//reset delays + assert(serstat==0); + int reg=5; + if(dataPoints[i]<0)reg=6; + for (int j=0;j<abs(dataPoints[i]);j++) { + serstat=m_configIF->writeHWregister(reg,0); //increment delay + assert(serstat==0); + } + return 0; + } + +private: + ConfigIF* m_configIF; + std::vector<int> dataPoints; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/DelayScanSetup.cc b/rce/rcecalib/scanctrl/DelayScanSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..91396868c55a7902656308c282c02de184804fbf --- /dev/null +++ b/rce/rcecalib/scanctrl/DelayScanSetup.cc @@ -0,0 +1,43 @@ +#include "rcecalib/scanctrl/DelayScanSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +int DelayScanSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // This calibration has a single loop + int nPoints = scanOptions->get<int>("scanLoop_0.nPoints"); + ScanLoop *scanloop=new ScanLoop("scanLoop_0",nPoints); + LoopAction* disable=af->createLoopAction("DISABLE_TRIGGER"); + scanloop->addLoopAction(disable); + LoopAction* setdelay=af->createLoopAction("COSMIC_SET_INPUT_DELAY",&scanOptions->get_child("scanLoop_0")); + scanloop->addLoopAction(setdelay); + LoopAction* changebin=af->createLoopAction("CHANGE_BIN"); + scanloop->addLoopAction(changebin); + LoopAction* enabletdc=af->createLoopAction("COSMIC_ENABLE_TDC"); + scanloop->addLoopAction(enabletdc); + LoopAction* enablesc=af->createLoopAction("COSMIC_ENABLE_SCINTILLATOR_TRIGGER"); + scanloop->addLoopAction(enablesc); + LoopAction* enable=af->createLoopAction("ENABLE_TRIGGER"); + scanloop->addLoopAction(enable); + // End of loop actions + EndOfLoopAction* disabletrigger=af->createEndOfLoopAction("DISABLE_TRIGGER",""); + scanloop->addEndOfLoopAction(disabletrigger); + EndOfLoopAction* disablechannels=af->createEndOfLoopAction("DISABLE_ALL_CHANNELS",""); + scanloop->addEndOfLoopAction(disablechannels); + // loop is the nested loop object + loop.addNewInnermostLoop(scanloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/DelayScanSetup.hh b/rce/rcecalib/scanctrl/DelayScanSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..3a910a13f08d1d24f26a52acc13271bbe40dd6d1 --- /dev/null +++ b/rce/rcecalib/scanctrl/DelayScanSetup.hh @@ -0,0 +1,18 @@ +#ifndef DELAYSCANSETUP_HH +#define DELAYSCANSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class DelayScanSetup: public LoopSetup{ +public: + DelayScanSetup():LoopSetup(){}; + virtual ~DelayScanSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/DisableAllChannelsAction.hh b/rce/rcecalib/scanctrl/DisableAllChannelsAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..a9ef168152f3ce4c6b44b339a803bbbf1f4b201c --- /dev/null +++ b/rce/rcecalib/scanctrl/DisableAllChannelsAction.hh @@ -0,0 +1,19 @@ +#ifndef DISABLEALLCHANNELSACTION_HH +#define DISABLEALLCHANNELSACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class DisableAllChannelsAction: public LoopAction{ +public: + DisableAllChannelsAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + m_configIF->disableAllChannels(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/DisableAllChannelsEoLAction.hh b/rce/rcecalib/scanctrl/DisableAllChannelsEoLAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..b27cd1868fb47170aaaf364c5ae9d65e401cb176 --- /dev/null +++ b/rce/rcecalib/scanctrl/DisableAllChannelsEoLAction.hh @@ -0,0 +1,19 @@ +#ifndef DISABLEALLCHANNELSEOLACTION_HH +#define DISABLEALLCHANNELSEOLACTION_HH + +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class DisableAllChannelsEoLAction: public EndOfLoopAction{ +public: + DisableAllChannelsEoLAction(std::string name, ConfigIF* cif) : + EndOfLoopAction(name),m_configIF(cif){} + int execute(){ + m_configIF->disableAllChannels(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/DisableTriggerAction.hh b/rce/rcecalib/scanctrl/DisableTriggerAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..ccdcb5f77ca124b26b65d102e0b42185f1046629 --- /dev/null +++ b/rce/rcecalib/scanctrl/DisableTriggerAction.hh @@ -0,0 +1,19 @@ +#ifndef DISABLETRIGGERACTION_HH +#define DISABLETRIGGERACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class DisableTriggerAction: public LoopAction{ +public: + DisableTriggerAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + //std::cout<<"Disabled trigger"<<std::endl; + return m_configIF->disableTrigger(); + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/DisableTriggerEoLAction.hh b/rce/rcecalib/scanctrl/DisableTriggerEoLAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..aee14eaed0e72f628ed045a3f7d331b9c007e761 --- /dev/null +++ b/rce/rcecalib/scanctrl/DisableTriggerEoLAction.hh @@ -0,0 +1,20 @@ +#ifndef DISABLETRIGGEREOLACTION_HH +#define DISABLETRIGGEREOLACTION_HH + +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class DisableTriggerEoLAction: public EndOfLoopAction{ +public: + DisableTriggerEoLAction(std::string name, ConfigIF* cif) : + EndOfLoopAction(name),m_configIF(cif){} + int execute(){ + std::cout<<"Disabling trigger"<<std::endl; + m_configIF->disableTrigger(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/EnableTriggerAction.hh b/rce/rcecalib/scanctrl/EnableTriggerAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..9be093ff8348c477b04354018bd37f718def30b4 --- /dev/null +++ b/rce/rcecalib/scanctrl/EnableTriggerAction.hh @@ -0,0 +1,20 @@ +#ifndef ENABLETRIGGERACTION_HH +#define ENABLETRIGGERACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class EnableTriggerAction: public LoopAction{ +public: + EnableTriggerAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + m_configIF->sendHWcommand(17); // tell HSIO trigger logic that this RCE is in control. + m_configIF->enableTrigger(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/EndOfLoopAction.hh b/rce/rcecalib/scanctrl/EndOfLoopAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..92d80eb7282e209551ad12a7d8e293cdadb9b85f --- /dev/null +++ b/rce/rcecalib/scanctrl/EndOfLoopAction.hh @@ -0,0 +1,17 @@ +#ifndef ENDOFLOOPACTION_HH +#define ENDOFLOOPACTION_HH + +#include <string> + +class EndOfLoopAction{ +public: + EndOfLoopAction(std::string name): + m_name(name){} + virtual ~EndOfLoopAction(){} + std::string name(){return m_name;} + virtual int execute() = 0; +protected: + std::string m_name; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/FitEoLAction.hh b/rce/rcecalib/scanctrl/FitEoLAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..8946b9622277417bf74b602878fe40d29cb518c7 --- /dev/null +++ b/rce/rcecalib/scanctrl/FitEoLAction.hh @@ -0,0 +1,27 @@ +#ifndef SCANFITACTION_HH +#define SCANFITACTION_HH + +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/scanctrl/RceCallback.hh" + +class FitEoLAction: public EndOfLoopAction{ +public: + FitEoLAction(std::string name, AbsDataProc* proc, std::string fitfunc): + EndOfLoopAction(name),m_dataProc(proc),m_fitfunc(fitfunc){} + int execute(){ + ipc::CallbackParams cbp; + cbp.rce=RceName::getRceNumber(); + cbp.status=ipc::FITTING; + cbp.maskStage=-1; + cbp.loop0=-1; + cbp.loop1=-1; + RceCallback::instance()->sendMsg(ipc::HIGH,&cbp); + return m_dataProc->fit(m_fitfunc); + } +private: + AbsDataProc* m_dataProc; + std::string m_fitfunc; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/IPCScan.cc b/rce/rcecalib/scanctrl/IPCScan.cc new file mode 100644 index 0000000000000000000000000000000000000000..a506e4d6cddd164863334e8bd88e62d6c47028db --- /dev/null +++ b/rce/rcecalib/scanctrl/IPCScan.cc @@ -0,0 +1,99 @@ +#ifndef IPCSCAN_CC +#define IPCSCAN_CC + +#include "rcecalib/scanctrl/IPCScan.hh" +#include "ers/ers.h" +#include "ipc/partition.h" +#include <boost/property_tree/ptree.hpp> + +#include <string> +#include <iostream> +#include "rcecalib/profiler/Profiler.hh" + +template <class TP> +void* IPCScan<TP>::startScanStatic(void* arg){ + ((IPCScan<TP>*)arg)->startScan(); + return 0; +} + +template <class TP> +IPCScan<TP>::IPCScan(IPCPartition & p, const char * name): + IPCNamedObject<POA_ipc::IPCScanAdapter, TP>( p, name ) , + Scan() { + + try { + IPCNamedObject<POA_ipc::IPCScanAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + + + +template <class TP> +IPCScan<TP>::~IPCScan(){ + try { + IPCNamedObject<POA_ipc::IPCScanAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +void IPCScan<TP>::IPCpause(){ + std::cout<<"Pause"<<std::endl; + pause(); +} +template <class TP> +void IPCScan<TP>::IPCresume(){ + std::cout<<"Resume"<<std::endl; + resume(); +} +template <class TP> +void IPCScan<TP>::IPCabort(){ + std::cout<<"Abort"<<std::endl; + abort(); +} +template <class TP> +void IPCScan<TP>::IPCstartScan(){ + pthread_t mthread; + pthread_attr_t attr; + int ret; + // setting a new size + int stacksize = (PTHREAD_STACK_MIN + 0x20000); + pthread_attr_init(&attr); + ret=pthread_attr_setstacksize(&attr, stacksize); + pthread_create( &mthread, &attr , startScanStatic, this); + pthread_detach(mthread); + //startScan(); +} +template <class TP> +void IPCScan<TP>::IPCwaitForData(){ + waitForData(); +} +template <class TP> +void IPCScan<TP>::IPCstopWaiting(){ + stopWaiting(); +} +template <class TP> +CORBA::Long IPCScan<TP>::IPCgetStatus(){ + return getStatus(); +} + +template <class TP> +void IPCScan<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/rcecalib/scanctrl/IPCScan.hh b/rce/rcecalib/scanctrl/IPCScan.hh new file mode 100644 index 0000000000000000000000000000000000000000..060fc210ce77e7869e2949227cf93e74d5fb3c05 --- /dev/null +++ b/rce/rcecalib/scanctrl/IPCScan.hh @@ -0,0 +1,29 @@ +#ifndef IPCSCAN_HH +#define IPCSCAN_HH + +#include "rcecalib/scanctrl/Scan.hh" +#include "ipc/object.h" +#include "ScanOptions.hh" +#include "IPCScanAdapter.hh" + +class IPCPartition; + +template <class TP = ipc::single_thread> +class IPCScan: public IPCNamedObject<POA_ipc::IPCScanAdapter,TP>, public Scan { +public: + IPCScan(IPCPartition & p, const char * name); + ~IPCScan(); + void IPCpause(); + void IPCresume(); + void IPCwaitForData(); + void IPCstopWaiting(); + void IPCabort(); + void IPCstartScan(); + CORBA::Long IPCgetStatus(); + void shutdown(); + static void *startScanStatic(void *arg); + +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/IPCScanRoot.cc b/rce/rcecalib/scanctrl/IPCScanRoot.cc new file mode 100644 index 0000000000000000000000000000000000000000..6694922d2a0c303072bd300937f92bb457af4a1b --- /dev/null +++ b/rce/rcecalib/scanctrl/IPCScanRoot.cc @@ -0,0 +1,184 @@ +#ifndef IPCSCANROOT_CC +#define IPCSCANROOT_CC + +#include "rcecalib/scanctrl/IPCScanRoot.hh" +#include "ers/ers.h" +#include "ipc/partition.h" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/AbsReceiver.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/scanctrl/Scan.hh" +#include "rcecalib/util/IPCHistoManager.hh" +#include "rcecalib/scanctrl/RceCallback.hh" + +#include <string> +#include <iostream> + + +template <class TP> +IPCScanRoot<TP>::IPCScanRoot(IPCPartition & p, const char * name, ConfigIF* cif, Scan* scan): + IPCNamedObject<POA_ipc::IPCScanRootAdapter, TP>( p, name ) , ScanRoot(cif,scan){ + try { + IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>::publish(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } +} + +template <class TP> +IPCScanRoot<TP>::~IPCScanRoot(){ + try { + IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>::withdraw(); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::warning( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } +} + +template <class TP> +CORBA::Long IPCScanRoot<TP>::IPCconfigureScan(const ipc::ScanOptions &options){ + //PixScan::dump(options); + //std::cout<<"Start IPCScanRoot "<<std::endl; + //convert struct into property tree + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + //Top level + pt->put("Name",options.name); // scan name. Can be used as a file name, for example. + pt->put("scanType",options.scanType); // scan type. Determines what loop setup to use + pt->put("Receiver",options.receiver); + pt->put("DataHandler",options.dataHandler); + pt->put("DataProc",options.dataProc); + pt->put("Timeout.Seconds",options.timeout.seconds); + pt->put("Timeout.Nanoseconds",options.timeout.nanoseconds); + pt->put("Timeout.AllowedTimeouts",options.timeout.allowedTimeouts); + pt->put("runNumber", options.runNumber); + pt->put("stagingMode",options.stagingMode); + //maskStages is not used in NewDsp, only nMaskStages + pt->put("maskStages", options.maskStages); + pt->put("nMaskStages",options.nMaskStages); + pt->put("firstStage",options.firstStage); + pt->put("stepStage",options.stepStage); + pt->put("nLoops",options.nLoops); + //Loops + for(int i=0;i<options.nLoops;i++){ + char loopname[128]; + sprintf (loopname,"scanLoop_%d.",i); + pt->put(std::string(loopname)+"scanParameter", options.scanLoop[i].scanParameter); + pt->put(std::string(loopname)+"nPoints",options.scanLoop[i].nPoints); + pt->put(std::string(loopname)+"endofLoopAction.Action", options.scanLoop[i].endofLoopAction.Action); + pt->put(std::string(loopname)+"endofLoopAction.fitFunction", options.scanLoop[i].endofLoopAction.fitFunction); + pt->put(std::string(loopname)+"endofLoopAction.targetThreshold", options.scanLoop[i].endofLoopAction.targetThreshold); + if(options.scanLoop[i].dataPoints.length()>0){ + char pointname[10]; + for(unsigned int j=0;j<options.scanLoop[i].dataPoints.length();j++){ + sprintf(pointname,"P_%d",j); + pt->put(std::string(loopname)+"dataPoints."+pointname,options.scanLoop[i].dataPoints[j]); + } + } + } + //Trigger options + pt->put("trigOpt.nEvents",options.trigOpt.nEvents); + pt->put("trigOpt.triggerMask",options.trigOpt.triggerMask); + pt->put("trigOpt.moduleTrgMask",options.trigOpt.moduleTrgMask); + pt->put("trigOpt.triggerDataOn",options.trigOpt.triggerDataOn); + pt->put("trigOpt.deadtime",options.trigOpt.deadtime); + pt->put("trigOpt.nL1AperEvent",options.trigOpt.nL1AperEvent); + pt->put("trigOpt.nTriggersPerGroup",options.trigOpt.nTriggersPerGroup); + pt->put("trigOpt.nTriggers",options.trigOpt.nTriggers); + pt->put("trigOpt.Lvl1_Latency",options.trigOpt.Lvl1_Latency); + pt->put("trigOpt.Lvl1_Latency_Secondary",options.trigOpt.Lvl1_Latency_Secondary); + pt->put("trigOpt.strobeDuration",options.trigOpt.strobeDuration); + pt->put("trigOpt.strobeMCCDelay",options.trigOpt.strobeMCCDelay); + pt->put("trigOpt.strobeMCCDelayRange",options.trigOpt.strobeMCCDelayRange); + pt->put("trigOpt.CalL1ADelay",options.trigOpt.CalL1ADelay); + pt->put("trigOpt.eventInterval",options.trigOpt.eventInterval); + pt->put("trigOpt.injectForTrigger",options.trigOpt.injectForTrigger); + pt->put("trigOpt.vcal_charge",options.trigOpt.vcal_charge); + pt->put("trigOpt.threshold",options.trigOpt.threshold); + pt->put("trigOpt.hitbusConfig",options.trigOpt.hitbusConfig); + + // each option gets an entry in the tree below optionsMask with value 1 + for (unsigned int i=0;i<options.trigOpt.optionsMask.length();i++){ + pt->put(std::string("trigOpt.optionsMask.")+(const char*)options.trigOpt.optionsMask[i],1); + } + pt->put("trigOpt.triggerMode", options.trigOpt.triggerMode); + + // front-end options + pt->put("feOpt.phi",options.feOpt.phi); + pt->put("feOpt.totThresholdMode",options.feOpt.totThresholdMode); + pt->put("feOpt.totMinimum",options.feOpt.totMinimum); + pt->put("feOpt.totTwalk",options.feOpt.totTwalk); + pt->put("feOpt.totLeMode",options.feOpt.totLeMode); + pt->put("feOpt.hitbus",options.feOpt.hitbus); + + pt->put("nHistoNames",options.histos.length()); + if(options.histos.length()>0){ + char pointname[10]; + for(unsigned int j=0;j<options.histos.length();j++){ + sprintf(pointname,"Name_%d",j); + pt->put(std::string("HistoNames.")+pointname,options.histos[j]); + } + } + //Trigger options + //call the real initScan function + //std::cout<<"Calling ScanRoot "<<std::endl; + configureScan(pt); + delete pt; + return 0; +} + +template <class TP> +ipc::StringVect* IPCScanRoot<TP>::IPCgetHistoNames(const char* reg){ + std::vector<std::string> strvec=IPCHistoManager::instance()->getHistoNames(reg); + ipc::StringVect &ipcstringvect=*new ipc::StringVect; + ipcstringvect.length(strvec.size()); + for(size_t i=0;i<strvec.size();i++){ + ipcstringvect[i]=CORBA::string_dup(strvec[i].c_str()); + } + return &ipcstringvect; +} +template <class TP> +ipc::StringVect* IPCScanRoot<TP>::IPCgetPublishedHistoNames(){ + std::vector<std::string> strvec=IPCHistoManager::instance()->getPublishedHistoNames(); + ipc::StringVect &ipcstringvect=*new ipc::StringVect; + ipcstringvect.length(strvec.size()); + for(size_t i=0;i<strvec.size();i++){ + ipcstringvect[i]=CORBA::string_dup(strvec[i].c_str()); + } + return &ipcstringvect; +} + +template <class TP> +CORBA::ULong IPCScanRoot<TP>::IPCnEvents(){ + if(m_dataProc) + return m_dataProc->nEvents(); + else + return 0; +} +template <class TP> +void IPCScanRoot<TP>::IPCresynch(){ + if(m_receiver) + m_receiver->resynch(); +} + +template <class TP> +void IPCScanRoot<TP>::IPCconfigureCallback(ipc::Callback_ptr cb, ipc::Priority pr){ + RceCallback::instance()->configure(cb,pr); +} + +template <class TP> +void IPCScanRoot<TP>::shutdown(){ + std::cout<<"Shutdown"<<std::endl; +} + +#endif diff --git a/rce/rcecalib/scanctrl/IPCScanRoot.hh b/rce/rcecalib/scanctrl/IPCScanRoot.hh new file mode 100644 index 0000000000000000000000000000000000000000..4606e88b1c7d383c156ebb89f022ff19b72bac6f --- /dev/null +++ b/rce/rcecalib/scanctrl/IPCScanRoot.hh @@ -0,0 +1,29 @@ +#ifndef IPCSCANROOT_HH +#define IPCSCANROOT_HH + +#include "rcecalib/scanctrl/ScanRoot.hh" +#include "ipc/object.h" +#include "ScanOptions.hh" +#include "IPCScanRootAdapter.hh" + +class IPCPartition; +class ConfigIF; +class Scan; + +template <class TP = ipc::single_thread> +class IPCScanRoot: public IPCNamedObject<POA_ipc::IPCScanRootAdapter,TP>, public ScanRoot { +public: + IPCScanRoot(IPCPartition & p, const char * name, ConfigIF* cif, Scan* scan); + ~IPCScanRoot(); + CORBA::Long IPCconfigureScan(const ipc::ScanOptions &options); + ipc::StringVect* IPCgetHistoNames(const char* reg); + ipc::StringVect* IPCgetPublishedHistoNames(); + CORBA::ULong IPCnEvents(); + void IPCresynch(); + void IPCconfigureCallback(ipc::Callback_ptr cb, ipc::Priority pr); + void shutdown(); + +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/IfScanSetup.cc b/rce/rcecalib/scanctrl/IfScanSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..709449e2d4bdc485e725214a052b59d00e88999c --- /dev/null +++ b/rce/rcecalib/scanctrl/IfScanSetup.cc @@ -0,0 +1,63 @@ +#include "rcecalib/scanctrl/IfScanSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +#include <stdio.h> + +int IfScanSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Start with the trigger loop + int nEvents = scanOptions->get<int>("trigOpt.nEvents"); + ScanLoop* triggerloop=new ScanLoop("Triggerloop",nEvents); + // LoopAction* pause=af->createLoopAction("PAUSE"); + LoopAction* sendtrigger=af->createLoopAction("SEND_TRIGGER",scanOptions); + //triggerloop->addLoopAction(pause); + triggerloop->addLoopAction(sendtrigger); + // loop is the nested loop object + loop.addNewInnermostLoop(triggerloop); + + // The position of the mask stage loop is not + // explicitely specified by PixLib. Implicitely it's the innermost loop + // if there is no other scan variable (nLoops==0) and next-to-innermost otherwise. + int nLoops = scanOptions->get<int>("nLoops"); + assert(nLoops==1); + // now it's time for the mask stage loop + int nMaskStages= scanOptions->get<int>("nMaskStages"); + ScanLoop* maskStageLoop = new ScanLoop("MaskStageLoop",nMaskStages); + LoopAction* maskaction=af->createLoopAction("SETUP_MASK", scanOptions); + maskStageLoop->addLoopAction(maskaction); + loop.addNewOutermostLoop(maskStageLoop); + //parameter loop is next + int nPoints = scanOptions->get<int>("scanLoop_0.nPoints"); + ScanLoop *firstparloop=new ScanLoop("scanLoop_0",nPoints); + LoopAction* wait=af->createLoopAction("IF_WAIT"); + LoopAction* setuppar0=af->createLoopAction("SETUP_PARAM",&scanOptions->get_child("scanLoop_0")); + LoopAction* chgbin0=af->createLoopAction("CHANGE_BIN"); + firstparloop->addLoopAction(wait); + firstparloop->addLoopAction(setuppar0); + firstparloop->addLoopAction(chgbin0); + loop.addNewOutermostLoop(firstparloop); + std::string action=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.Action"); + std::string fitfunc=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.fitFunction"); + EndOfLoopAction* fitaction=af->createEndOfLoopAction(action,fitfunc); + /* protect against no loop action returned */ + if(fitaction)maskStageLoop->addEndOfLoopAction(fitaction); + ScanLoop *configloop=new ScanLoop("Configure modules",1); + LoopAction* configaction=af->createLoopAction("CONFIGURE_MODULES_NO_ENABLE"); + configloop->addLoopAction(configaction); + loop.addNewOutermostLoop(configloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/IfScanSetup.hh b/rce/rcecalib/scanctrl/IfScanSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..e819150b7f95091d4fc98d7796d30db1342fbb74 --- /dev/null +++ b/rce/rcecalib/scanctrl/IfScanSetup.hh @@ -0,0 +1,18 @@ +#ifndef IFSCANSETUP_HH +#define IFSCANSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class IfScanSetup: public LoopSetup{ +public: + IfScanSetup():LoopSetup(){}; + virtual ~IfScanSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/IfWaitAction.hh b/rce/rcecalib/scanctrl/IfWaitAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..5c3d5e51b1d27e6f3d3c165f9109682e3bc1c956 --- /dev/null +++ b/rce/rcecalib/scanctrl/IfWaitAction.hh @@ -0,0 +1,22 @@ +#ifndef IFWAITACTION_HH +#define IFWAITACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/Scan.hh" + +class IfWaitAction: public LoopAction{ +public: + IfWaitAction(std::string name): + LoopAction(name){} + enum del{DELAY=100000}; + int execute(int i){ + //std::cout<<"Pausing scan"<<std::endl; + usleep(DELAY); + return 0; + //std::cout<<"Done pausing scan"<<std::endl; + } +private: + Scan* m_scan; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/LoopAction.hh b/rce/rcecalib/scanctrl/LoopAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..c84e088cdf90a1ca3dcf0c58a7395e609df39955 --- /dev/null +++ b/rce/rcecalib/scanctrl/LoopAction.hh @@ -0,0 +1,19 @@ +#ifndef LOOPACTION_HH +#define LOOPACTION_HH + +#include <string> + + +class LoopAction{ +public: + LoopAction(std::string name): + m_name(name){} + std::string name(){return m_name;} + virtual ~LoopAction(){} + virtual int execute(int i) = 0; + +protected: + std::string m_name; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/LoopFactory.cc b/rce/rcecalib/scanctrl/LoopFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..b01ac2eba34afc87e62aa342c993cab704878d44 --- /dev/null +++ b/rce/rcecalib/scanctrl/LoopFactory.cc @@ -0,0 +1,38 @@ +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/scanctrl/LoopFactory.hh" +#include "rcecalib/scanctrl/RegularScanSetup.hh" +#include "rcecalib/scanctrl/RegularCfgScanSetup.hh" +#include "rcecalib/scanctrl/IfScanSetup.hh" +#include "rcecalib/scanctrl/SelftriggerSetup.hh" +#include "rcecalib/scanctrl/DelayScanSetup.hh" +#include "rcecalib/scanctrl/CosmicDataSetup.hh" +#include "rcecalib/scanctrl/NoiseScanSetup.hh" +#include <stdio.h> /* for sprintf */ + +LoopFactory::LoopFactory(){} + + +LoopSetup* LoopFactory::createLoopSetup(const char* type){ + + if(std::string(type)=="Regular") + return new RegularScanSetup; + else if(std::string(type)=="RegularCfg") + return new RegularCfgScanSetup; + else if(std::string(type)=="IfScan") + return new IfScanSetup; + else if(std::string(type)=="Delay") + return new DelayScanSetup; + else if(std::string(type)=="CosmicData") + return new CosmicDataSetup; + else if(std::string(type)=="Selftrigger") + return new SelftriggerSetup; + else if(std::string(type)=="Noisescan") + return new NoiseScanSetup; + else { + char message[128]; + sprintf(message, "Scan loop setup for %s is not defined.", type); + ERS_ASSERT_MSG(0, message); + } + return 0; +} + diff --git a/rce/rcecalib/scanctrl/LoopFactory.hh b/rce/rcecalib/scanctrl/LoopFactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..d96fd0f8778269f8b68393eaba2659f2716bcfd5 --- /dev/null +++ b/rce/rcecalib/scanctrl/LoopFactory.hh @@ -0,0 +1,16 @@ +#ifndef LOOPFACTORY_HH +#define LOOPFACTORY_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/scanctrl/LoopSetup.hh" +class NestedLoop; + + +class LoopFactory{ +public: + LoopFactory(); + LoopSetup* createLoopSetup(const char* type); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/LoopSetup.hh b/rce/rcecalib/scanctrl/LoopSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..4c352bb3abca30f3670f9eac748c612f433ede01 --- /dev/null +++ b/rce/rcecalib/scanctrl/LoopSetup.hh @@ -0,0 +1,17 @@ +#ifndef LOOPSETUP_HH +#define LOOPSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" + +class LoopSetup{ +public: + LoopSetup(){}; + virtual ~LoopSetup(){}; + virtual int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af)=0; +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/Makefile b/rce/rcecalib/scanctrl/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/rcecalib/scanctrl/Makefile @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/rcecalib/scanctrl/NestedLoop.cc b/rce/rcecalib/scanctrl/NestedLoop.cc new file mode 100644 index 0000000000000000000000000000000000000000..24b16074a1effe6f840a68e2749c5fd8dc5ea767 --- /dev/null +++ b/rce/rcecalib/scanctrl/NestedLoop.cc @@ -0,0 +1,81 @@ + +#include "ScanLoop.hh" +#include "NestedLoop.hh" +#include <iostream> +#include <sstream> + +void NestedLoop::addNewInnermostLoop(ScanLoop* loop){ + ScanLoop *oldinnermost; + if(m_looplist.empty()){ + oldinnermost=0; + }else{ + oldinnermost=m_looplist.front(); + } + m_looplist.push_front(loop); + loop->setNextOuterLoop(oldinnermost); +} +void NestedLoop::addNewOutermostLoop(ScanLoop* loop){ + ScanLoop *oldoutermost; + if(!m_looplist.empty()){ + oldoutermost=m_looplist.back(); + oldoutermost->setNextOuterLoop(loop); + } + m_looplist.push_back(loop); +} + +void NestedLoop::next(){ // all for loops are chained together and call each other. + // the first event is special because all loop actions have to be performed for setup + if(!m_looplist.empty()){ + if(m_init==false){ + firstEvent(); + m_init=true; + }else{ + m_done=m_looplist.front()->next(); //done comes from the outermost loop + } + } +} + +void NestedLoop::firstEvent(){ + std::list<ScanLoop*>::reverse_iterator listit; + // has to go from the outside to the inside + for(listit = m_looplist.rbegin(); listit != m_looplist.rend(); listit++){ + (*listit)->firstEvent(); + } +} + +void NestedLoop::clear(){ + std::list<ScanLoop*>::iterator listit; + for(listit = m_looplist.begin(); listit != m_looplist.end(); listit++){ + delete *listit; + } + m_looplist.clear(); + m_init=false; + m_done=false; +} +void NestedLoop::reset(){ + m_init=false; + m_done=false; + std::list<ScanLoop*>::iterator listit; + for(listit = m_looplist.begin(); listit != m_looplist.end(); listit++){ + (*listit)->reset(); + } +} + +NestedLoop::~NestedLoop(){ + std::list<ScanLoop*>::iterator listit; + for(listit = m_looplist.begin(); listit != m_looplist.end(); listit++){ + delete *listit; + } +} + +void NestedLoop::print(){ + std::cout<<std::endl; + std::list<ScanLoop*>::iterator listit; + std::stringstream spaces(" "); + for(listit = m_looplist.begin(); listit != m_looplist.end(); listit++){ + ScanLoop* loop=(*listit); + loop->print(spaces.str().c_str()); + spaces<<" "; + std::cout<<std::endl; + } +} diff --git a/rce/rcecalib/scanctrl/NestedLoop.hh b/rce/rcecalib/scanctrl/NestedLoop.hh new file mode 100644 index 0000000000000000000000000000000000000000..4b263fbf699c6b4478cb07a61e52fbc10f7c485a --- /dev/null +++ b/rce/rcecalib/scanctrl/NestedLoop.hh @@ -0,0 +1,32 @@ +#ifndef NESTED_LOOP_HH +#define NESTED_LOOP_HH + +// Implements a nested for loop. +// Works together with ScanLoop.hh + +// C 2009 SLAC Author: Martin Kocian + +#include <list> + +class ScanLoop; + +class NestedLoop{ + +public: + NestedLoop():m_done(false),m_init(false){} + ~NestedLoop(); + bool done(){return m_done;} + void clear(); + void reset(); + void addNewInnermostLoop(ScanLoop*); + void addNewOutermostLoop(ScanLoop*); + void firstEvent(); + void next(); + void print(); +private: + std::list<ScanLoop*> m_looplist; + bool m_done; + bool m_init; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/NoiseScanSetup.cc b/rce/rcecalib/scanctrl/NoiseScanSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..224811b9ea420ec20dae63362cf65977b12a78cd --- /dev/null +++ b/rce/rcecalib/scanctrl/NoiseScanSetup.cc @@ -0,0 +1,42 @@ +#include "rcecalib/scanctrl/NoiseScanSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +int NoiseScanSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Data Taking has a single loop with one entry + ScanLoop *scanloop=new ScanLoop("scan",1); + LoopAction* conf=af->createLoopAction("CONFIGURE_MODULES"); + scanloop->addLoopAction(conf); + // LoopAction* linkmask=af->createLoopAction("SETUP_CHANNELMASK"); + //scanloop->addLoopAction(linkmask); + LoopAction* setupcyclic=af->createLoopAction("SETUP_TRIGGER", scanOptions); + scanloop->addLoopAction(setupcyclic); + LoopAction* enable=af->createLoopAction("ENABLE_TRIGGER"); + scanloop->addLoopAction(enable); + // End of loop actions + EndOfLoopAction* disabletrigger=af->createEndOfLoopAction("DISABLE_TRIGGER",""); + scanloop->addEndOfLoopAction(disabletrigger); + EndOfLoopAction* closefile=af->createEndOfLoopAction("CLOSE_FILE",""); + scanloop->addEndOfLoopAction(closefile); + EndOfLoopAction* resetfe=af->createEndOfLoopAction("RESET_FE",""); + scanloop->addEndOfLoopAction(resetfe); + EndOfLoopAction* disablechannels=af->createEndOfLoopAction("DISABLE_ALL_CHANNELS",""); + scanloop->addEndOfLoopAction(disablechannels); + // loop is the nested loop object + loop.addNewInnermostLoop(scanloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/NoiseScanSetup.hh b/rce/rcecalib/scanctrl/NoiseScanSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..d0fd91406bf07b4bb1baad2f355ff6a3d0c942d5 --- /dev/null +++ b/rce/rcecalib/scanctrl/NoiseScanSetup.hh @@ -0,0 +1,18 @@ +#ifndef NOISESCANSETUP_HH +#define NOISESCANSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class NoiseScanSetup: public LoopSetup{ +public: + NoiseScanSetup():LoopSetup(){}; + virtual ~NoiseScanSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/PauseAction.hh b/rce/rcecalib/scanctrl/PauseAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..26dcd3b3c431327e44612ea54f3fdaa29a1aa4e8 --- /dev/null +++ b/rce/rcecalib/scanctrl/PauseAction.hh @@ -0,0 +1,20 @@ +#ifndef PAUSEACTION_HH +#define PAUSEACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/Scan.hh" + +class PauseAction: public LoopAction{ +public: + PauseAction(std::string name, Scan* scan): + LoopAction(name),m_scan(scan){} + int execute(int i){ + //std::cout<<"Pausing scan"<<std::endl; + return m_scan->pause(); + //std::cout<<"Done pausing scan"<<std::endl; + } +private: + Scan* m_scan; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/RceCallback.cc b/rce/rcecalib/scanctrl/RceCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..fd803de6f0bf8e314a9d925a7d69fc0476d4fa47 --- /dev/null +++ b/rce/rcecalib/scanctrl/RceCallback.cc @@ -0,0 +1,47 @@ +#include "rcecalib/scanctrl/RceCallback.hh" +#include <iostream> + +RceCallback* RceCallback::m_instance=0; +omni_mutex RceCallback::m_guard; + +RceCallback* RceCallback::instance(){ + if( ! m_instance){ + omni_mutex_lock ml(m_guard); + if( ! m_instance){ + m_instance=new RceCallback; + } + } + return m_instance; +} + +RceCallback::RceCallback(): m_configured(false){} + +void RceCallback::configure(ipc::Callback_ptr cb, ipc::Priority pr){ + m_cb = ipc::Callback::_duplicate( cb ); + m_pr=pr; + m_configured=true; +} + +void RceCallback::sendMsg(ipc::Priority pr, const ipc::CallbackParams *msg){ + if(m_configured==true){ + if(pr>=m_pr){ + try { + m_cb->notify( *msg ); + } + catch(...) { + std::cout << "callback : notification fails" << std::endl; + } + } + } +} +void RceCallback::shutdown(){ + if(m_configured==true){ + try { + m_cb->stopServer(); + } + catch(...) { + std::cout << "callback : notification fails" << std::endl; + } + m_configured=false; + } +} diff --git a/rce/rcecalib/scanctrl/RceCallback.hh b/rce/rcecalib/scanctrl/RceCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..a79ab8c84701eac7b0ba563d8519429dc53256ac --- /dev/null +++ b/rce/rcecalib/scanctrl/RceCallback.hh @@ -0,0 +1,24 @@ +#ifndef RCEMSG_HH +#define RCEMSG_HH + +#include "Callback.hh" +#include <omnithread.h> + +class RceCallback{ +public: + enum Priority {LOW, MEDIUM, HIGH}; + static RceCallback* instance(); + void sendMsg(ipc::Priority pr, const ipc::CallbackParams *msg); + void shutdown(); + void configure( ipc::Callback_ptr cb, ipc::Priority pr); +private: + RceCallback(); + ipc::Callback_var m_cb; + ipc::Priority m_pr; + bool m_configured; + static omni_mutex m_guard; + static RceCallback* m_instance; + +}; + +#endif diff --git a/rce/rcecalib/scanctrl/RegularCfgScanSetup.cc b/rce/rcecalib/scanctrl/RegularCfgScanSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..2db88060efb17d48055dfb8347ae730e6c788b9a --- /dev/null +++ b/rce/rcecalib/scanctrl/RegularCfgScanSetup.cc @@ -0,0 +1,110 @@ +#include "rcecalib/scanctrl/RegularCfgScanSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +#include <stdio.h> + +int RegularCfgScanSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Start with the trigger loop + int nEvents = scanOptions->get<int>("trigOpt.nEvents"); + ScanLoop* triggerloop=new ScanLoop("Triggerloop",nEvents); + // LoopAction* pause=af->createLoopAction("PAUSE"); + LoopAction* sendtrigger=af->createLoopAction("SEND_TRIGGER",scanOptions); + //triggerloop->addLoopAction(pause); + triggerloop->addLoopAction(sendtrigger); + // loop is the nested loop object + loop.addNewInnermostLoop(triggerloop); + + // The position of the mask stage loop is not + // explicitely specified by PixLib. Implicitely it's the innermost loop + // if there is no other scan variable (nLoops==0) and next-to-innermost otherwise. + int nLoops = scanOptions->get<int>("nLoops"); + if(nLoops>0){ + //parameter loop is next + int nPoints = scanOptions->get<int>("scanLoop_0.nPoints"); + ScanLoop *firstparloop=new ScanLoop("scanLoop_0",nPoints); + //LoopAction* disable0=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* setuppar0=af->createLoopAction("SETUP_PARAM",&scanOptions->get_child("scanLoop_0")); + LoopAction* chgbin0=af->createLoopAction("CHANGE_BIN"); + //LoopAction* linkmask0=af->createLoopAction("SETUP_CHANNELMASK"); + // LoopAction* enable0=af->createLoopAction("ENABLE_TRIGGER"); + // End of loop action is deferred to mask stage + // firstparloop->addLoopAction(disable0); + firstparloop->addLoopAction(setuppar0); + firstparloop->addLoopAction(chgbin0); + //firstparloop->addLoopAction(linkmask0); + // firstparloop->addLoopAction(enable0); + loop.addNewOutermostLoop(firstparloop); + } + // now it's time for the mask stage loop + int nMaskStages= scanOptions->get<int>("nMaskStages"); + ScanLoop* maskStageLoop = new ScanLoop("MaskStageLoop",nMaskStages); + //LoopAction* disablem=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* maskaction=af->createLoopAction("SETUP_MASK", scanOptions); + //LoopAction* linkmaskm=af->createLoopAction("SETUP_CHANNELMASK"); + //LoopAction* enablem=af->createLoopAction("ENABLE_TRIGGER"); + //maskStageLoop->addLoopAction(disablem); + maskStageLoop->addLoopAction(maskaction); + //maskStageLoop->addLoopAction(linkmaskm); + //maskStageLoop->addLoopAction(enablem); + // The end of loop action from the parameter loop above if there is one + /* add calculation of ToT/BCID mean and sigma to end-of-loop sction */ + if(scanOptions->get<std::string>("DataProc")=="BCID" || scanOptions->get<std::string>("DataProc")=="TOT") { + std::cout << "Add BCID calculation as end-of-loop action" << std::endl; + EndOfLoopAction* action=af->createEndOfLoopAction("CALCULATE_MEAN_SIGMA","CALCULATE_MEAN_SIGMA"); + if(action) maskStageLoop->addEndOfLoopAction(action); + } + + + if(nLoops>0){ + std::string action=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.Action"); + std::string fitfunc=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.fitFunction"); + EndOfLoopAction* fitaction=af->createEndOfLoopAction(action,fitfunc); + /* protect against no loop action returned */ + if(fitaction)maskStageLoop->addEndOfLoopAction(fitaction); + } + loop.addNewOutermostLoop(maskStageLoop); + // now add any additional loops + char desc[128]; + for (int i=1;i<nLoops;i++){ + sprintf(desc,"scanLoop_%d",i); + int nPoints = scanOptions->get<int>(std::string(desc)+".nPoints"); + ScanLoop *parloop=new ScanLoop(desc,nPoints); + // LoopAction* disable=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* setuppar=af->createLoopAction("SETUP_PARAM",&scanOptions->get_child(desc)); + LoopAction* chgbin=af->createLoopAction("CHANGE_BIN"); + //LoopAction* enable=af->createLoopAction("ENABLE_TRIGGER"); + //LoopAction* linkmask=af->createLoopAction("SETUP_CHANNELMASK"); + // End of loop action is deferred to mask stage + // parloop->addLoopAction(disable); + parloop->addLoopAction(setuppar); + parloop->addLoopAction(chgbin); + //maskStageLoop->addLoopAction(linkmask); + // parloop->addLoopAction(enable); + std::string action=scanOptions->get<std::string>(std::string(desc)+".endofLoopAction.Action"); + std::string fitfunc=scanOptions->get<std::string>(std::string(desc)+".endofLoopAction.fitFunction"); + EndOfLoopAction* fitaction=af->createEndOfLoopAction(action,fitfunc); + if(fitaction) + parloop->addEndOfLoopAction(fitaction); + loop.addNewOutermostLoop(parloop); + } + ScanLoop *configloop=new ScanLoop("Configure modules",1); + LoopAction* configaction=af->createLoopAction("CONFIGURE_MODULES_NO_ENABLE"); + configloop->addLoopAction(configaction); + loop.addNewOutermostLoop(configloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/RegularCfgScanSetup.hh b/rce/rcecalib/scanctrl/RegularCfgScanSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..6be05ef14677ca874dae19b66d8035278bac93aa --- /dev/null +++ b/rce/rcecalib/scanctrl/RegularCfgScanSetup.hh @@ -0,0 +1,18 @@ +#ifndef REGULARCFGSCANSETUP_HH +#define REGULARCFGSCANSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class RegularCfgScanSetup: public LoopSetup{ +public: + RegularCfgScanSetup():LoopSetup(){}; + virtual ~RegularCfgScanSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/RegularScanSetup.cc b/rce/rcecalib/scanctrl/RegularScanSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..3c5d97e2b29f49c2cb4bf423b093b0703d51f14f --- /dev/null +++ b/rce/rcecalib/scanctrl/RegularScanSetup.cc @@ -0,0 +1,106 @@ +#include "rcecalib/scanctrl/RegularScanSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +#include <stdio.h> + +int RegularScanSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Start with the trigger loop + int nEvents = scanOptions->get<int>("trigOpt.nEvents"); + ScanLoop* triggerloop=new ScanLoop("Triggerloop",nEvents); + // LoopAction* pause=af->createLoopAction("PAUSE"); + LoopAction* sendtrigger=af->createLoopAction("SEND_TRIGGER",scanOptions); + //triggerloop->addLoopAction(pause); + triggerloop->addLoopAction(sendtrigger); + // loop is the nested loop object + loop.addNewInnermostLoop(triggerloop); + + // The position of the mask stage loop is not + // explicitely specified by PixLib. Implicitely it's the innermost loop + // if there is no other scan variable (nLoops==0) and next-to-innermost otherwise. + int nLoops = scanOptions->get<int>("nLoops"); + if(nLoops>0){ + //parameter loop is next + int nPoints = scanOptions->get<int>("scanLoop_0.nPoints"); + ScanLoop *firstparloop=new ScanLoop("scanLoop_0",nPoints); + //LoopAction* disable0=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* setuppar0=af->createLoopAction("SETUP_PARAM",&scanOptions->get_child("scanLoop_0")); + LoopAction* chgbin0=af->createLoopAction("CHANGE_BIN"); + //LoopAction* linkmask0=af->createLoopAction("SETUP_CHANNELMASK"); + // LoopAction* enable0=af->createLoopAction("ENABLE_TRIGGER"); + // End of loop action is deferred to mask stage + // firstparloop->addLoopAction(disable0); + firstparloop->addLoopAction(setuppar0); + firstparloop->addLoopAction(chgbin0); + //firstparloop->addLoopAction(linkmask0); + // firstparloop->addLoopAction(enable0); + loop.addNewOutermostLoop(firstparloop); + } + // now it's time for the mask stage loop + int nMaskStages= scanOptions->get<int>("nMaskStages"); + ScanLoop* maskStageLoop = new ScanLoop("MaskStageLoop",nMaskStages); + //LoopAction* disablem=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* maskaction=af->createLoopAction("SETUP_MASK", scanOptions); + //LoopAction* linkmaskm=af->createLoopAction("SETUP_CHANNELMASK"); + //LoopAction* enablem=af->createLoopAction("ENABLE_TRIGGER"); + //maskStageLoop->addLoopAction(disablem); + maskStageLoop->addLoopAction(maskaction); + //maskStageLoop->addLoopAction(linkmaskm); + //maskStageLoop->addLoopAction(enablem); + // The end of loop action from the parameter loop above if there is one + /* add calculation of ToT/BCID mean and sigma to end-of-loop sction */ + if(scanOptions->get<std::string>("DataProc")=="BCID" || scanOptions->get<std::string>("DataProc")=="TOT") { + std::cout << "Add Mean/Sgima calculation as end-of-loop action" << std::endl; + EndOfLoopAction* action=af->createEndOfLoopAction("CALCULATE_MEAN_SIGMA","CALCULATE_MEAN_SIGMA"); + if(action) maskStageLoop->addEndOfLoopAction(action); + } + + + if(nLoops>0){ + std::string action=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.Action"); + std::string fitfunc=scanOptions->get<std::string>("scanLoop_0.endofLoopAction.fitFunction"); + EndOfLoopAction* fitaction=af->createEndOfLoopAction(action,fitfunc); + /* protect against no loop action returned */ + if(fitaction)maskStageLoop->addEndOfLoopAction(fitaction); + } + loop.addNewOutermostLoop(maskStageLoop); + // now add any additional loops + char desc[128]; + for (int i=1;i<nLoops;i++){ + sprintf(desc,"scanLoop_%d",i); + int nPoints = scanOptions->get<int>(std::string(desc)+".nPoints"); + ScanLoop *parloop=new ScanLoop(desc,nPoints); + // LoopAction* disable=af->createLoopAction("DISABLE_TRIGGER"); + LoopAction* setuppar=af->createLoopAction("SETUP_PARAM",&scanOptions->get_child(desc)); + LoopAction* chgbin=af->createLoopAction("CHANGE_BIN"); + //LoopAction* enable=af->createLoopAction("ENABLE_TRIGGER"); + //LoopAction* linkmask=af->createLoopAction("SETUP_CHANNELMASK"); + // End of loop action is deferred to mask stage + // parloop->addLoopAction(disable); + parloop->addLoopAction(setuppar); + parloop->addLoopAction(chgbin); + //maskStageLoop->addLoopAction(linkmask); + // parloop->addLoopAction(enable); + std::string action=scanOptions->get<std::string>(std::string(desc)+".endofLoopAction.Action"); + std::string fitfunc=scanOptions->get<std::string>(std::string(desc)+".endofLoopAction.fitFunction"); + EndOfLoopAction* fitaction=af->createEndOfLoopAction(action,fitfunc); + if(fitaction) + parloop->addEndOfLoopAction(fitaction); + loop.addNewOutermostLoop(parloop); + } + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/RegularScanSetup.hh b/rce/rcecalib/scanctrl/RegularScanSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..d6077b06e9ae0c592e928e3763ffa8079dfac55d --- /dev/null +++ b/rce/rcecalib/scanctrl/RegularScanSetup.hh @@ -0,0 +1,18 @@ +#ifndef REGULARSCANSETUP_HH +#define REGULARSCANSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class RegularScanSetup: public LoopSetup{ +public: + RegularScanSetup():LoopSetup(){}; + virtual ~RegularScanSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/ResetFEEoLAction.hh b/rce/rcecalib/scanctrl/ResetFEEoLAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..1fa76f42ae6a52ba79eab8adc07e21781ac61ae8 --- /dev/null +++ b/rce/rcecalib/scanctrl/ResetFEEoLAction.hh @@ -0,0 +1,19 @@ +#ifndef RESETFEEOLACTION_HH +#define RESETFEEOLACTION_HH + +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class ResetFEEoLAction: public EndOfLoopAction{ +public: + ResetFEEoLAction(std::string name, ConfigIF* cif) : + EndOfLoopAction(name),m_configIF(cif){} + int execute(){ + m_configIF->resetFE(); + return 0; + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/Scan.cc b/rce/rcecalib/scanctrl/Scan.cc new file mode 100644 index 0000000000000000000000000000000000000000..1684c1f12265120aa01d1f12ae65e9bf09bb146e --- /dev/null +++ b/rce/rcecalib/scanctrl/Scan.cc @@ -0,0 +1,242 @@ + +#include "rcecalib/scanctrl/Scan.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include "rcecalib/scanctrl/LoopFactory.hh" +#include "rcecalib/scanctrl/RceCallback.hh" +#include "rcecalib/util/RceName.hh" +#include <pthread.h> +#include <stdio.h> /* for printf */ + +#include <boost/property_tree/ptree.hpp> +#include <boost/foreach.hpp> + +#include "rcecalib/util/exceptions.hh" + +#include "rcecalib/util/IPCHistoManager.hh" + +#include <string> +#include <iostream> +#include "rcecalib/profiler/Profiler.hh" +#include "rcecalib/HW/SerialIF.hh" + +#ifdef __rtems__ +extern "C"{ + #include <rtems/malloc.h> +} +#endif + +Scan::Scan(): + m_state(IDLE), m_pause_cond (&m_pause_mutex), + m_i(0), m_handler(0),m_timeout_seconds(0),m_timeout_nanoseconds(0), m_failed(false), m_timeouts(0){} + +Scan::~Scan(){ +} + +int Scan::configureScan(boost::property_tree::ptree *scanOptions, ActionFactory &af, AbsDataHandler* par){ + m_handler=par; + if(m_state!=IDLE && m_state!=CONFIGURED){ + std::cout<<"Warning: Scan was not in idle state. Trying to clean up..."<<std::endl; + // perhaps there is an old scan hanging in the main loop + abort(); + sleep(2); + if(m_state!=IDLE){ + std::cout<<"Could not recover situation. Starting anyway."<<std::endl; + m_state=IDLE; + }else{ + std::cout<<"Cleanup successful. Starting the run now"<<std::endl; + } + } + // in case we got stuck in the waiting state somehow in a previous run + stopWaiting(); + m_handler->timeoutOccurred(); + int retval=0; + try{ + // set up loops + //setup contains the code to build the concrete nested loop + LoopFactory lf; + std::string type = scanOptions->get<std::string>("scanType"); + std::cout<<"Scan Type "<<type<<std::endl; + LoopSetup* setup=lf.createLoopSetup(type.c_str()); + //m_loops gets configured + setup->setupLoops(m_loops,scanOptions, &af); + m_timeout_seconds=scanOptions->get<unsigned>("Timeout.Seconds"); + m_timeout_nanoseconds=scanOptions->get<unsigned>("Timeout.Nanoseconds"); + m_allowedTimeouts=scanOptions->get<int>("Timeout.AllowedTimeouts"); + m_state=CONFIGURED; + // get rid of the setup object + // m_loops.print(); + delete setup; + // histograms + int nHistoNames=scanOptions->get<int>("nHistoNames"); + m_histolist.clear(); + if(nHistoNames>0){ + BOOST_FOREACH(boost::property_tree::ptree::value_type &v, scanOptions->get_child("HistoNames")){ + ERS_DEBUG(2, v.second.data()); + std::string data = boost::lexical_cast<std::string>(v.second.data()); + std::cout<<"Histogram "<<data<<std::endl; + m_histolist.push_back(data); + } + } + + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + return retval; +} + +int Scan::waitForData(){ + if(m_dataCond.waitingForData!=false)return 1;// only makes sense if running + m_dataCond.mutex.lock(); + m_dataCond.waitingForData=true; + return 0; +} + +int Scan::stopWaiting(){ + if(m_dataCond.waitingForData!=true)return 1;// cannot go on unless waiting + omni_mutex_lock pl( m_dataCond.mutex ); + m_dataCond.waitingForData=false; + m_dataCond.cond.signal(); + return 0; +} + +int Scan::pause(){ + if(m_state!=RUNNING)return 1;// only pause if running + omni_mutex_lock pl( m_pause_mutex ); + m_state=PAUSED; + return 0; +} +int Scan::resume(){ + if(m_state!=PAUSED)return 1;// cannot resume unless paused + omni_mutex_lock pl( m_pause_mutex ); + m_state=RUNNING; + m_pause_cond.signal(); + return 0; +} + +int Scan::abort(){ + // abort must wake up the main thread when it is paused + omni_mutex_lock pl( m_pause_mutex ); + m_state=ABORT; + m_pause_cond.signal(); + stopWaiting(); + return 0; +} + +int Scan::startScan(){ + std::cout<<"Starting Scan"<<std::endl; + if(m_state!=IDLE && m_state!=CONFIGURED){ + std::cout<<"Bad state "<<m_state<<std::endl; + return 1; + } + int timeoutcount=0; + while(m_state!=CONFIGURED){ + if(timeoutcount>=CONFIG_TIMEOUT){ + std::cout<<"Configure timed out"<<std::endl; + return 1; //configure timed out + } + timeoutcount++; + usleep(10000); + } + std::cout<<"Running"<<std::endl; + m_state=RUNNING; + // m_loops.print(); + m_loops.reset(); + struct sched_param param; + int policy; + pthread_getschedparam(pthread_self(), &policy, ¶m); + param.sched_priority=254; + pthread_setschedparam(pthread_self(), policy, ¶m); +#ifdef __rtems__ + rtems_malloc_statistics_t stats; + malloc_get_statistics(&stats); + printf("*** malloc statistics\n"); + printf("space available: %uk\n",(unsigned int)stats.space_available/1024); + printf("space allocated: %uk\n",(unsigned int)(stats.lifetime_allocated-stats.lifetime_freed)/1024); + //malloc_report_statistics(); +#endif + m_timeouts=0; + m_failed=false; + do{ + // std::cout<<"pre event"<<std::endl; + + //Set the state to WAITINGFORDATA until the data is processed. + //The actual waiting happens at m_data_cond.wait() + //waitForData(); + m_loops.next(); + //std::cout<<"post event"<<std::endl; + //if(m_loops.done())stopWaiting(); //there is no data to wait for + if(!m_loops.done())waitForData(); //there is no data to wait for + //std::cout<<"before pause"<<std::endl; + //if paused go to sleep until resume() wakes the thread up + if(m_dataCond.waitingForData==true) { + unsigned long abs_sec,abs_nsec; + omni_thread::get_time(&abs_sec,&abs_nsec,m_timeout_seconds,m_timeout_nanoseconds); + int signalled=m_dataCond.cond.timedwait(abs_sec,abs_nsec); + m_dataCond.waitingForData=false; + if(signalled==0){ //timeout. Something went wrong with the data. + if(m_allowedTimeouts!=-1){ //-1 means any number is allowed + m_timeouts++; + if(m_timeouts>m_allowedTimeouts){ + std::cout<<"Timeout limit reached. Aborting scan"<<std::endl; + setFailed(); + abort(); + } + } + std::cout<<"Timeout"<<std::endl; + m_handler->timeoutOccurred(); + }else{ + //std::cout<<"Was restarted"<<std::endl; + } + } + m_dataCond.mutex.unlock(); + //std::cout<<"Unlocked data mutex "<<m_i++<<std::endl; + + m_pause_mutex.lock(); + if(m_state==PAUSED) m_pause_cond.wait(); + m_pause_mutex.unlock(); + + //std::cout<<"loop"<<std::endl; + }while(!m_loops.done() && m_state!=ABORT); + SerialIF::setChannelOutMask(0); + if(!failed()){ + std::cout<<"Publish histos "<<m_i<<std::endl; + ipc::CallbackParams cbp; + cbp.rce=RceName::getRceNumber(); + cbp.status=ipc::DOWNLOADING; + cbp.maskStage=-1; + cbp.loop0=-1; + cbp.loop1=-1; + RceCallback::instance()->sendMsg(ipc::HIGH,&cbp); + publishHistos(); + std::cout<<"Done "<<m_i++<<std::endl; + }else{ + std::cout<<"Failed"<<std::endl; + } + RceCallback::instance()->shutdown(); + m_state=IDLE; + return 0; +} + +void Scan::publishHistos(){ + // this scan has no histograms + if(m_histolist.size()==0)return; + for (size_t k=0;k<m_histolist.size();k++){ + IPCHistoManager::instance()->publish(m_histolist[k].c_str()); + } +} + +void Scan::setFailed(){ + m_failed=true; + ipc::CallbackParams cbp; + cbp.rce=RceName::getRceNumber(); + cbp.status=ipc::FAILED; + cbp.maskStage=-1; + cbp.loop0=-1; + cbp.loop1=-1; + RceCallback::instance()->sendMsg(ipc::HIGH,&cbp); +} + diff --git a/rce/rcecalib/scanctrl/Scan.hh b/rce/rcecalib/scanctrl/Scan.hh new file mode 100644 index 0000000000000000000000000000000000000000..f6b3d16e8b669d0b8d08af537bbbb2bbaea792a4 --- /dev/null +++ b/rce/rcecalib/scanctrl/Scan.hh @@ -0,0 +1,47 @@ +#ifndef SCAN_HH +#define SCAN_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include <omnithread.h> +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/util/DataCond.hh" +#include <vector> + +class ActionFactory; +class AbsDataHandler; + +class Scan{ +public: + Scan(); + ~Scan(); + int configureScan(boost::property_tree::ptree* scanOptions, ActionFactory& af, AbsDataHandler* par); + int waitForData(); + int stopWaiting(); + int pause(); + int resume(); + int abort(); + int startScan(); + int getStatus(){return (int)m_state;} + DataCond& getDataCond(){return m_dataCond;} + void setFailed(); + bool failed(){return m_failed;} + enum State{IDLE, CONFIGURED, RUNNING, PAUSED, ABORT}; + enum Timeout{CONFIG_TIMEOUT=500};//5 seconds +protected: + void publishHistos(); + State m_state; + NestedLoop m_loops; + omni_mutex m_pause_mutex ; + omni_condition m_pause_cond ; + DataCond m_dataCond; + int m_i; + AbsDataHandler *m_handler; + unsigned m_timeout_seconds; + unsigned m_timeout_nanoseconds; + bool m_failed; + int m_timeouts; + int m_allowedTimeouts; + std::vector<std::string> m_histolist; + +}; +#endif diff --git a/rce/rcecalib/scanctrl/ScanLoop.cc b/rce/rcecalib/scanctrl/ScanLoop.cc new file mode 100644 index 0000000000000000000000000000000000000000..7105194556e1c580ca24524474c5c47c093fe05b --- /dev/null +++ b/rce/rcecalib/scanctrl/ScanLoop.cc @@ -0,0 +1,83 @@ + +#include "ScanLoop.hh" +#include "ers/ers.h" +#include <stdio.h> + +ScanLoop::ScanLoop(const char* name, unsigned n): m_nPoints(n),m_nextOuterLoop(0),m_i(0){ + strcpy(m_name,name); + ERS_ASSERT_MSG(m_nPoints>0,"a scan loop must have at least one scan point"); + } +ScanLoop::~ScanLoop(){ + std::list<LoopAction*>::iterator listit; + for(listit = m_loopActions.begin(); listit != m_loopActions.end(); listit++){ + delete *listit; + } + std::list<EndOfLoopAction*>::iterator listit2; + for(listit2 = m_endOfLoopActions.begin(); listit2 != m_endOfLoopActions.end(); listit2++){ + delete *listit2; + } +} +void ScanLoop::addLoopAction(LoopAction *la){ + m_loopActions.push_back(la); +} + +void ScanLoop::addEndOfLoopAction(EndOfLoopAction *ea){ + m_endOfLoopActions.push_back(ea); +} + +bool ScanLoop::next(){ + m_i++; + bool done=false; + if(m_i>=m_nPoints){ // loop is over + endOfLoopAction(); + if(m_nextOuterLoop==0){ + done=true; + }else{ + done=m_nextOuterLoop->next(); + reset(); + } + } + if(done==false){ + loopAction(m_i); // perform loop action unless the nested loop is at its end + } + return done; +} + +void ScanLoop::loopAction(unsigned i){ + std::list<LoopAction*>::iterator listit; + for(listit = m_loopActions.begin(); listit != m_loopActions.end(); listit++){ + (*listit)->execute(i); + } +} +void ScanLoop::endOfLoopAction(){ + std::list<EndOfLoopAction*>::iterator listit; + for(listit = m_endOfLoopActions.begin(); listit != m_endOfLoopActions.end(); listit++){ + (*listit)->execute(); + } +} + +void ScanLoop::setNextOuterLoop(ScanLoop* loop){ + m_nextOuterLoop=loop; +} +void ScanLoop::firstEvent(){ + reset(); + loopAction(m_i); +} + +void ScanLoop::print(const char* prefix){ + std::cout<<prefix<<name()<<" 0 ... "<<m_nPoints - 1<<std::endl; + std::list<LoopAction*>::iterator lait=m_loopActions.begin(); + if(lait!=m_loopActions.end()){ + std::cout<<prefix<<"Loop Actions:"<<std::endl; + for(; lait != m_loopActions.end(); lait++){ + std::cout<<prefix<<" "<<(*lait)->name()<<std::endl; + } + } + std::list<EndOfLoopAction*>::iterator elait=m_endOfLoopActions.begin(); + if(elait!=m_endOfLoopActions.end()){ + std::cout<<prefix<<"End of Loop Actions:"<<std::endl; + for(; elait != m_endOfLoopActions.end(); elait++){ + std::cout<<prefix<<" "<<(*elait)->name()<<std::endl; + } + } +} diff --git a/rce/rcecalib/scanctrl/ScanLoop.hh b/rce/rcecalib/scanctrl/ScanLoop.hh new file mode 100644 index 0000000000000000000000000000000000000000..f79ba28348bb8ce948fb86353e514f0a7b7395be --- /dev/null +++ b/rce/rcecalib/scanctrl/ScanLoop.hh @@ -0,0 +1,48 @@ +#ifndef SCANLOOP_HH +#define SCANLOOP_HH + +// Implements a nested for loop. Each loop object has a pointer to the next outer loop to call its next function. +// setupLoop is called every time the loop counter is incremented. endOfLoopAction is called at the end of the loop. +// next returns the return value of the next outer loop. The outermost loop returns if it's done (i.e. the nested +// loop is over. +// This class is the replacement for the NewDsp LoopCtrl structure. + +// C 2009 SLAC Author: Martin Kocian + +#include <string.h> +#include <vector> +#include <list> + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" + +class ScanLoop { + +public: + ScanLoop(const char* name, unsigned n); + ~ScanLoop(); + bool next(); + void reset(){m_i=0;}; + void firstEvent(); + void addLoopAction(LoopAction* la); + void addEndOfLoopAction(EndOfLoopAction* ea); + const char* name(){return m_name;} + void print(const char* prefix); + +protected: + void setNextOuterLoop(ScanLoop*); + void loopAction(unsigned); + void endOfLoopAction(); + + char m_name[128]; + unsigned m_nPoints; + ScanLoop* m_nextOuterLoop; + unsigned m_i; + std::vector<int> m_values; + std::list<LoopAction*> m_loopActions; + std::list<EndOfLoopAction*> m_endOfLoopActions; + + friend class NestedLoop; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/ScanRoot.cc b/rce/rcecalib/scanctrl/ScanRoot.cc new file mode 100644 index 0000000000000000000000000000000000000000..354864964d0ed447c2a23749e00bc26f3d4bd963 --- /dev/null +++ b/rce/rcecalib/scanctrl/ScanRoot.cc @@ -0,0 +1,72 @@ + +#include "rcecalib/scanctrl/ScanRoot.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include "rcecalib/dataproc/AbsDataHandler.hh" +#include "rcecalib/dataproc/DataProcFactory.hh" +#include "rcecalib/scanctrl/Scan.hh" +#include "rcecalib/config/ConfigIF.hh" + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/info_parser.hpp> + +#include "rcecalib/util/DataCond.hh" +#include "rcecalib/util/exceptions.hh" + +#include <string> +#include <iostream> + + +ScanRoot::ScanRoot(ConfigIF* confif, Scan *scan): + m_configIF(confif),m_dataProc(0),m_scan(scan),m_formatter(0), m_handler(0),m_receiver(0){ +} +ScanRoot::~ScanRoot(){ +} + +int ScanRoot::configureScan(boost::property_tree::ptree *scanOptions){ + //std::cout<<"Start ScanRoot configureScan"<<std::endl; + int retval=0; + //print out configuration + //write_info(std::cout,*scanOptions); + + // set up pixel modules + retval+=m_configIF->configureScan(scanOptions); + // set up data processor + printf("configIF configured\n"); + DataProcFactory dfac; + try{ //catch bad scan option parameters + delete m_dataProc; + printf("Deleted old dataproc\n"); + m_dataProc=0; + std::string dataProc = scanOptions->get<std::string>("DataProc"); + m_dataProc=dfac.createDataProcessor(dataProc.c_str(),m_configIF, scanOptions); + printf("Created dataproc of type %s\n", dataProc.c_str()); + std::string ptype = scanOptions->get<std::string>("DataHandler"); + delete m_handler; + m_handler=0; + m_handler=dfac.createDataHandler(ptype.c_str(),m_dataProc, m_scan->getDataCond(), m_configIF, scanOptions); + printf("Created data handler of type %s\n", ptype.c_str()); + std::string rtype = scanOptions->get<std::string>("Receiver"); + delete m_receiver; + m_receiver=0; + m_receiver=dfac.createReceiver(rtype.c_str(),m_handler, scanOptions); + printf("Created receiver of type %s\n", rtype.c_str()); + ERS_ASSERT_MSG(m_handler!=0,"no data handler defined"); + + // set up Scan Loops + // The action factory contains all available loop and end-of-loop actions. + // These can depend on m_config, m_dataProc, m_scan. Therefore created here. + ActionFactory af(m_configIF, m_dataProc, m_scan); + m_scan->configureScan(scanOptions, af, m_handler); + + std::cout<<"Setup done"<<std::endl; + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + ERS_ASSERT_MSG(m_dataProc!=0,"no data processor defined"); + return retval; +} + diff --git a/rce/rcecalib/scanctrl/ScanRoot.hh b/rce/rcecalib/scanctrl/ScanRoot.hh new file mode 100644 index 0000000000000000000000000000000000000000..07e5dc45cb98fddae59fed22168a8f2b7652e3bb --- /dev/null +++ b/rce/rcecalib/scanctrl/ScanRoot.hh @@ -0,0 +1,28 @@ +#ifndef SCANROOT_HH +#define SCANROOT_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include <pthread.h> + +class ConfigIF; +class AbsDataProc; +class AbsDataHandler; +class AbsFormatter; +class AbsReceiver; +class Scan; + +class ScanRoot{ +public: + ScanRoot(ConfigIF*, Scan*); + virtual ~ScanRoot(); + virtual int configureScan(boost::property_tree::ptree* scanOptions); +protected: + ConfigIF* m_configIF; + AbsDataProc* m_dataProc; + Scan* m_scan; + AbsFormatter *m_formatter; + AbsDataHandler* m_handler; + AbsReceiver* m_receiver; + +}; +#endif diff --git a/rce/rcecalib/scanctrl/SelftriggerSetup.cc b/rce/rcecalib/scanctrl/SelftriggerSetup.cc new file mode 100644 index 0000000000000000000000000000000000000000..bb8cca662e61a2de058fe5615e69b1234016d9da --- /dev/null +++ b/rce/rcecalib/scanctrl/SelftriggerSetup.cc @@ -0,0 +1,37 @@ +#include "rcecalib/scanctrl/SelftriggerSetup.hh" +#include "rcecalib/scanctrl/ScanLoop.hh" +#include <boost/property_tree/ptree.hpp> +#include "rcecalib/scanctrl/ActionFactory.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/scanctrl/EndOfLoopAction.hh" +#include "rcecalib/util/exceptions.hh" + +int SelftriggerSetup::setupLoops( NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af){ + int retval=0; + loop.clear(); + try{ //catch bad scan option parameters + // Data Taking has a single loop with one entry + ScanLoop *scanloop=new ScanLoop("Selftrigger",1); + LoopAction* conf=af->createLoopAction("CONFIGURE_MODULES"); + scanloop->addLoopAction(conf); + // LoopAction* linkmask=af->createLoopAction("SETUP_CHANNELMASK"); + //scanloop->addLoopAction(linkmask); + // End of loop actions + //The fitaction is used here to close the file with the hits if available. + EndOfLoopAction* fitaction=af->createEndOfLoopAction("FIT","CLOSE_FILE"); + scanloop->addEndOfLoopAction(fitaction); + EndOfLoopAction* resetfe=af->createEndOfLoopAction("RESET_FE",""); + scanloop->addEndOfLoopAction(resetfe); + EndOfLoopAction* disablechannels=af->createEndOfLoopAction("DISABLE_ALL_CHANNELS",""); + scanloop->addEndOfLoopAction(disablechannels); + // loop is the nested loop object + loop.addNewInnermostLoop(scanloop); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + retval=1; + } + // loop.print(); + return retval; +} diff --git a/rce/rcecalib/scanctrl/SelftriggerSetup.hh b/rce/rcecalib/scanctrl/SelftriggerSetup.hh new file mode 100644 index 0000000000000000000000000000000000000000..3fcb42bd2a12ea08f133dc3c23c59ba647789d11 --- /dev/null +++ b/rce/rcecalib/scanctrl/SelftriggerSetup.hh @@ -0,0 +1,18 @@ +#ifndef SELFTRIGGERSETUP_HH +#define SELFTRIGGERSETUP_HH + +#include "rcecalib/scanctrl/NestedLoop.hh" +#include "rcecalib/scanctrl/LoopSetup.hh" +#include "rcecalib/scanctrl/ActionFactory.hh" +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/config/ConfigIF.hh" + +class SelftriggerSetup: public LoopSetup{ +public: + SelftriggerSetup():LoopSetup(){}; + virtual ~SelftriggerSetup(){} + int setupLoops(NestedLoop& loop, boost::property_tree::ptree *scanOptions, ActionFactory* af); +}; + + +#endif diff --git a/rce/rcecalib/scanctrl/SendTriggerAction.hh b/rce/rcecalib/scanctrl/SendTriggerAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..532c587aa5ffa7f9e03e7a20b27d019bad4d23fb --- /dev/null +++ b/rce/rcecalib/scanctrl/SendTriggerAction.hh @@ -0,0 +1,19 @@ +#ifndef SENDTRIGGERACTION_HH +#define SENDTRIGGERACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class SendTriggerAction: public LoopAction{ +public: + SendTriggerAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + //std::cout<<"SendTriggerAction"<<std::endl; + return m_configIF->sendTrigger(); + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/SetChannelMaskAction.hh b/rce/rcecalib/scanctrl/SetChannelMaskAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..2a8ef252cbcb20b1dd532a7faea8039e8af06da1 --- /dev/null +++ b/rce/rcecalib/scanctrl/SetChannelMaskAction.hh @@ -0,0 +1,18 @@ +#ifndef SETCHANNELMASKACTION_HH +#define SETCHANNELMASKACTION_HH + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" + +class SetChannelMaskAction: public LoopAction{ +public: + SetChannelMaskAction(std::string name, ConfigIF* cif): + LoopAction(name),m_configIF(cif){} + int execute(int i){ + return m_configIF->setChannelMask(); + } +private: + ConfigIF* m_configIF; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/SetupMaskStageAction.hh b/rce/rcecalib/scanctrl/SetupMaskStageAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..f35eaafdb53bb830e670f91f665f24547f798366 --- /dev/null +++ b/rce/rcecalib/scanctrl/SetupMaskStageAction.hh @@ -0,0 +1,52 @@ +#ifndef SETUPMASKSTAGEACTION_HH +#define SETUPMASKSTAGEACTION_HH + + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" +#include "rcecalib/util/RceName.hh" +#include "rcecalib/dataproc/AbsDataProc.hh" +#include <boost/property_tree/ptree.hpp> +#include <string> +#include <stdio.h> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/scanctrl/RceCallback.hh" + +class SetupMaskStageAction: public LoopAction{ +public: + SetupMaskStageAction(std::string name, ConfigIF* cif, AbsDataProc* proc, boost::property_tree::ptree *pt): + LoopAction(name),m_configIF(cif),m_dataProc(proc){ + try{ + m_firstStage=pt->get<int>("firstStage"); + m_stepStage=pt->get<int>("stepStage"); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + } + int execute(int i){ + int stage=m_firstStage+i*m_stepStage; + //std::cout<<"Stage "<<stage<<std::endl; + m_dataProc->setMaskStage(stage); + ipc::CallbackParams cbp; + cbp.rce=RceName::getRceNumber(); + cbp.status=ipc::SCANNING; + cbp.maskStage=stage; + cbp.loop0=-1; + cbp.loop1=-1; + ipc::Priority pr=ipc::LOW; + if(stage%100==0)pr=ipc::HIGH; + else if(stage%10==0)pr=ipc::MEDIUM; + RceCallback::instance()->sendMsg(pr,&cbp); + return m_configIF->setupMaskStage(stage); + //std::cout<<"Post after SetupMaskStageAction"<<std::endl; + } +private: + ConfigIF* m_configIF; + AbsDataProc* m_dataProc; + unsigned short m_firstStage; + unsigned short m_stepStage; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/SetupParamAction.hh b/rce/rcecalib/scanctrl/SetupParamAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..b387bd26aebd0b809dde34e3934ca4ff1f0c5a10 --- /dev/null +++ b/rce/rcecalib/scanctrl/SetupParamAction.hh @@ -0,0 +1,45 @@ +#ifndef SETUPPARAMACTION_HH +#define SETUPPARAMACTION_HH + +#include <boost/property_tree/ptree.hpp> +#include <boost/foreach.hpp> +#include "rcecalib/util/exceptions.hh" +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <string> +#include <vector> + +class SetupParamAction: public LoopAction{ +public: + SetupParamAction(std::string name, ConfigIF* cif, boost::property_tree::ptree *pt ): + LoopAction(name),m_configIF(cif){ + try{ + m_scanParameter=pt->get<std::string>("scanParameter"); + int nPoints=pt->get<int>("nPoints"); + ERS_DEBUG(2,"scanParameter: "<<m_scanParameter); + BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt->get_child("dataPoints")){ + ERS_DEBUG(2, v.second.data()); + int data = boost::lexical_cast<int>(v.second.data()); + dataPoints.push_back(data); + } + ERS_ASSERT_MSG((int)dataPoints.size()==nPoints,"of an inconsistency in the number of scan points."); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + } + + int execute(int i){ + ERS_DEBUG(2,"SetupParamAction "<<i); + //std::cout<<"Parameter is "<<dataPoints[i]<<std::endl; + return m_configIF->setupParameter(m_scanParameter.c_str(),dataPoints[i]); + } + +private: + ConfigIF* m_configIF; + std::string m_scanParameter; + std::vector<int> dataPoints; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/SetupTriggerAction.hh b/rce/rcecalib/scanctrl/SetupTriggerAction.hh new file mode 100644 index 0000000000000000000000000000000000000000..99110980c2c8879ccdf53dc82a87555499891184 --- /dev/null +++ b/rce/rcecalib/scanctrl/SetupTriggerAction.hh @@ -0,0 +1,53 @@ +#ifndef SETUPTRIGGERACTION_HH +#define SETUPTRIGGERACTION_HH + + +#include "rcecalib/scanctrl/LoopAction.hh" +#include "rcecalib/config/ConfigIF.hh" +#include <boost/property_tree/ptree.hpp> +#include <string> +#include "rcecalib/util/exceptions.hh" + +class SetupTriggerAction: public LoopAction{ +public: + SetupTriggerAction(std::string name, ConfigIF* cif, boost::property_tree::ptree *pt): + LoopAction(name),m_configIF(cif){ + try{ + m_interval=pt->get<int>("trigOpt.eventInterval"); + m_l1delay = pt->get<int>("trigOpt.CalL1ADelay"); + m_triggermask = pt->get<int>("trigOpt.triggerMask"); + m_repetitions = pt->get<int>("trigOpt.nTriggers"); + m_deadtime = pt->get<int>("trigOpt.deadtime"); + m_hitbusconfig = pt->get<int>("trigOpt.hitbusConfig"); + m_protectFifo = pt->get("trigOpt.optionsMask.PROTECT_FIFO", 0); + } + catch(boost::property_tree::ptree_bad_path ex){ + rcecalib::Bad_ptree_param issue( ERS_HERE, ex.what()); + ers::error(issue); + } + } + int execute(int i){ + std::cout<<"Configuring trigger with interval="<<std::dec<<m_interval<<", l1 delay="<<m_l1delay<< + ", number of repetitions="<<m_repetitions<<", triggermask="<<std::hex<<m_triggermask<< + ", hitbus config="<<m_hitbusconfig<<", protectFifo="<<m_protectFifo<<std::dec<<std::endl; + m_configIF->writeHWregister(9,(unsigned)m_interval); //period + m_configIF->writeHWregister(14,(unsigned)m_repetitions); //n-1 events only + m_configIF->writeHWregister(8,(unsigned)m_l1delay); + m_configIF->writeHWregister(15,(unsigned)m_deadtime); + //m_configIF->writeHWregister(21,(unsigned)m_hitbusconfig); // per RCE + m_configIF->writeHWregister(26,(unsigned)m_protectFifo); + m_configIF->writeHWregister(11,(unsigned)m_triggermask); //trigger mask 2=cyclic + return 0; + } +private: + ConfigIF* m_configIF; + int m_interval; + int m_l1delay; + int m_triggermask; + int m_repetitions; + int m_deadtime; + int m_hitbusconfig; + int m_protectFifo; +}; + +#endif diff --git a/rce/rcecalib/scanctrl/constituents.mk b/rce/rcecalib/scanctrl/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..cc8e972699ae0b86a241b653c08e4568f7f3885f --- /dev/null +++ b/rce/rcecalib/scanctrl/constituents.mk @@ -0,0 +1,45 @@ + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := scanctrl +endif +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + modlibnames := scanctrl + endif +ifeq ($(profiler),y) +CPPFLAGS+='-D__PROFILER_ENABLED__' +endif + + +libsrcs_scanctrl := ActionFactory.cc \ + LoopFactory.cc \ + NestedLoop.cc \ + RegularScanSetup.cc \ + RegularCfgScanSetup.cc \ + IfScanSetup.cc \ + DelayScanSetup.cc \ + CosmicDataSetup.cc \ + SelftriggerSetup.cc \ + NoiseScanSetup.cc \ + Scan.cc \ + ScanLoop.cc \ + ScanRoot.cc \ + RceCallback.cc + + +libincs_scanctrl := $(ers_include_path) \ + $(owl_include_path) \ + $(ipc_include_path) \ + $(is_include_path) \ + $(oh_include_path) \ + $(boost_include_path) \ + $(omniorb_include_path) + + + + + + + + + + diff --git a/rce/rcecalib/server/.gitignore b/rce/rcecalib/server/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5761abcfdf0c26a75374c945dfe366eaeee04285 --- /dev/null +++ b/rce/rcecalib/server/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/rce/rcecalib/server/AFPHPTDCConfigFile.cc b/rce/rcecalib/server/AFPHPTDCConfigFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..9eae9479430f979dd48f5002dcf93dc5bfa48ba2 --- /dev/null +++ b/rce/rcecalib/server/AFPHPTDCConfigFile.cc @@ -0,0 +1,566 @@ +#include "rcecalib/server/AFPHPTDCConfigFile.hh" +#include "rcecalib/util/exceptions.hh" +#include <boost/algorithm/string.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <sys/stat.h> + +std::string AFPHPTDCConfigFile::getFullPath(std::string relPath){ + std::string newPath = relPath, basePath=m_moduleCfgFilePath, testName; + unsigned int pos; + // skip config file-name part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // skip "config" part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos+1,basePath.length()-pos); + else basePath=""; + // then add relative path of DAC or mask file + newPath = basePath + "calib/"+newPath; + return newPath; +} + +AFPHPTDCConfigFile::~AFPHPTDCConfigFile(){} + +unsigned AFPHPTDCConfigFile::lookupToUnsigned(std::string par, int index, int size){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par][index]; + unsigned val; + int success=convertToUnsigned(vals, val, size); + if(success==false){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} +/* +float AFPHPTDCConfigFile::lookupToFloat(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + float val; + char* end; + val=strtof(vals.c_str(), &end); + if(end-vals.c_str()!=(int)vals.size()){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} +*/ + +int AFPHPTDCConfigFile::convertToUnsigned(std::string par, unsigned &val, int size){ + char* end; + val=strtoul(par.c_str(), &end, 0); + if(end-par.c_str()!=(int)par.size()){ + return 0; + } + if(size==0 && (val&0xffffff00)!=0){ + std::cout<<"Value "<<val<<" too large."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + else if(size==1 && (val&0xffff0000)!=0){ + std::cout<<"Value "<<val<<" too large."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return 1; +} + + +void AFPHPTDCConfigFile::setupCalib(float cal[2][12][ipc::IPC_N_CALIBVALS] , std::string par, int i1, int i2){ + char pa[20]; + sprintf(pa, "%s_%d", par.c_str(), i2); + std::string pastr(pa); + if( m_params.find(pastr)==m_params.end()){ + std::cout<<"Parameter "<<pastr<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string fullpath=getFullPath(m_params[pastr][0]); + std::ifstream dacfile(fullpath.c_str()); + if(!dacfile.good()){ + std::cout<<"Cannot open file with name "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + for(int i=0;i<ipc::IPC_N_CALIBVALS;i++){ + dacfile>>cal[i1][i2][i]; + if(dacfile.eof()){ + std::cout<<"Not enough values in file "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + } +} + +void AFPHPTDCConfigFile::writeModuleConfig(ipc::AFPHPTDCModuleConfig* config, const std::string &base, const std::string &confdir, + const std::string &configname, const std::string &key){ +/* + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(base.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<" does not exist. Not writing config file"<<std::endl; + return; + } + intStat = stat((base+"/"+confdir).c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + //std::cout<<"Directory "<<base<<"/"<<confdir<<" does not exist. Creating."<<std::endl; + mkdir ((base+"/"+confdir).c_str(),0777); + mkdir ((base+"/"+confdir+"/configs").c_str(),0777); + mkdir ((base+"/"+confdir+"/masks").c_str(),0777); + mkdir ((base+"/"+confdir+"/tdacs").c_str(),0777); + mkdir ((base+"/"+confdir+"/fdacs").c_str(),0777); + } + std::string cfgname=configname; + if(key.size()!=0)cfgname+="__"+key; + std::string fullpath=base+"/"+confdir+"/configs/"+cfgname+".cfg"; + std::ofstream cfgfile(fullpath.c_str()); + cfgfile<<"# FEI4B Configuration"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Module name"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"ModuleID\t\t"<<config->idStr<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Geographical address"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"Address\t\t\t"<<(unsigned)config->FECommand.address<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Global register"<<std::endl; + cfgfile<<std::endl; + //Global register + ipc::AFPHPTDCModuleGlobal* cfg=&config->FEGlobal; + cfgfile<<"TrigCnt\t\t\t"<<cfg->TrigCnt<<std::endl; + cfgfile<<"Conf_AddrEnable\t\t"<<cfg->Conf_AddrEnable <<std::endl; + cfgfile<<"Reg2Spare\t\t"<<cfg->Reg2Spare <<std::endl; + cfgfile<<"ErrMask0\t\t"<<"0x"<<std::hex<<cfg->ErrMask0 <<std::dec<<std::endl; + cfgfile<<"ErrMask1\t\t"<<"0x"<<std::hex<<cfg->ErrMask1 <<std::dec<<std::endl; + cfgfile<<"PrmpVbpRight\t\t"<< cfg->PrmpVbpRight <<std::endl; + cfgfile<<"BufVgOpAmp\t\t"<<cfg->BufVgOpAmp <<std::endl; + cfgfile<<"Reg6Spare\t\t"<<cfg->Reg6Spare <<std::endl; + cfgfile<<"PrmpVbp\t\t\t"<<cfg->PrmpVbp <<std::endl; + cfgfile<<"TdacVbp\t\t\t"<< cfg->TdacVbp <<std::endl; + cfgfile<<"DisVbn\t\t\t"<<cfg->DisVbn <<std::endl; + cfgfile<<"Amp2Vbn\t\t\t"<<cfg->Amp2Vbn <<std::endl; + cfgfile<<"Amp2VbpFol\t\t"<<cfg->Amp2VbpFol <<std::endl; + cfgfile<<"Reg9Spare\t\t"<<cfg->Reg9Spare <<std::endl; + cfgfile<<"Amp2Vbp\t\t\t"<<cfg->Amp2Vbp <<std::endl; + cfgfile<<"FdacVbn\t\t\t"<<cfg->FdacVbn <<std::endl; + cfgfile<<"Amp2Vbpf\t\t"<<cfg->Amp2Vbpf <<std::endl; + cfgfile<<"PrmpVbnFol\t\t"<<cfg->PrmpVbnFol <<std::endl; + cfgfile<<"PrmpVbpLeft\t\t"<<cfg->PrmpVbpLeft <<std::endl; + cfgfile<<"PrmpVbpf\t\t"<<cfg->PrmpVbpf <<std::endl; + cfgfile<<"PrmpVbnLcc\t\t"<<cfg->PrmpVbnLcc <<std::endl; + cfgfile<<"Reg13Spare\t\t"<<cfg->Reg13Spare <<std::endl; + cfgfile<<"PxStrobes\t\t"<<cfg->PxStrobes <<std::endl; + cfgfile<<"S0\t\t\t"<<cfg->S0 <<std::endl; + cfgfile<<"S1\t\t\t"<<cfg->S1 <<std::endl; + cfgfile<<"LVDSDrvIref\t\t"<<cfg->LVDSDrvIref <<std::endl; + cfgfile<<"GADCOpAmp\t\t"<<cfg->GADCOpAmp <<std::endl; + cfgfile<<"PllIbias\t\t"<<cfg->PllIbias <<std::endl; + cfgfile<<"LVDSDrvVos\t\t"<<cfg->LVDSDrvVos <<std::endl; + cfgfile<<"TempSensBias\t\t"<<cfg->TempSensBias <<std::endl; + cfgfile<<"PllIcp\t\t\t"<<cfg->PllIcp <<std::endl; + cfgfile<<"Reg17Spare\t\t"<<cfg->Reg17Spare <<std::endl; + cfgfile<<"PlsrIdacRamp\t\t"<<cfg->PlsrIdacRamp <<std::endl; + cfgfile<<"VrefDigTune\t\t"<<cfg->VrefDigTune <<std::endl; + cfgfile<<"PlsrVgOPamp\t\t"<<cfg->PlsrVgOPamp <<std::endl; + cfgfile<<"PlsrDacBias\t\t"<<cfg->PlsrDacBias <<std::endl; + cfgfile<<"VrefAnTune\t\t"<<cfg->VrefAnTune <<std::endl; + cfgfile<<"Vthin_AltCoarse\t\t"<<cfg->Vthin_AltCoarse <<std::endl; + cfgfile<<"Vthin_AltFine\t\t"<<cfg->Vthin_AltFine <<std::endl; + cfgfile<<"PlsrDAC\t\t\t"<<cfg->PlsrDAC <<std::endl; + cfgfile<<"DIGHITIN_Sel\t\t"<<cfg->DIGHITIN_Sel <<std::endl; + cfgfile<<"DINJ_Override\t\t"<<cfg->DINJ_Override <<std::endl; + cfgfile<<"HITLD_In\t\t"<<cfg->HITLD_In <<std::endl; + cfgfile<<"Reg21Spare\t\t"<<cfg->Reg21Spare <<std::endl; + cfgfile<<"Reg22Spare2\t\t"<<cfg->Reg22Spare2 <<std::endl; + cfgfile<<"Colpr_Addr\t\t"<<cfg->Colpr_Addr <<std::endl; + cfgfile<<"Colpr_Mode\t\t"<<cfg->Colpr_Mode <<std::endl; + cfgfile<<"Reg22Spare1\t\t"<<cfg->Reg22Spare1 <<std::endl; + cfgfile<<"DisableColumnCnfg0\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg0 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg1\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg1 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg2\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg2 <<std::dec<<std::endl; + cfgfile<<"TrigLat\t\t\t"<< cfg->TrigLat <<std::endl; + cfgfile<<"CMDcnt\t\t\t"<<cfg->CMDcnt <<std::endl; + cfgfile<<"StopModeCnfg\t\t"<<cfg->StopModeCnfg <<std::endl; + cfgfile<<"HitDiscCnfg\t\t"<<cfg->HitDiscCnfg <<std::endl; + cfgfile<<"EN_PLL\t\t\t"<<cfg->EN_PLL <<std::endl; + cfgfile<<"Efuse_sense\t\t"<<cfg->Efuse_sense <<std::endl; + cfgfile<<"Stop_Clk\t\t"<<cfg->Stop_Clk <<std::endl; + cfgfile<<"ReadErrorReq\t\t"<<cfg->ReadErrorReq <<std::endl; + cfgfile<<"Reg27Spare1\t\t"<<cfg->Reg27Spare1 <<std::endl; + cfgfile<<"GADC_Enable\t\t"<<cfg->GADC_Enable <<std::endl; + cfgfile<<"ShiftReadBack\t\t"<<cfg->ShiftReadBack <<std::endl; + cfgfile<<"Reg27Spare2\t\t"<<cfg->Reg27Spare2 <<std::endl; + cfgfile<<"GateHitOr\t\t"<<cfg->GateHitOr <<std::endl; + cfgfile<<"CalEn\t\t\t"<<cfg->CalEn <<std::endl; + cfgfile<<"SR_clr\t\t\t"<<cfg->SR_clr <<std::endl; + cfgfile<<"Latch_en\t\t"<<cfg->Latch_en <<std::endl; + cfgfile<<"SR_Clock\t\t"<<cfg->SR_Clock <<std::endl; + cfgfile<<"LVDSDrvSet06\t\t"<<cfg->LVDSDrvSet06 <<std::endl; + cfgfile<<"Reg28Spare\t\t"<<cfg->Reg28Spare <<std::endl; + cfgfile<<"EN40M\t\t\t"<<cfg->EN40M <<std::endl; + cfgfile<<"EN80M\t\t\t"<<cfg->EN80M <<std::endl; + cfgfile<<"CLK0_S2\t\t\t"<<(cfg->CLK0 &0x1)<<std::endl; + cfgfile<<"CLK0_S1\t\t\t"<<((cfg->CLK0>>1)&0x1 )<<std::endl; + cfgfile<<"CLK0_S0\t\t\t"<<((cfg->CLK0>>2)&0x1 )<<std::endl; + cfgfile<<"CLK1_S2\t\t\t"<<(cfg->CLK1&0x1 )<<std::endl; + cfgfile<<"CLK1_S1\t\t\t"<<((cfg->CLK1>>1)&0x1 )<<std::endl; + cfgfile<<"CLK1_S0\t\t\t"<<((cfg->CLK1>>2)&0x1 )<<std::endl; + cfgfile<<"EN160M\t\t\t"<<cfg->EN160M <<std::endl; + cfgfile<<"EN320M\t\t\t"<<cfg->EN320M <<std::endl; + cfgfile<<"Reg29Spare1\t\t"<<cfg->Reg29Spare1 <<std::endl; + cfgfile<<"no8b10b\t\t\t"<<cfg->no8b10b <<std::endl; + cfgfile<<"Clk2OutCnfg\t\t"<<cfg->Clk2OutCnfg <<std::endl; + cfgfile<<"EmptyRecord\t\t"<<cfg->EmptyRecord <<std::endl; + cfgfile<<"Reg29Spare2\t\t"<<cfg->Reg29Spare2 <<std::endl; + cfgfile<<"LVDSDrvEn\t\t"<<cfg->LVDSDrvEn <<std::endl; + cfgfile<<"LVDSDrvSet30\t\t"<<cfg->LVDSDrvSet30 <<std::endl; + cfgfile<<"LVDSDrvSet12\t\t"<<cfg->LVDSDrvSet12 <<std::endl; + cfgfile<<"TempSensDiodeSel\t"<<cfg->TempSensDiodeSel <<std::endl; + cfgfile<<"TempSensDisable\t\t"<<cfg->TempSensDisable <<std::endl; + cfgfile<<"IleakRange\t\t"<<cfg->IleakRange <<std::endl; + cfgfile<<"Reg30Spare\t\t"<<cfg->Reg30Spare <<std::endl; + cfgfile<<"PlsrRiseUpTau\t\t"<<cfg->PlsrRiseUpTau <<std::endl; + cfgfile<<"PlsrPwr\t\t\t"<<cfg->PlsrPwr <<std::endl; + cfgfile<<"PlsrDelay\t\t"<<cfg->PlsrDelay <<std::endl; + cfgfile<<"ExtDigCalSW\t\t"<<cfg->ExtDigCalSW <<std::endl; + cfgfile<<"ExtAnaCalSW\t\t"<<cfg->ExtAnaCalSW <<std::endl; + cfgfile<<"Reg31Spare\t\t"<<cfg->Reg31Spare <<std::endl; + cfgfile<<"GADCSel\t\t\t"<<cfg->GADCSel <<std::endl; + cfgfile<<"SELB0\t\t\t"<<cfg->SELB0 <<std::endl; + cfgfile<<"SELB1\t\t\t"<<cfg->SELB1 <<std::endl; + cfgfile<<"SELB2\t\t\t"<<cfg->SELB2 <<std::endl; + cfgfile<<"Reg34Spare1\t\t"<<cfg->Reg34Spare1 <<std::endl; + cfgfile<<"PrmpVbpMsnEn\t\t"<<cfg->PrmpVbpMsnEn <<std::endl; + cfgfile<<"Reg34Spare2\t\t"<<cfg->Reg34Spare2 <<std::endl; + cfgfile<<"Chip_SN\t\t\t"<<cfg->Chip_SN <<std::endl; + cfgfile<<"Reg1Spare\t\t"<<cfg->Reg1Spare <<std::endl; + cfgfile<<"SmallHitErase\t\t"<<cfg->SmallHitErase <<std::endl; + cfgfile<<"Eventlimit\t\t"<<cfg->Eventlimit <<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Pixel register"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"enable\t\t\t"<<confdir<<"/masks/enable_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"largeCap\t\t"<<confdir<<"/masks/largeCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"smallCap\t\t"<<confdir<<"/masks/smallCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"hitbus\t\t\t"<<confdir<<"/masks/hitbus_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"tdac\t\t\t"<<confdir<<"/tdacs/tdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"fdac\t\t\t"<<confdir<<"/fdacs/fdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Charge injection parameters"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"cinjLo\t\t\t"<<config->FECalib.cinjLo <<std::endl; + cfgfile<<"cinjHi\t\t\t"<<config->FECalib.cinjHi <<std::endl; + cfgfile<<"vcalCoeff[0]\t\t"<<config->FECalib.vcalCoeff[0] <<std::endl; + cfgfile<<"vcalCoeff[1]\t\t"<<config->FECalib.vcalCoeff[1] <<std::endl; + cfgfile<<"vcalCoeff[2]\t\t"<<config->FECalib.vcalCoeff[2] <<std::endl; + cfgfile<<"vcalCoeff[3]\t\t"<<config->FECalib.vcalCoeff[3] <<std::endl; + cfgfile<<"chargeCoeffClo\t\t"<<config->FECalib.chargeCoeffClo<<std::endl; + cfgfile<<"chargeCoeffChi\t\t"<<config->FECalib.chargeCoeffChi<<std::endl; + cfgfile<<"chargeOffsetClo\t\t"<<config->FECalib.chargeOffsetClo<<std::endl; + cfgfile<<"chargeOffsetChi\t\t"<<config->FECalib.chargeOffsetChi<<std::endl; + cfgfile<<"monleakCoeff\t\t"<<config->FECalib.monleakCoeff<<std::endl; + writeMaskFile(ipc::enable, config, base+"/"+confdir+"/masks/enable_"+cfgname+".dat"); + writeMaskFile(ipc::largeCap, config, base+"/"+confdir+"/masks/largeCap_"+cfgname+".dat"); + writeMaskFile(ipc::smallCap, config, base+"/"+confdir+"/masks/smallCap_"+cfgname+".dat"); + writeMaskFile(ipc::hitbus, config, base+"/"+confdir+"/masks/hitbus_"+cfgname+".dat"); + + writeDacFile(config->FETrims.dacThresholdTrim, base+"/"+confdir+"/tdacs/tdac_"+cfgname+".dat"); + writeDacFile(config->FETrims.dacFeedbackTrim, base+"/"+confdir+"/fdacs/fdac_"+cfgname+".dat"); + + */ + +} + +void AFPHPTDCConfigFile::writeCalibFile(float cal[2][12][ipc::IPC_N_CALIBVALS] , const std::string filename, int i1, int i2){ + std::ofstream maskfile(filename.c_str()); + for (int i=0;i<ipc::IPC_N_CALIBVALS;i++) + maskfile<<cal[i1][i2][i]; + maskfile<<std::endl; +} + +void AFPHPTDCConfigFile::readModuleConfig(ipc::AFPHPTDCModuleConfig* cfg, std::string filename){ + //clear structure + char* ccfg=(char*)cfg; + for (unsigned int i=0;i<sizeof(ipc::AFPHPTDCModuleConfig);i++)ccfg[i]=0; + //open file + m_moduleCfgFile=new std::ifstream(filename.c_str()); + if(!m_moduleCfgFile->good()){ + std::cout<<"Cannot open file with name "<<filename<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + m_moduleCfgFilePath = filename; + // parse config file + std::string inpline; + m_params.clear(); + while(true){ + getline(*m_moduleCfgFile, inpline); + if(m_moduleCfgFile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" \t"), boost::token_compress_on ); + if(splitVec.size()<2){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + for (size_t i=1;i<splitVec.size();i++) + m_params[splitVec[0]].push_back(splitVec[i]); + } + } + // Module name + std::string modname; + if( m_params.find("ModuleID")==m_params.end()){ + std::cout<<"No Module ID defined."<<std::endl; + }else{ + modname=m_params["ModuleID"][0]; + } + sprintf((char*)cfg->idStr, "%s", modname.c_str()); + cfg->test = lookupToUnsigned("test", 0, 1); + cfg->tdcControl = lookupToUnsigned("tdcControl", 0); + cfg->run = lookupToUnsigned("run", 0); + cfg->bypassLut = lookupToUnsigned("bypassLut", 0); + cfg->localClockEn = lookupToUnsigned("localClockEn", 0); + cfg->calClockEn = lookupToUnsigned("calClockEn", 0); + cfg->refEn = lookupToUnsigned("refEn", 0); + cfg->hitTestEn = lookupToUnsigned("hitTestEn", 0); + cfg->inputSel = lookupToUnsigned("inputSel", 0); + cfg->address = lookupToUnsigned("address", 0); + cfg->fanspeed = lookupToUnsigned("fanspeed", 0); + cfg->channelEn = lookupToUnsigned("channelEn", 0, 1); + + for (int i=0;i<3;i++){ + cfg->test_select[i] = lookupToUnsigned("test_select", i); + cfg->enable_error_mark[i] = lookupToUnsigned("enable_error_mark", i); + cfg->enable_error_bypass[i] = lookupToUnsigned("enable_error_bypass", i); + cfg->enable_error[i] = lookupToUnsigned("enable_error", i, 1); + cfg->readout_single_cycle_speed[i] = lookupToUnsigned("readout_single_cycle_speed", i); + cfg->serial_delay[i] = lookupToUnsigned("serial_delay", i); + cfg->strobe_select[i] = lookupToUnsigned("strobe_select", i); + cfg->readout_speed_select[i] = lookupToUnsigned("readout_speed_select", i); + cfg->token_delay[i] = lookupToUnsigned("token_delay", i); + cfg->enable_local_trailer[i] = lookupToUnsigned("enable_local_trailer", i); + cfg->enable_local_header[i] = lookupToUnsigned("enable_local_header", i); + cfg->enable_global_trailer[i] = lookupToUnsigned("enable_global_trailer", i); + cfg->enable_global_header[i] = lookupToUnsigned("enable_global_header", i); + cfg->keep_token[i] = lookupToUnsigned("keep_token", i); + cfg->master[i] = lookupToUnsigned("master", i); + cfg->enable_bytewise[i] = lookupToUnsigned("enable_bytewise", i); + cfg->enable_serial[i] = lookupToUnsigned("enable_serial", i); + cfg->enable_jtag_readout[i] = lookupToUnsigned("enable_jtag_readout", i); + cfg->tdc_id[i] = lookupToUnsigned("tdc_id", i); + cfg->select_bypass_inputs[i] = lookupToUnsigned("select_bypass_inputs", i); + cfg->readout_fifo_size[i] = lookupToUnsigned("readout_fifo_size", i); + cfg->reject_count_offset[i] = lookupToUnsigned("reject_count_offset", i, 1); + cfg->search_window[i] = lookupToUnsigned("search_window", i, 1); + cfg->match_window[i] = lookupToUnsigned("match_window", i, 1); + cfg->leading_resolution[i] = lookupToUnsigned("leading_resolution", i); + cfg->fixed_pattern[i] = lookupToUnsigned("fixed_pattern", i, 2); + cfg->enable_fixed_pattern[i] = lookupToUnsigned("enable_fixed_pattern", i); + cfg->max_event_size[i] = lookupToUnsigned("max_event_size", i); + cfg->reject_readout_fifo_full[i] = lookupToUnsigned("reject_readout_fifo_full", i); + cfg->enable_readout_occupancy[i] = lookupToUnsigned("enable_readout_occupancy", i); + cfg->enable_readout_separator[i] = lookupToUnsigned("enable_readout_separator", i); + cfg->enable_overflow_detect[i] = lookupToUnsigned("enable_overflow_detect", i); + cfg->enable_relative[i] = lookupToUnsigned("enable_relative", i); + cfg->enable_automatic_reject[i] = lookupToUnsigned("enable_automatic_reject", i); + cfg->event_count_offset[i] = lookupToUnsigned("event_count_offset", i, 1); + cfg->trigger_count_offset[i] = lookupToUnsigned("trigger_count_offset", i, 1); + cfg->enable_set_counters_on_bunch_reset[i] = lookupToUnsigned("enable_set_counters_on_bunch_reset", i); + cfg->enable_master_reset_code[i] = lookupToUnsigned("enable_master_reset_code", i); + cfg->enable_master_reset_code_on_event_reset[i] = lookupToUnsigned("enable_master_reset_code_on_event_reset", i); + cfg->enable_reset_channel_buffer_when_separator[i] = lookupToUnsigned("enable_reset_channel_buffer_when_separator", i); + cfg->enable_separator_on_event_reset[i] = lookupToUnsigned("enable_separator_on_event_reset", i); + cfg->enable_separator_on_bunch_reset[i] = lookupToUnsigned("enable_separator_on_bunch_reset", i); + cfg->enable_direct_event_reset[i] = lookupToUnsigned("enable_direct_event_reset", i); + cfg->enable_direct_bunch_reset[i] = lookupToUnsigned("enable_direct_bunch_reset", i); + cfg->enable_direct_trigger[i] = lookupToUnsigned("enable_direct_trigger", i); + for (int j=0;j<32;j++){ + char offs[32]; + sprintf(offs, "offset%d", j); + cfg->offset[j][i] = lookupToUnsigned(offs, i, 1); + } + cfg->coarse_count_offset[i] = lookupToUnsigned("coarse_count_offset", i, 1); + cfg->dll_tap_adjust3_0[i] = lookupToUnsigned("dll_tap_adjust3_0", i, 1); + cfg->dll_tap_adjust7_4[i] = lookupToUnsigned("dll_tap_adjust7_4", i, 1); + cfg->dll_tap_adjust11_8[i] = lookupToUnsigned("dll_tap_adjust11_8", i, 1); + cfg->dll_tap_adjust15_12[i] = lookupToUnsigned("dll_tap_adjust15_12", i, 1); + cfg->dll_tap_adjust19_16[i] = lookupToUnsigned("dll_tap_adjust19_16", i, 1); + cfg->dll_tap_adjust23_20[i] = lookupToUnsigned("dll_tap_adjust23_20", i, 1); + cfg->dll_tap_adjust27_24[i] = lookupToUnsigned("dll_tap_adjust27_24", i, 1); + cfg->dll_tap_adjust31_28[i] = lookupToUnsigned("dll_tap_adjust31_28", i, 1); + cfg->rc_adjust[i] = lookupToUnsigned("rc_adjust", i, 1); + cfg->not_used[i] = lookupToUnsigned("not_used", i); + cfg->low_power_mode[i] = lookupToUnsigned("low_power_mode", i); + cfg->width_select[i] = lookupToUnsigned("width_select", i); + cfg->vernier_offset[i] = lookupToUnsigned("vernier_offset", i); + cfg->dll_control[i] = lookupToUnsigned("dll_control", i); + cfg->dead_time[i] = lookupToUnsigned("dead_time", i); + cfg->test_invert[i] = lookupToUnsigned("test_invert", i); + cfg->test_mode[i] = lookupToUnsigned("test_mode", i); + cfg->enable_trailing[i] = lookupToUnsigned("enable_trailing", i); + cfg->enable_leading[i] = lookupToUnsigned("enable_leading", i); + cfg->mode_rc_compression[i] = lookupToUnsigned("mode_rc_compression", i); + cfg->mode_rc[i] = lookupToUnsigned("mode_rc", i); + cfg->dll_mode[i] = lookupToUnsigned("dll_mode", i); + cfg->pll_control[i] = lookupToUnsigned("pll_control", i); + cfg->serial_clock_delay[i] = lookupToUnsigned("serial_clock_delay", i); + cfg->io_clock_delay[i] = lookupToUnsigned("io_clock_delay", i); + cfg->core_clock_delay[i] = lookupToUnsigned("core_clock_delay", i); + cfg->dll_clock_delay[i] = lookupToUnsigned("dll_clock_delay", i); + cfg->serial_clock_source[i] = lookupToUnsigned("serial_clock_source", i); + cfg->io_clock_source[i] = lookupToUnsigned("io_clock_source", i); + cfg->core_clock_source[i] = lookupToUnsigned("core_clock_source", i); + cfg->dll_clock_source[i] = lookupToUnsigned("dll_clock_source", i); + cfg->roll_over[i] = lookupToUnsigned("roll_over", i, 1); + cfg->enable_matching[i] = lookupToUnsigned("enable_matching", i); + cfg->enable_pair[i] = lookupToUnsigned("enable_pair", i); + cfg->enable_ttl_serial[i] = lookupToUnsigned("enable_ttl_serial", i); + cfg->enable_ttl_control[i] = lookupToUnsigned("enable_ttl_control", i); + cfg->enable_ttl_reset[i] = lookupToUnsigned("enable_ttl_reset", i); + cfg->enable_ttl_clock[i] = lookupToUnsigned("enable_ttl_clock", i); + cfg->enable_ttl_hit[i] = lookupToUnsigned("enable_ttl_hit", i); + } + for(int i=0;i<12;i++){ + setupCalib(cfg->calib, "Inl", 0, i); + setupCalib(cfg->calib, "Dnl", 1, i); + } + delete m_moduleCfgFile; +} + +void AFPHPTDCConfigFile::dump(const ipc::AFPHPTDCModuleConfig *cfg){ +std::cout<<"FPGA Register Fields:"<<std::endl; +std::cout<<"====================="<<std::endl; +std::cout<<"idStr "<<cfg->idStr<<std::endl; +std::cout<<"test "<<(unsigned)cfg->test<<std::endl; +std::cout<<"tdcControl "<<(unsigned)cfg->tdcControl<<std::endl; +std::cout<<"run "<<(unsigned)cfg->run<<std::endl; +std::cout<<"bypassLut "<<(unsigned)cfg->bypassLut<<std::endl; +std::cout<<"localClockEn "<<(unsigned)cfg->localClockEn<<std::endl; +std::cout<<"calClockEn "<<(unsigned)cfg->calClockEn<<std::endl; +std::cout<<"refEn "<<(unsigned)cfg->refEn<<std::endl; +std::cout<<"hitTestEn "<<(unsigned)cfg->hitTestEn<<std::endl; +std::cout<<"inputSel "<<(unsigned)cfg->inputSel<<std::endl; +std::cout<<"address "<<(unsigned)cfg->address<<std::endl; +std::cout<<"fanspeed "<<(unsigned)cfg->fanspeed<<std::endl<<std::endl; +std::cout<<"channelEn "<<(unsigned)cfg->channelEn<<std::endl<<std::endl; + +std::cout<<"TDC Configuration Fields:"<<std::endl; +std::cout<<"========================="<<std::endl; +for(int i=0;i<2;i++){ + std::cout<<"test_select "<<(unsigned)cfg->test_select[0]<<" "<<(unsigned)cfg->test_select[1]<<" "<<(unsigned)cfg->test_select[2]<<std::endl; + std::cout<<"enable_error_mark "<<(unsigned)cfg->enable_error_mark[0]<<" "<<(unsigned)cfg->enable_error_mark[1]<<" "<<(unsigned)cfg->enable_error_mark[2]<<std::endl; + std::cout<<"enable_error_bypass "<<(unsigned)cfg->enable_error_bypass[0]<<" "<<(unsigned)cfg->enable_error_bypass[1]<<" "<<(unsigned)cfg->enable_error_bypass[2]<<std::endl; + std::cout<<"enable_error "<<(unsigned)cfg->enable_error[0]<<" "<<(unsigned)cfg->enable_error[1]<<" "<<(unsigned)cfg->enable_error[2]<<std::endl; + std::cout<<"readout_single_cycle_speed "<<(unsigned)cfg->readout_single_cycle_speed[0]<<" "<<(unsigned)cfg->readout_single_cycle_speed[1]<<" "<<(unsigned)cfg->readout_single_cycle_speed[2]<<std::endl; + std::cout<<"serial_delay "<<(unsigned)cfg->serial_delay[0]<<" "<<(unsigned)cfg->serial_delay[1]<<" "<<(unsigned)cfg->serial_delay[2]<<std::endl; + std::cout<<"strobe_select "<<(unsigned)cfg->strobe_select[0]<<" "<<(unsigned)cfg->strobe_select[1]<<" "<<(unsigned)cfg->strobe_select[2]<<std::endl; + std::cout<<"readout_speed_select "<<(unsigned)cfg->readout_speed_select[0]<<" "<<(unsigned)cfg->readout_speed_select[1]<<" "<<(unsigned)cfg->readout_speed_select[2]<<std::endl; + std::cout<<"token_delay "<<(unsigned)cfg->token_delay[0]<<" "<<(unsigned)cfg->token_delay[1]<<" "<<(unsigned)cfg->token_delay[2]<<std::endl; + std::cout<<"enable_local_trailer "<<(unsigned)cfg->enable_local_trailer[0]<<" "<<(unsigned)cfg->enable_local_trailer[1]<<" "<<(unsigned)cfg->enable_local_trailer[2]<<std::endl; + std::cout<<"enable_local_header "<<(unsigned)cfg->enable_local_header[0]<<" "<<(unsigned)cfg->enable_local_header[1]<<" "<<(unsigned)cfg->enable_local_header[2]<<std::endl; + std::cout<<"enable_global_trailer "<<(unsigned)cfg->enable_global_trailer[0]<<" "<<(unsigned)cfg->enable_global_trailer[1]<<" "<<(unsigned)cfg->enable_global_trailer[2]<<std::endl; + std::cout<<"enable_global_header "<<(unsigned)cfg->enable_global_header[0]<<" "<<(unsigned)cfg->enable_global_header[1]<<" "<<(unsigned)cfg->enable_global_header[2]<<std::endl; + std::cout<<"keep_token "<<(unsigned)cfg->keep_token[0]<<" "<<(unsigned)cfg->keep_token[1]<<" "<<(unsigned)cfg->keep_token[2]<<std::endl; + std::cout<<"master "<<(unsigned)cfg->master[0]<<" "<<(unsigned)cfg->master[1]<<" "<<(unsigned)cfg->master[2]<<std::endl; + std::cout<<"enable_bytewise "<<(unsigned)cfg->enable_bytewise[0]<<" "<<(unsigned)cfg->enable_bytewise[1]<<" "<<(unsigned)cfg->enable_bytewise[2]<<std::endl; + std::cout<<"enable_serial "<<(unsigned)cfg->enable_serial[0]<<" "<<(unsigned)cfg->enable_serial[1]<<" "<<(unsigned)cfg->enable_serial[2]<<std::endl; + std::cout<<"enable_jtag_readout "<<(unsigned)cfg->enable_jtag_readout[0]<<" "<<(unsigned)cfg->enable_jtag_readout[1]<<" "<<(unsigned)cfg->enable_jtag_readout[2]<<std::endl; + std::cout<<"tdc_id "<<(unsigned)cfg->tdc_id[0]<<" "<<(unsigned)cfg->tdc_id[1]<<" "<<(unsigned)cfg->tdc_id[2]<<std::endl; + std::cout<<"select_bypass_inputs "<<(unsigned)cfg->select_bypass_inputs[0]<<" "<<(unsigned)cfg->select_bypass_inputs[1]<<" "<<(unsigned)cfg->select_bypass_inputs[2]<<std::endl; + std::cout<<"readout_fifo_size "<<(unsigned)cfg->readout_fifo_size[0]<<" "<<(unsigned)cfg->readout_fifo_size[1]<<" "<<(unsigned)cfg->readout_fifo_size[2]<<std::endl; + std::cout<<"reject_count_offset "<<(unsigned)cfg->reject_count_offset[0]<<" "<<(unsigned)cfg->reject_count_offset[1]<<" "<<(unsigned)cfg->reject_count_offset[2]<<std::endl; + std::cout<<"search_window "<<(unsigned)cfg->search_window[0]<<" "<<(unsigned)cfg->search_window[1]<<" "<<(unsigned)cfg->search_window[2]<<std::endl; + std::cout<<"match_window "<<(unsigned)cfg->match_window[0]<<" "<<(unsigned)cfg->match_window[1]<<" "<<(unsigned)cfg->match_window[2]<<std::endl; + std::cout<<"leading_resolution "<<(unsigned)cfg->leading_resolution[0]<<" "<<(unsigned)cfg->leading_resolution[1]<<" "<<(unsigned)cfg->leading_resolution[2]<<std::endl; + std::cout<<"fixed_pattern "<<(unsigned)cfg->fixed_pattern[0]<<" "<<(unsigned)cfg->fixed_pattern[1]<<" "<<(unsigned)cfg->fixed_pattern[2]<<std::endl; + std::cout<<"enable_fixed_pattern "<<(unsigned)cfg->enable_fixed_pattern[0]<<" "<<(unsigned)cfg->enable_fixed_pattern[1]<<" "<<(unsigned)cfg->enable_fixed_pattern[2]<<std::endl; + std::cout<<"max_event_size "<<(unsigned)cfg->max_event_size[0]<<" "<<(unsigned)cfg->max_event_size[1]<<" "<<(unsigned)cfg->max_event_size[2]<<std::endl; + std::cout<<"reject_readout_fifo_full "<<(unsigned)cfg->reject_readout_fifo_full[0]<<" "<<(unsigned)cfg->reject_readout_fifo_full[1]<<" "<<(unsigned)cfg->reject_readout_fifo_full[2]<<std::endl; + std::cout<<"enable_readout_occupancy "<<(unsigned)cfg->enable_readout_occupancy[0]<<" "<<(unsigned)cfg->enable_readout_occupancy[1]<<" "<<(unsigned)cfg->enable_readout_occupancy[2]<<std::endl; + std::cout<<"enable_readout_separator "<<(unsigned)cfg->enable_readout_separator[0]<<" "<<(unsigned)cfg->enable_readout_separator[1]<<" "<<(unsigned)cfg->enable_readout_separator[2]<<std::endl; + std::cout<<"enable_overflow_detect "<<(unsigned)cfg->enable_overflow_detect[0]<<" "<<(unsigned)cfg->enable_overflow_detect[1]<<" "<<(unsigned)cfg->enable_overflow_detect[2]<<std::endl; + std::cout<<"enable_relative "<<(unsigned)cfg->enable_relative[0]<<" "<<(unsigned)cfg->enable_relative[1]<<" "<<(unsigned)cfg->enable_relative[2]<<std::endl; + std::cout<<"enable_automatic_reject "<<(unsigned)cfg->enable_automatic_reject[0]<<" "<<(unsigned)cfg->enable_automatic_reject[1]<<" "<<(unsigned)cfg->enable_automatic_reject[2]<<std::endl; + std::cout<<"event_count_offset "<<(unsigned)cfg->event_count_offset[0]<<" "<<(unsigned)cfg->event_count_offset[1]<<" "<<(unsigned)cfg->event_count_offset[2]<<std::endl; + std::cout<<"trigger_count_offset "<<(unsigned)cfg->trigger_count_offset[0]<<" "<<(unsigned)cfg->trigger_count_offset[1]<<" "<<(unsigned)cfg->trigger_count_offset[2]<<std::endl; + std::cout<<"enable_set_counters_on_bunch_reset "<<(unsigned)cfg->enable_set_counters_on_bunch_reset[0]<<" "<<(unsigned)cfg->enable_set_counters_on_bunch_reset[1]<<" "<<(unsigned)cfg->enable_set_counters_on_bunch_reset[2]<<std::endl; + std::cout<<"enable_master_reset_code "<<(unsigned)cfg->enable_master_reset_code[0]<<" "<<(unsigned)cfg->enable_master_reset_code[1]<<" "<<(unsigned)cfg->enable_master_reset_code[2]<<std::endl; + std::cout<<"enable_master_reset_code_on_event_reset "<<(unsigned)cfg->enable_master_reset_code_on_event_reset[0]<<" "<<(unsigned)cfg->enable_master_reset_code_on_event_reset[1]<<" "<<(unsigned)cfg->enable_master_reset_code_on_event_reset[2]<<std::endl; + std::cout<<"enable_reset_channel_buffer_when_separator "<<(unsigned)cfg->enable_reset_channel_buffer_when_separator[0]<<" "<<(unsigned)cfg->enable_reset_channel_buffer_when_separator[1]<<" "<<(unsigned)cfg->enable_reset_channel_buffer_when_separator[2]<<std::endl; + std::cout<<"enable_separator_on_event_reset "<<(unsigned)cfg->enable_separator_on_event_reset[0]<<" "<<(unsigned)cfg->enable_separator_on_event_reset[1]<<" "<<(unsigned)cfg->enable_separator_on_event_reset[2]<<std::endl; + std::cout<<"enable_separator_on_bunch_reset "<<(unsigned)cfg->enable_separator_on_bunch_reset[0]<<" "<<(unsigned)cfg->enable_separator_on_bunch_reset[1]<<" "<<(unsigned)cfg->enable_separator_on_bunch_reset[2]<<std::endl; + std::cout<<"enable_direct_event_reset "<<(unsigned)cfg->enable_direct_event_reset[0]<<" "<<(unsigned)cfg->enable_direct_event_reset[1]<<" "<<(unsigned)cfg->enable_direct_event_reset[2]<<std::endl; + std::cout<<"enable_direct_bunch_reset "<<(unsigned)cfg->enable_direct_bunch_reset[0]<<" "<<(unsigned)cfg->enable_direct_bunch_reset[1]<<" "<<(unsigned)cfg->enable_direct_bunch_reset[2]<<std::endl; + std::cout<<"enable_direct_trigger "<<(unsigned)cfg->enable_direct_trigger[0]<<" "<<(unsigned)cfg->enable_direct_trigger[1]<<" "<<(unsigned)cfg->enable_direct_trigger[2]<<std::endl; + for(int j=31;j>=0;j--){ + std::cout<<"offset"<<j<<" "<<(unsigned)cfg->offset[j][0]<<" "<<(unsigned)cfg->offset[j][1]<<" "<<(unsigned)cfg->offset[j][2]<<std::endl; + } + std::cout<<"coarse_count_offset "<<(unsigned)cfg->coarse_count_offset[0]<<" "<<(unsigned)cfg->coarse_count_offset[1]<<" "<<(unsigned)cfg->coarse_count_offset[2]<<std::endl; + std::cout<<"dll_tap_adjust3_0 "<<(unsigned)cfg->dll_tap_adjust3_0[0]<<" "<<(unsigned)cfg->dll_tap_adjust3_0[1]<<" "<<(unsigned)cfg->dll_tap_adjust3_0[2]<<std::endl; + std::cout<<"dll_tap_adjust7_4 "<<(unsigned)cfg->dll_tap_adjust7_4[0]<<" "<<(unsigned)cfg->dll_tap_adjust7_4[1]<<" "<<(unsigned)cfg->dll_tap_adjust7_4[2]<<std::endl; + std::cout<<"dll_tap_adjust11_8 "<<(unsigned)cfg->dll_tap_adjust11_8[0]<<" "<<(unsigned)cfg->dll_tap_adjust11_8[1]<<" "<<(unsigned)cfg->dll_tap_adjust11_8[2]<<std::endl; + std::cout<<"dll_tap_adjust15_12 "<<(unsigned)cfg->dll_tap_adjust15_12[0]<<" "<<(unsigned)cfg->dll_tap_adjust15_12[1]<<" "<<(unsigned)cfg->dll_tap_adjust15_12[2]<<std::endl; + std::cout<<"dll_tap_adjust19_16 "<<(unsigned)cfg->dll_tap_adjust19_16[0]<<" "<<(unsigned)cfg->dll_tap_adjust19_16[1]<<" "<<(unsigned)cfg->dll_tap_adjust19_16[2]<<std::endl; + std::cout<<"dll_tap_adjust23_20 "<<(unsigned)cfg->dll_tap_adjust23_20[0]<<" "<<(unsigned)cfg->dll_tap_adjust23_20[1]<<" "<<(unsigned)cfg->dll_tap_adjust23_20[2]<<std::endl; + std::cout<<"dll_tap_adjust27_24 "<<(unsigned)cfg->dll_tap_adjust27_24[0]<<" "<<(unsigned)cfg->dll_tap_adjust27_24[1]<<" "<<(unsigned)cfg->dll_tap_adjust27_24[2]<<std::endl; + std::cout<<"dll_tap_adjust31_28 "<<(unsigned)cfg->dll_tap_adjust31_28[0]<<" "<<(unsigned)cfg->dll_tap_adjust31_28[1]<<" "<<(unsigned)cfg->dll_tap_adjust31_28[2]<<std::endl; + std::cout<<"rc_adjust "<<(unsigned)cfg->rc_adjust[0]<<" "<<(unsigned)cfg->rc_adjust[1]<<" "<<(unsigned)cfg->rc_adjust[2]<<std::endl; + std::cout<<"not_used "<<(unsigned)cfg->not_used[0]<<" "<<(unsigned)cfg->not_used[1]<<" "<<(unsigned)cfg->not_used[2]<<std::endl; + std::cout<<"low_power_mode "<<(unsigned)cfg->low_power_mode[0]<<" "<<(unsigned)cfg->low_power_mode[1]<<" "<<(unsigned)cfg->low_power_mode[2]<<std::endl; + std::cout<<"width_select "<<(unsigned)cfg->width_select[0]<<" "<<(unsigned)cfg->width_select[1]<<" "<<(unsigned)cfg->width_select[2]<<std::endl; + std::cout<<"vernier_offset "<<(unsigned)cfg->vernier_offset[0]<<" "<<(unsigned)cfg->vernier_offset[1]<<" "<<(unsigned)cfg->vernier_offset[2]<<std::endl; + std::cout<<"dll_control "<<(unsigned)cfg->dll_control[0]<<" "<<(unsigned)cfg->dll_control[1]<<" "<<(unsigned)cfg->dll_control[2]<<std::endl; + std::cout<<"dead_time "<<(unsigned)cfg->dead_time[0]<<" "<<(unsigned)cfg->dead_time[1]<<" "<<(unsigned)cfg->dead_time[2]<<std::endl; + std::cout<<"test_invert "<<(unsigned)cfg->test_invert[0]<<" "<<(unsigned)cfg->test_invert[1]<<" "<<(unsigned)cfg->test_invert[2]<<std::endl; + std::cout<<"test_mode "<<(unsigned)cfg->test_mode[0]<<" "<<(unsigned)cfg->test_mode[1]<<" "<<(unsigned)cfg->test_mode[2]<<std::endl; + std::cout<<"enable_trailing "<<(unsigned)cfg->enable_trailing[0]<<" "<<(unsigned)cfg->enable_trailing[1]<<" "<<(unsigned)cfg->enable_trailing[2]<<std::endl; + std::cout<<"enable_leading "<<(unsigned)cfg->enable_leading[0]<<" "<<(unsigned)cfg->enable_leading[1]<<" "<<(unsigned)cfg->enable_leading[2]<<std::endl; + std::cout<<"mode_rc_compression "<<(unsigned)cfg->mode_rc_compression[0]<<" "<<(unsigned)cfg->mode_rc_compression[1]<<" "<<(unsigned)cfg->mode_rc_compression[2]<<std::endl; + std::cout<<"mode_rc "<<(unsigned)cfg->mode_rc[0]<<" "<<(unsigned)cfg->mode_rc[1]<<" "<<(unsigned)cfg->mode_rc[2]<<std::endl; + std::cout<<"dll_mode "<<(unsigned)cfg->dll_mode[0]<<" "<<(unsigned)cfg->dll_mode[1]<<" "<<(unsigned)cfg->dll_mode[2]<<std::endl; + std::cout<<"pll_control "<<(unsigned)cfg->pll_control[0]<<" "<<(unsigned)cfg->pll_control[1]<<" "<<(unsigned)cfg->pll_control[2]<<std::endl; + std::cout<<"serial_clock_delay "<<(unsigned)cfg->serial_clock_delay[0]<<" "<<(unsigned)cfg->serial_clock_delay[1]<<" "<<(unsigned)cfg->serial_clock_delay[2]<<std::endl; + std::cout<<"io_clock_delay "<<(unsigned)cfg->io_clock_delay[0]<<" "<<(unsigned)cfg->io_clock_delay[1]<<" "<<(unsigned)cfg->io_clock_delay[2]<<std::endl; + std::cout<<"core_clock_delay "<<(unsigned)cfg->core_clock_delay[0]<<" "<<(unsigned)cfg->core_clock_delay[1]<<" "<<(unsigned)cfg->core_clock_delay[2]<<std::endl; + std::cout<<"dll_clock_delay "<<(unsigned)cfg->dll_clock_delay[0]<<" "<<(unsigned)cfg->dll_clock_delay[1]<<" "<<(unsigned)cfg->dll_clock_delay[2]<<std::endl; + std::cout<<"serial_clock_source "<<(unsigned)cfg->serial_clock_source[0]<<" "<<(unsigned)cfg->serial_clock_source[1]<<" "<<(unsigned)cfg->serial_clock_source[2]<<std::endl; + std::cout<<"io_clock_source "<<(unsigned)cfg->io_clock_source[0]<<" "<<(unsigned)cfg->io_clock_source[1]<<" "<<(unsigned)cfg->io_clock_source[2]<<std::endl; + std::cout<<"core_clock_source "<<(unsigned)cfg->core_clock_source[0]<<" "<<(unsigned)cfg->core_clock_source[1]<<" "<<(unsigned)cfg->core_clock_source[2]<<std::endl; + std::cout<<"dll_clock_source "<<(unsigned)cfg->dll_clock_source[0]<<" "<<(unsigned)cfg->dll_clock_source[1]<<" "<<(unsigned)cfg->dll_clock_source[2]<<std::endl; + std::cout<<"roll_over "<<(unsigned)cfg->roll_over[0]<<" "<<(unsigned)cfg->roll_over[1]<<" "<<(unsigned)cfg->roll_over[2]<<std::endl; + std::cout<<"enable_matching "<<(unsigned)cfg->enable_matching[0]<<" "<<(unsigned)cfg->enable_matching[1]<<" "<<(unsigned)cfg->enable_matching[2]<<std::endl; + std::cout<<"enable_pair "<<(unsigned)cfg->enable_pair[0]<<" "<<(unsigned)cfg->enable_pair[1]<<" "<<(unsigned)cfg->enable_pair[2]<<std::endl; + std::cout<<"enable_ttl_serial "<<(unsigned)cfg->enable_ttl_serial[0]<<" "<<(unsigned)cfg->enable_ttl_serial[1]<<" "<<(unsigned)cfg->enable_ttl_serial[2]<<std::endl; + std::cout<<"enable_ttl_control "<<(unsigned)cfg->enable_ttl_control[0]<<" "<<(unsigned)cfg->enable_ttl_control[1]<<" "<<(unsigned)cfg->enable_ttl_control[2]<<std::endl; + std::cout<<"enable_ttl_reset "<<(unsigned)cfg->enable_ttl_reset[0]<<" "<<(unsigned)cfg->enable_ttl_reset[1]<<" "<<(unsigned)cfg->enable_ttl_reset[2]<<std::endl; + std::cout<<"enable_ttl_clock "<<(unsigned)cfg->enable_ttl_clock[0]<<" "<<(unsigned)cfg->enable_ttl_clock[1]<<" "<<(unsigned)cfg->enable_ttl_clock[2]<<std::endl; + std::cout<<"enable_ttl_hit "<<(unsigned)cfg->enable_ttl_hit[0]<<" "<<(unsigned)cfg->enable_ttl_hit[1]<<" "<<(unsigned)cfg->enable_ttl_hit[2]<<std::endl; +} + + //Calibrations + std::cout<<"Calibration constants"<<std::endl; + std::cout<<"---------------------"<<std::endl; + for (int i=0;i<12;i++){ + std::cout<<"Inl_"<<i<<" "; + dumpCalib(cfg->calib, 0, i); + } + for (int i=0;i<12;i++){ + std::cout<<"Dnl_"<<i<<" "; + dumpCalib(cfg->calib, 1, i); + } + +} + +void AFPHPTDCConfigFile::dumpCalib(const float cal[2][12][ipc::IPC_N_CALIBVALS], int i1, int i2){ + std::cout<<cal[i1][i2][0]<<" ... "<<(unsigned)cal[i1][i2][ipc::IPC_N_CALIBVALS-1]<<std::endl; +} + diff --git a/rce/rcecalib/server/AFPHPTDCConfigFile.hh b/rce/rcecalib/server/AFPHPTDCConfigFile.hh new file mode 100644 index 0000000000000000000000000000000000000000..ab35a0a645c877cc3adfda5ae3dcaa48ba455957 --- /dev/null +++ b/rce/rcecalib/server/AFPHPTDCConfigFile.hh @@ -0,0 +1,30 @@ +#ifndef AFPHPTDCCONFIGFILE_HH +#define AFPHPTDCCONFIGFILE_HH + +#include "AFPHPTDCModuleConfig.hh" +#include <string> +#include <map> +#include <vector> + +class AFPHPTDCConfigFile { +public: + AFPHPTDCConfigFile(){} + ~AFPHPTDCConfigFile(); + void readModuleConfig(ipc::AFPHPTDCModuleConfig* cfg, std::string filename); + void writeModuleConfig(ipc::AFPHPTDCModuleConfig* cfg, const std::string &base, const std::string &confdir, const std::string &configname, const std::string &key); + void writeCalibFile(float cal[2][12][ipc::IPC_N_CALIBVALS] , const std::string filename, int, int); + void dump(const ipc::AFPHPTDCModuleConfig *cfg); +private: + std::string getFullPath(std::string relPath); + void setupCalib(float cal[2][12][ipc::IPC_N_CALIBVALS] , std::string par, int i1, int i2); + unsigned lookupToUnsigned(std::string par, int index, int size=0); + int convertToUnsigned(std::string par, unsigned & val, int size); + //float lookupToFloat(std::string par); + void dumpCalib(const float cal[2][12][ipc::IPC_N_CALIBVALS], int i1, int i2); + + std::string m_moduleCfgFilePath; + std::ifstream *m_moduleCfgFile; + std::map<std::string, std::vector<std::string> > m_params; +}; + +#endif diff --git a/rce/rcecalib/server/BootLoaderPort.hh b/rce/rcecalib/server/BootLoaderPort.hh new file mode 100644 index 0000000000000000000000000000000000000000..2332728ac8a7479511ebf6b656910be63db29c50 --- /dev/null +++ b/rce/rcecalib/server/BootLoaderPort.hh @@ -0,0 +1,6 @@ +#ifndef BOOTLOADERPORT_HH +#define BOOTLOADERPORT_HH + +const unsigned short BootloaderPort = 1350; + +#endif diff --git a/rce/rcecalib/server/CalibGui.cc b/rce/rcecalib/server/CalibGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..eeb0831e0a6b5d2d416ba25d1e8beac97d85d6ea --- /dev/null +++ b/rce/rcecalib/server/CalibGui.cc @@ -0,0 +1,1856 @@ +#include <ipc/partition.h> +#include <ipc/core.h> +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/CalibGui.hh" +#include "rcecalib/server/PrimListGui.hh" +#include "rcecalib/server/PrimList.hh" +#include "rcecalib/server/ScanGui.hh" +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/IPCHistoController.hh" +#include "rcecalib/server/IPCGuiCallback.hh" +#include "rcecalib/analysis/CalibAnalysis.hh" +#include "rcecalib/analysis/AnalysisFactory.hh" +#include "rcecalib/server/DataExporter.hh" +#include "rcecalib/server/ScanLog.hh" +#include "rcecalib/util/VerifyErrors.hh" +#include "server/CallbackInfo.hh" + +//#include "rcecalib/server/atlasimage.hh" +#include "ScanOptions.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TGIcon.h" +#include "TGTab.h" +#include "TGMenu.h" +#include "TCanvas.h" +#include "TGCanvas.h" +#include "TGListTree.h" +#include "TRootEmbeddedCanvas.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TH2F.h> +#include <TStyle.h> +#include <cmdl/cmdargs.h> +#include <boost/regex.hpp> +#include <iostream> +#include <time.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <fstream> +#include <list> +#include <pthread.h> +#include <time.h> + +#include <is/infoT.h> +#include <is/infodictionary.h> + +using namespace RCE; + + + + +void* CalibGui::runloop( void *ptr ){ + CalibGui* calibGui=(CalibGui*)ptr; + calibGui->runloop(); + return 0; +} + + +void CalibGui::runloop(){ +//Execute shell script before scan, if available +if(m_primList->isLoaded() && m_primList->getCurrentPreScript().compare("") != 0) +{ + std::string script = m_primList->getCurrentPreScript(); + if(script.find("RUNNUM")!=(unsigned)-1)script.replace(script.find("RUNNUM"), 6, + Form("%06d", m_globalconf->getRunNumber())); + + char directory[512]; + getcwd(directory,512); + int retval=system(script.c_str()); + chdir(directory); + if(retval!=0){ + std::cout<<"****Script "<<script<<" failed. Aborting run."<<std::endl; + m_primList->setFailed(true); + stopRun(); + return; + } + +} + ipc::ScanOptions *options; + PixScan *pixscan=currentScan(); + options=currentScanConfig(); + std::vector<float>loop1vals=pixscan->getLoopVarValues(1); + std::vector<float>loop2vals=pixscan->getLoopVarValues(2); + size_t loopsize1=loop1vals.size(); + size_t loopsize2=loop2vals.size(); + //even if the loops don't exist we have to run through once + if(pixscan->getLoopActive(1)==false || pixscan->getDspProcessing(1)==true)loopsize1=1; + if(pixscan->getLoopActive(2)==false || pixscan->getDspProcessing(2)==true)loopsize2=1; + char txt[128]; + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + TGListTreeItem *current1=0, *current2; + TGListTreeItem *old1; + old1=0; + m_dir=""; + current2=0; + std::string dir2=""; + PixLib::EnumScanParam parlist; + + for(size_t i=0;i<loopsize2;i++){ + m_nLoop2->SetText(i); + if(pixscan->getDspProcessing(2)==false && pixscan->getLoopActive(2)==true){ + sprintf(txt, "loop2_%d",i); + if(saveChecked()){ + m_file->cd(); + m_file->mkdir(txt,"Loop 2 directory"); + dir2=txt; + } + current2=m_tree->AddItem(root,txt); + updateTree(); + }else{ + current2=root; + } + for(size_t j=0;j<loopsize1;j++){ + m_nLoop1->SetText(j); + if(pixscan->getDspProcessing(1)==false && pixscan->getLoopActive(1)==true){ + sprintf(txt, "loop1_%d",j); + if(saveChecked()){ + m_file->cd(dir2.c_str()); + gDirectory->mkdir(txt,"Loop 1 directory"); + if(dir2!="") m_dir=dir2+"/"+txt; + else m_dir=txt; + } + if(j!=0 || i!=0)old1=current1; + current1=m_tree->AddItem(current2,txt); + updateTree(); + }else{ + current1=current2; + } + + m_controller.downloadScanConfig(*options); + if(pixscan->getDspProcessing(2)==false && pixscan->getLoopActive(2)==true){ + loopAction(2, i); + m_controller.setupParameter(parlist.lookup(pixscan->getLoopParam(2)).c_str(), (int)loop2vals[i]); + } + if(pixscan->getDspProcessing(1)==false && pixscan->getLoopActive(1)==true){ + loopAction(1, j); + m_controller.setupParameter(parlist.lookup(pixscan->getLoopParam(1)).c_str(), (int)loop1vals[j]); + } + m_cb=new IPCGuiCallback(m_cbinfo); + + runScan(pixscan->getCallbackPriority()); + if(m_cbinfo->failed()){ //Scan failed + m_status=FAILED; + m_primList->setFailed(true); + stopRun(); + return; + } + if(saveChecked()){ + + m_timers->Stop(); //TFile->Write() crashes sometimes when the timer is running + saveHistos(); + m_timers->Start(); + } + if(old1!=0 && saveChecked()==false){ + m_tree->DeleteChildren(old1); + updateTree(); + } + fillHistoTree(current1); + updateTree(); + if(m_primList->isLoaded() && m_primList->getCurrentPostScript().compare("") != 0) + { + std::string script = m_primList->getCurrentPostScript(); + if(script.find("RUNNUM")!=(unsigned)-1)script.replace(script.find("RUNNUM"), 6, + Form("%06d", m_globalconf->getRunNumber())); + int retval=system(script.c_str()); + if(retval!=0){ + std::cout<<"****Script "<<script<<" failed. Aborting run."<<std::endl; + m_primList->setFailed(true); + stopRun(); + return; + } + } + if(m_isrunning==false){ //Scan was aborted + m_primList->setFailed(true); + stopRun(); + return; + } + } + } + if(currentScan()->verifyConfig()==true)verifyConfiguration(); + if(saveChecked()&&std::string(pixscan->getAnalysisType())!="NONE"){ + m_file->ReOpen("read"); //re-open file for reading + analyze(); + } + if(exportChecked()){ + m_file->ReOpen("read"); //re-open file for reading + std::string topconfigname=m_globalconf->getConfigName()+".cfg"; + m_dataExporter->exportData(m_exportdir, topconfigname, m_rcdir, m_file, m_anfile); + } + //End of successful run loop + if(m_primList->isLoaded())//Running primlist, so check and see if there is another item + EndOfPrimListScan(); + else //Using ScanGui, so stop run + stopRun(); + +} + +CalibGui::~CalibGui(){ + Cleanup(); + delete m_dataExporter; +} + +CalibGui::CalibGui(IPCPartition *partition, const TGWindow *p,UInt_t w,UInt_t h) + : TGMainFrame(p,w,h), m_partition(partition), m_controller(*new IPCController(*partition)), + m_hcontroller(*new IPCHistoController(*partition)), + m_histo(0), m_file(0), m_anfile(0), m_delhisto(false) { + // connect x icon on window manager + ISInfoDictionary dict(*partition); + ISInfoInt gui_running(0); + try{ + dict.getValue("RceIsServer.GUI_running", gui_running); + }catch(daq::is::RepositoryNotFound){ + std::cout<<"RceIsServer not running in the partition"<<std::endl; + exit(0); + }catch(daq::is::InfoNotFound){ + //std::cout<<"No entry for GUI_running"<<std::endl; + } + if (gui_running){ + int retcode; + char msg[512]; + sprintf(msg, "Another GUI is already running in partition %s. Continue?", m_partition->name().c_str()); + new TGMsgBox(gClient->GetRoot(), 0, "Attention", msg, + kMBIconExclamation, kMBYes | kMBCancel,&retcode); + if(retcode!=kMBYes){ + exit(0); + } + } + gui_running=1; + dict.checkin("RceIsServer.GUI_running", gui_running); + Connect("CloseWindow()","CalibGui",this,"quit()"); + + TGMenuBar *menubar=new TGMenuBar(this,1,1,kHorizontalFrame | kRaisedFrame); + TGLayoutHints *menubarlayout=new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + // menu "File" + TGPopupMenu* filepopup=new TGPopupMenu(gClient->GetRoot()); + filepopup->AddEntry("&Load Config",LOAD); + filepopup->AddEntry("&Save Config",SAVE); + filepopup->AddSeparator(); + filepopup->AddEntry("&Quit",QUIT); + menubar->AddPopup("&File",filepopup,menubarlayout); + + filepopup->Connect("Activated(Int_t)","CalibGui",this,"handleFileMenu(Int_t)"); + + TGPopupMenu* plotpopup=new TGPopupMenu(gClient->GetRoot()); + plotpopup->AddEntry("&Save as gif",GIF); + plotpopup->AddEntry("&Savefd as pdf",PDF); + menubar->AddPopup("&Plot",plotpopup,menubarlayout); + + + plotpopup->Connect("Activated(Int_t)","CalibGui",this,"handlePlotMenu(Int_t)"); + + AddFrame(menubar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,2)); + + //TGVerticalFrame* datapanel=new TGVerticalFrame(this,1,1, kSunkenFrame); + TGTab* fTab = new TGTab(this); + AddFrame(fTab,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY )) ; + TGCompositeFrame *datapanelt1 = fTab->AddTab("Scan"); + TGCompositeFrame *datapanelt2 = fTab->AddTab("Config Halfstave A"); + TGCompositeFrame *datapanelt2b = fTab->AddTab("Config Halfstave C"); + TGCompositeFrame *datapanelt2x = fTab->AddTab("Config Halfstave A (2)"); + TGCompositeFrame *datapanelt2bx = fTab->AddTab("Config Halfstave C (2)"); + TGCompositeFrame *datapanelt3 = fTab->AddTab("Plots"); + TGVerticalFrame *scanpanel=new TGVerticalFrame(datapanelt1); + datapanelt1->AddFrame(scanpanel,new TGLayoutHints(kLHintsExpandX |kLHintsExpandY)); + + // TGVerticalFrame *primlistpanel = new TGVerticalFrame(datapanelt1); + // datapanelt1->AddFrame(primlistpanel, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + // scan panel + TGHorizontalFrame *datapanel1a = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel1a,new TGLayoutHints(kLHintsExpandX )); + m_datapaneldd = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(m_datapaneldd, new TGLayoutHints(kLHintsExpandX, 2, 2, 0, 10)); + TGHorizontalFrame *datapanel1 = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel1,new TGLayoutHints(kLHintsExpandX )); + TGHorizontalFrame *datapanel2aa = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel2aa,new TGLayoutHints(kLHintsExpandX )); + TGHorizontalFrame *fwpanel = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(fwpanel, new TGLayoutHints(kLHintsExpandX)); + TGHorizontalFrame *datapanel2a = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel2a,new TGLayoutHints(kLHintsExpandX )); + TGHorizontalFrame *datapanelprim = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanelprim, new TGLayoutHints(kLHintsExpandX)); + TGHorizontalFrame *datapanel2 = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel2,new TGLayoutHints(kLHintsExpandX )); + TGHorizontalFrame *datapanel3 = new TGHorizontalFrame(scanpanel, 2, 2, kSunkenFrame); + scanpanel->AddFrame(datapanel3,new TGLayoutHints(kLHintsExpandX)); + TGVerticalFrame *datapanel4[4]; + datapanel4[0] = new TGVerticalFrame(datapanelt2, 2, 2, kSunkenFrame); + datapanelt2->AddFrame(datapanel4[0],new TGLayoutHints(kLHintsExpandX)); + datapanel4[1] = new TGVerticalFrame(datapanelt2b, 2, 2, kSunkenFrame); + datapanelt2b->AddFrame(datapanel4[1],new TGLayoutHints(kLHintsExpandX)); + datapanel4[2] = new TGVerticalFrame(datapanelt2x, 2, 2, kSunkenFrame); + datapanelt2x->AddFrame(datapanel4[2],new TGLayoutHints(kLHintsExpandX)); + datapanel4[3] = new TGVerticalFrame(datapanelt2bx, 2, 2, kSunkenFrame); + datapanelt2bx->AddFrame(datapanel4[3],new TGLayoutHints(kLHintsExpandX)); + TGHorizontalFrame *datapanel5 = new TGHorizontalFrame(datapanelt3, 2, 2, kSunkenFrame); + datapanelt3->AddFrame(datapanel5,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + //AddFrame(datapanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + m_scan=new ScanGui("Scan Config", datapanel1, 1, 1, kSunkenFrame); + datapanel1->AddFrame(m_scan,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,0,0)); + + //HSIO Firmware + + TGTextButton *mddd=new TGTextButton(fwpanel,"Print HSIO Firmware Version"); + mddd->Connect("Clicked()", "CalibGui", this,"getFirm()"); //todo: find and print FW + fwpanel->AddFrame(mddd,new TGLayoutHints(kLHintsCenterY | kLHintsExpandX ,2,2,5,5)); + + //primList Panel + + m_primList = new PrimListGui("Prim List", datapanelprim, 1, 1, kSunkenFrame); + m_primList->setScanTypes(m_scan->getScanTypes()); + datapanelprim->AddFrame(m_primList, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,0,0)); + m_globalconf=new GlobalConfigGui(m_config, ".calibDaq.rc",datapanel1a, 1, 1, kSunkenFrame); + datapanel1a->AddFrame(m_globalconf,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2)); + + int modperpanel=ConfigGui::MAX_MODULES/4; + const char* fenames[]={"A1-1", "A1-2", "A2-1", "A2-2", "A3-1", "A3-2", + "A4-1", "A4-2", "A5-1", "A5-2", "A6-1", "A6-2", + "A7-1", "A7-2", "A8-1", "A8-2", + "C1-1", "C1-2", "C2-1", "C2-2", "C3-1", "C3-2", + "C4-1", "C4-2", "C5-1", "C5-2", "C6-1", "C6-2", + "C7-1", "C7-2", "C8-1", "C8-2"}; + + for(int j=0;j<4;j++){ + TGHorizontalFrame *datapanelb=new TGHorizontalFrame(datapanel4[j]); + datapanel4[j]->AddFrame(datapanelb,new TGLayoutHints(kLHintsExpandX )); + TGTextButton *alloff=new TGTextButton(datapanelb,"All Off"); + alloff->SetMargins(15,25,0,0); + datapanelb->AddFrame(alloff,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,2,2,2,2)); + TGTextButton *allon=new TGTextButton(datapanelb,"All On"); + allon->SetMargins(15,25,0,0); + datapanelb->AddFrame(allon,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,2,2,2,2)); + if(j==0){ + alloff->Connect("Clicked()", "CalibGui", this,"allOffA()"); + allon->Connect("Clicked()", "CalibGui", this,"allOnA()"); + }else if(j==1){ + alloff->Connect("Clicked()", "CalibGui", this,"allOffC()"); + allon->Connect("Clicked()", "CalibGui", this,"allOnC()"); + }else if(j==2){ + alloff->Connect("Clicked()", "CalibGui", this,"allOffA2()"); + allon->Connect("Clicked()", "CalibGui", this,"allOnA2()"); + }else if(j==3){ + alloff->Connect("Clicked()", "CalibGui", this,"allOffC2()"); + allon->Connect("Clicked()", "CalibGui", this,"allOnC2()"); + } + TGHorizontalFrame *datapanelc[4]; + for(int i=0;i<4;i++){ + datapanelc[i] = new TGHorizontalFrame(datapanel4[j]); + datapanel4[j]->AddFrame(datapanelc[i],new TGLayoutHints(kLHintsExpandX |kLHintsExpandY)); + } + char modname[128]; + for (int i=0;i<modperpanel;i++){ + sprintf(modname, "%s", fenames[(j%2)*modperpanel+i]); + m_config[i+modperpanel*j]=new ConfigGui(modname, datapanelc[i/(modperpanel/4)],1,1, kSunkenFrame); + datapanelc[i/(modperpanel/4)]->AddFrame(m_config[i+modperpanel*j],new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,1,1)); + } + } + m_nevt=0; + m_timers=new TTimer; + m_timers->Connect("Timeout()","CalibGui",this,"timeouts()"); + m_start=new TGTextButton(datapanel2,"Start Run"); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_start->SetFont(labelfont); + m_start->SetMargins(10,40,10,10); + datapanel2->AddFrame(m_start,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,5,5,5,5)); + m_start->Connect("Clicked()", "CalibGui", this, "toggle()"); + m_save=new TGCheckButton(datapanel2,"Analyze/Save Histos"); + m_save->SetOn(true); + m_save->Connect("Clicked()", "CalibGui", this, "clearTree()"); + m_save->Connect("Clicked()", "CalibGui", this, "synchSave2()"); + datapanel2->AddFrame(m_save,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,10,2,5,5)); + m_export=new TGCheckButton(datapanel2,"Export Data"); + m_export->SetOn(false); + m_export->Connect("Clicked()", "CalibGui", this, "synchSave1()"); + datapanel2->AddFrame(m_export,new TGLayoutHints(kLHintsCenterY |kLHintsLeft, 0, 2, 5, 5)); + m_debug=new TGCheckButton(datapanel2,"Debugging Run"); + m_debug->SetOn(false); + datapanel2->AddFrame(m_debug,new TGLayoutHints(kLHintsCenterY |kLHintsLeft, 0, 2, 5, 5)); + //TGTextButton *quit=new TGTextButton(datapanel2,"&Quit","gApplication->Terminate(0)"); + m_quit=new TGTextButton(datapanel2,"Quit"); + m_quit->Connect("Clicked()", "CalibGui", this,"quit()"); + m_quit->SetFont(labelfont); + m_quit->SetMargins(15,25,10,10); + datapanel2->AddFrame(m_quit,new TGLayoutHints(kLHintsCenterY | kLHintsRight ,2,2,5,5)); + + m_print=new TGTextButton(datapanel2aa,"Print Scan"); + datapanel2aa->AddFrame(m_print,new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX ,2,2,5,0)); + m_print->Connect("Clicked()", "CalibGui", this, "printFromGui()"); + + TGLabel *commentlabel=new TGLabel(datapanel2a,"Comment:"); + datapanel2a->AddFrame(commentlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_comment=new TGTextEntry(datapanel2a); + datapanel2a->AddFrame(m_comment,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsExpandX, 2, 2, 10, 0)); + + TGLabel *timelabel=new TGLabel(datapanel3,"Time:"); + datapanel3->AddFrame(timelabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_time=new TGLabel(datapanel3,"0 s "); + datapanel3->AddFrame(m_time,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 30, 0, 0)); + m_time->SetTextFont(labelfont); + + TGLabel *nevlabel=new TGLabel(datapanel3,"Mask Stage:"); + datapanel3->AddFrame(nevlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_nEvents=new TGLabel(datapanel3,"0 "); + datapanel3->AddFrame(m_nEvents,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 30, 0, 0)); + m_nEvents->SetTextFont(labelfont); + m_cbinfo=new CallbackInfo(m_nEvents); + + nevlabel=new TGLabel(datapanel3,"Loop 1:"); + datapanel3->AddFrame(nevlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 20, 2, 10, 0)); + m_nLoop1=new TGLabel(datapanel3,"0 "); + datapanel3->AddFrame(m_nLoop1,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 30, 0, 0)); + m_nLoop1->SetTextFont(labelfont); + + nevlabel=new TGLabel(datapanel3,"Loop 2:"); + datapanel3->AddFrame(nevlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 20, 2, 10, 0)); + m_nLoop2=new TGLabel(datapanel3,"0 "); + datapanel3->AddFrame(m_nLoop2,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 30, 0, 0)); + m_nLoop2->SetTextFont(labelfont); + + TGVerticalFrame *treepanel = new TGVerticalFrame(datapanel5, 150, 2, kSunkenFrame); + datapanel5->AddFrame(treepanel,new TGLayoutHints(kLHintsExpandY)); + TGVerticalFrame *plotpanel = new TGVerticalFrame(datapanel5, 2, 2, kSunkenFrame); + datapanel5->AddFrame(plotpanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + + + m_tgc=new TGCanvas(treepanel, 300,100); + m_tree=new TGListTree(m_tgc, kHorizontalFrame); + m_tree->AddItem(0,"Histos"); + m_tree->Connect("Clicked(TGListTreeItem*, Int_t)","CalibGui", this, "displayHisto(TGListTreeItem*, Int_t)"); + treepanel->AddFrame(m_tgc,new TGLayoutHints(kLHintsExpandY)); + m_canvas=new TRootEmbeddedCanvas("Canvas",plotpanel,100,100); + m_canvas->GetCanvas()->GetPad(0)->SetRightMargin(0.15); + plotpanel->AddFrame(m_canvas,new TGLayoutHints(kLHintsExpandY|kLHintsExpandX)); + + m_dataExporter=new DataExporter(m_config); + m_homedir=getenv("HOME"); + m_homedir+="/"; + readGuiConfig((m_homedir+".calibDaq.rc").Data()); + m_scanLog=new ScanLog; + + m_thp = gClient->GetPicture("h1_t.xpm"); + + SetWindowName("Calibration GUI"); + Resize(w,h); + Layout(); + MapSubwindows(); + MapWindow(); +} +void CalibGui::toggle(){ + setRun(!running()); +} +void CalibGui::synchSave1(){ + if(m_export->IsOn()==true && m_save->IsOn()==false){ + m_save->SetOn(true); + } +} +void CalibGui::synchSave2(){ + if(m_export->IsOn()==true && m_save->IsOn()==false){ + m_export->SetOn(false); + } +} +void CalibGui::setRun(Bool_t on){ + + if (on){ + + //load new top config, change includes for primlist + if(m_primList->isLoaded()){ + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + m_config[i]->enableControls(true); + } + if(m_primList->getCurrentTopConfig()!=""){ + std::cout<<"Loading top config "<<m_primList->getCurrentTopConfig().c_str()<<std::endl; + m_globalconf->load(m_primList->getCurrentTopConfig().c_str()); + } + m_primList->changeIncludes(m_config); + } + enableControls(false); + m_globalconf->incrementRunNumber(); + m_globalconf->updateAvailable(false); + int ret=setupScan(); + if(ret==-1){ + enableControls(true); + return; + } + if(saveChecked()){ + int stat=openFile(); + if(stat){ + enableControls(true); + return; + } + } + if(m_primList->isLoaded())//set Primlist update info + { + + if(!m_globalconf->oldFileLoaded())//if no global conf loaded, prompt user where to save + { + m_globalconf->filePrompt(); + + } + if(!m_globalconf->oldFileLoaded())//file loading canceled or failed + { + setRun(false); + m_primList->updateStatus("PrimList will not run because no valid cfg directory chosen!"); + return; + } + else + { + std::stringstream buf; + buf << "Running " << m_primList->getCurrScanName() << " Scan (" << m_primList->currentScan + 1<< "/"<< m_primList->getNumScans() << ")" ; + m_primList->updateStatus(buf.str()); + m_primList->setFailed(false); + } + } + m_timers->Start(1000,kFALSE); // update every second + m_starttime.Set(); + m_nevt=0; + m_start->SetDown(true); + m_isrunning=true; + m_status=OK; + m_start->SetText("Running"); + m_cbinfo->clear(); + m_cbinfo->addToMask(CallbackInfo::RUNNING); + clearTree(); + startRun(); + } else{ + std::cout<<"Aborting Scan"<<std::endl; + m_controller.abortScan(); + m_isrunning=false; + m_controller.resetFE(); + /* + m_timers->Stop(); + m_start->SetDown(false); + m_start->SetText("Start Run"); + if(m_save->IsDisabledAndSelected()){ + m_file->ReOpen("read"); //re-open file for reading + } + enableControls(); + */ + + } +} +void CalibGui::stopRun(){ + m_comment->Clear(); + finishLogFile(); + //m_controller.sendHWcommand(0, 111); + m_controller.resetFE(); + if(saveChecked()){ + m_file->ReOpen("read"); //re-open file for reading + } + if(m_primList->isLoaded()) + { + std::stringstream buf; + if(m_primList->failed()){ + buf << "Primlist failed in scan "<<m_primList->currentScan +1<<". Aborted Run."<<std::endl; + }else{ + buf << "Finished running " << m_primList->getNumScans() << " scans! "; + } + m_primList->updateStatus(buf.str()); + } + m_primList->currentScan=0;//reset PrimList to beginning + m_timers->Stop(); + m_start->SetDown(false); + m_start->SetText("Start Run"); + m_isrunning=false; + m_cbinfo->addToMask(CallbackInfo::DONE); + m_cbinfo->updateGui(); + enableControls(true); + std::cout<<"Done"<<std::endl; +} +void CalibGui::timeouts(){ + // 1 s timeout, update number of events + char labelstring[128]; + TTimeStamp currenttime; + currenttime.Set(); + int timediff=(int)(currenttime.AsDouble()-m_starttime.AsDouble()+.5); + //std::cout<<"starttime "<<m_starttime.AsDouble()<<std::endl; + //std::cout<<"currenttime "<<currenttime.AsDouble()<<std::endl; + //std::cout<<"Timediff "<<timediff<<std::endl; + sprintf(labelstring,"%d s",timediff); + //std::cout<<"Labelstring "<<labelstring<<std::endl; + m_time->SetText(labelstring); + m_cbinfo->updateGui(); +} + +int CalibGui::startRun(){ + + //clear is server + if( m_hcontroller.clearISServer(".*", false) == 0 ){ + std::cout<<"Clearing histograms off IS server at beginning of run failed! Not continuing"<<std::endl; + assert(0); + } + + //configure all valid modules + //set up RCEs first + + std::map<int,unsigned int> rcemap; + m_controller.removeAllRces(); + m_hcontroller.removeAllRces(); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + m_controller.addRce(m_config[i]->getRce()); + m_hcontroller.addRce(m_config[i]->getRce()); + rcemap[m_config[i]->getRce()]=0; //value will be the phase word + } + } + // set up the trigger + + PixScan *pixscan=currentScan(); + //pixscan->dump(std::cout, *m_scan->getScanConfig()); + if(pixscan==0){ // no scan selected + stopRun(); + return 1; + } + + m_controller.setupTrigger(pixscan->getTriggerType()); + //now set up modules + m_controller.removeAllModules(); + bool valid=false; + std::map<int,unsigned int> linkmap; + std::map<int,unsigned int> idmap; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + valid=true; + unsigned rce=m_config[i]->getRce(); + unsigned outlink=m_config[i]->getOutLink(); + if(linkmap.find(outlink+1000*rce)!=linkmap.end()){ + int retcode; + new TGMsgBox(gClient->GetRoot(), 0, "Attention",Form("Outlink %d used by more than one frontend. Fix in config tab.", outlink), + kMBIconExclamation, kMBClose,&retcode); + stopRun(); + return 1; + } + linkmap[outlink+1000*rce]=1; + unsigned inlink=m_config[i]->getInLink(); + //rcemap[rce]|=1<<(m_config[i]->getPhase()+outlink*4); + int id=m_config[i]->getId(); + if(idmap.find(id)!=idmap.end()){ + int retcode; + new TGMsgBox(gClient->GetRoot(), 0, "Attention",Form("ID %d used by more than one frontend. Fix configuration files.", id), + kMBIconExclamation, kMBClose,&retcode); + stopRun(); + return 1; + } + idmap[id]=1; + const char* modname=m_config[i]->getName(); + std::string formatter=pixscan->getFormatterType(); + if(m_config[i]->getType()=="FEI4A"){ + if(formatter=="FEI4")formatter+="A"; + printf("FEI4A: addModule (%s, %d, %d, %d, %d, %s)\n",modname, id, inlink, outlink, rce,formatter.c_str()); + m_controller.addModule(modname, "FEI4A",id, inlink, outlink, rce, formatter.c_str()); + ipc::PixelFEI4AConfig *cfg=m_config[i]->getFEI4AConfig(); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else if(m_config[i]->getType()=="FEI4B"){ + if(formatter=="FEI4")formatter+="B"; + printf("FEI4B: addModule (%s, %d, %d, %d, %d, %s)\n",modname, id, inlink, outlink, rce,formatter.c_str()); + m_controller.addModule(modname, "FEI4B",id, inlink, outlink, rce, formatter.c_str()); + ipc::PixelFEI4BConfig *cfg=m_config[i]->getFEI4BConfig(); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else if(m_config[i]->getType()=="FEI3"){ + printf("FEI3: addModule (%s, %d, %d, %d, %d, %s)\n",modname, id, inlink, outlink, rce,formatter.c_str()); + m_controller.addModule(modname, "FEI3",id, inlink, outlink, rce, formatter.c_str()); + ipc::PixelModuleConfig *cfg=m_config[i]->getModuleConfig(); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else if(m_config[i]->getType()=="Hitbus"){ + printf("Hitbus: addModule (%s, %d, %d, %d, %d %s)\n",modname, id, inlink, outlink, rce,formatter.c_str()); + m_controller.addModule(modname, "Hitbus",id, inlink, outlink, rce, ""); + ipc::HitbusModuleConfig *cfg=m_config[i]->getHitbusConfig(); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else { + std::cout<<"Unknown config type"<<std::endl; + assert(0); + } + } + } + if(valid==false){ + int retcode; + new TGMsgBox(gClient->GetRoot(), 0, "Attention", "No pixel module included in the calibration. Continue?", + kMBIconExclamation, kMBYes | kMBCancel,&retcode); + if(retcode!=kMBYes){ + stopRun(); + return 1; + } + } + unsigned goodHSIOconnection; + for (std::map <int, unsigned int>::const_iterator it = rcemap.begin(); it != rcemap.end(); ++it){ + int rce=it->first; + goodHSIOconnection=m_controller.writeHWregister(rce, 11,0x0); //Trigger mask 1=scint 2=cyclic 4=Eudet 8=HSIO + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 3,0); //Mode 0=normal 1=tdccalib 2=eudaq + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 27,0); //regular L1A + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 22,0); //don't optimize multiplexer + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 23,0); //don't optimize multiplexer + assert(goodHSIOconnection==0); + // Reset delays + goodHSIOconnection=m_controller.writeHWregister(rce, 7,0); + assert(goodHSIOconnection==0); + //assert(m_controller.writeHWregister(rce, 15,0x280)==0); //setup mux + //assert(m_controller.writeHWregister(rce, 20,0x0)==0); //no BPM encoding + //else assert(m_controller.writeHWregister(rce, 20,0x1)==0); //BPM encoding + //assert(m_controller.writeHWregister(rce,17,it->second)==0); // set up phase + //Delay 0 -- Delay for disc 0 + // for(int i=0;i<m_phase->GetIntNumber();i++){ + // serstat=m_controller.writeHWregister(rce, 5,0); + // assert(serstat==0); + //} + + } + if (currentScanConfig()==0){ + stopRun(); + return 1; + } + logScan(); + pthread_t mthread; + pthread_create( &mthread, 0, CalibGui::runloop, (void*)this); + pthread_detach(mthread); + + + return 0; +} + +void CalibGui::runScan(int pr){ + m_controller.runScan((ipc::Priority)pr, m_cb); +} + +void CalibGui::verifyConfiguration(){ + std::cout<<"Verifying HW configuration"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::VERIFY); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + unsigned rce=m_config[i]->getRce(); + unsigned id=m_config[i]->getId(); + std::cout<<"Frontend "<<id<<" on RCE "<<rce<<" Outlink "<<m_config[i]->getOutLink()<<":"<<std::endl; + int retval=m_controller.verifyModuleConfigHW(rce, id); + if(retval&ModuleVerify::NO_FORMATTER)std::cout<<"No formatter defined. Skipping register readback."<<std::endl; + if(retval&ModuleVerify::GLOBAL_READBACK_FAILED)std::cout<<"Global register readback failed for unknown reasons."<<std::endl; + if(retval&ModuleVerify::GLOBAL_READBACK_DIFFERENT)std::cout<<"Global register readback differs from original configuration."<<std::endl; + if(retval&ModuleVerify::PIXEL_WRONG_N_WORDS)std::cout<<"Pixel register read back wrong number of words."<<std::endl; + if(retval&ModuleVerify::PIXEL_READBACK_DIFFERENT)std::cout<<"Pixel register readback differs from original configuration."<<std::endl; + if(retval==ModuleVerify::OK)std::cout<<"Register verification successful."<<std::endl; + if(retval!=ModuleVerify::OK)m_status=FAILED; + } + } +} +void CalibGui::enableControls(bool on){ + m_print->SetEnabled(on); + m_quit->SetEnabled(on); + m_save->SetEnabled(on); + m_export->SetEnabled(on); + m_debug->SetEnabled(on); + m_comment->SetEnabled(on); + for(int i=0;i<ConfigGui::MAX_MODULES;i++) + m_config[i]->enableControls(on); + m_scan->enableControls(on); + m_globalconf->enableControls(on); +} + +void CalibGui::quit(){ + writeGuiConfig((m_homedir+".calibDaq.rc").Data()); + ISInfoDictionary dict(*m_partition); + ISInfoInt gui_running(0); + dict.checkin("RceIsServer.GUI_running", gui_running); + gApplication->Terminate(0); +} + + +void CalibGui::handlePlotMenu(int item){ + if(item==GIF){ + m_canvas->GetCanvas()->SaveAs("c1.gif"); + }else if(item==PDF){ + m_canvas->GetCanvas()->SaveAs("c1.pdf"); + } +} +void CalibGui::getFirm(){ + std::map<int,unsigned int> rcemap; + m_controller.removeAllRces(); + bool foundRce=false; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + foundRce=true; + m_controller.addRce(m_config[i]->getRce()); + rcemap[m_config[i]->getRce()]=0; //value will be the phase word + } + } + unsigned firm; + for (std::map <int, unsigned int>::const_iterator it = rcemap.begin(); it != rcemap.end(); ++it){ + int rce=it->first; + unsigned value; + firm=m_controller.readHWregister(rce, 13, value); + if(firm==0){ + std::cout<<"RCE "<<rce<<": HSIO firmware version is "<<std::hex<<value<<std::dec<<"\n"; + }else{ + std::cout<<"RCE "<<rce<<": Firmware readout failed"<<"\n"; + } + } + if(foundRce==false){ + std::cout<<"***NO RCEs FOUND!***\n"<<std::endl; + }else{printf("Done\n");} +} + +void CalibGui::switchOn(int panel, bool on){ + int modperpanel=ConfigGui::MAX_MODULES/4; + for (int i=panel*modperpanel;i<(panel+1)*modperpanel;i++){ + m_config[i]->setIncluded(on); + } +} + + +void CalibGui::handleFileMenu(int item){ + TGFileInfo fileinfo; + const char* types[]={"Teststand config", "*.tcf", "All files", "*", 0, 0}; + fileinfo.fFileTypes=types; + if(item==QUIT)quit(); + else if(item==LOAD){ + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + readGuiConfig(fileinfo.fFilename); + } + else if(item==SAVE){ + new TGFileDialog(gClient->GetRoot(), 0, kFDSave, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + writeGuiConfig(fileinfo.fFilename); + } +} +void CalibGui::clearTree(){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + if(root) m_tree->DeleteChildren(root); + root->SetOpen(false); + updateTree(); +} +void CalibGui::updateTree(){ + int x=m_tgc->GetViewPort()->GetX(); + int y=m_tgc->GetViewPort()->GetY(); + int w=m_tgc->GetViewPort()->GetWidth(); + int h=m_tgc->GetViewPort()->GetHeight(); + m_tree->DrawRegion(x,y,w,h); +} + +void CalibGui::fillHistoTree(TGListTreeItem* branch){ + std::vector<std::string> names=m_hcontroller.getPublishedHistoNames(); + if(names.size()==0){ + std::cout<<"No Histograms available"<<std::endl; + return; + } + for(size_t i=0;i<names.size();i++){ + names[i]=CalibAnalysis::addPosition(names[i].c_str(), m_config); + } + std::sort(names.begin(), names.end()); + for(size_t i=0;i<names.size();i++){ + TGListTreeItem* item=m_tree->AddItem(branch,names[i].c_str()); + item->SetPictures(m_thp,m_thp); + } +} +void CalibGui::displayHisto(TGListTreeItem* item, int b){ + TGListTreeItem *parent=item->GetParent(); + if(parent==0)return; + std::string histonames=item->GetText(); + if(histonames[5]==':')histonames=histonames.substr(6); //remove position information + const char* histoname=histonames.c_str(); + if(std::string(histoname).substr(0,4)=="loop")return; + if(std::string(histoname).substr(0,8)=="Analysis")return; + //std::cout<<"Text "<<histoname<<std::endl; + if(std::string(parent->GetText())=="Analysis"){ + if(m_delhisto==true) delete m_histo; + m_delhisto=false; + m_anfile->cd(); + m_histo=(TH1*)gDirectory->Get(histoname); + //assert(m_histo!=0); + if(m_histo==0){ + std::cout<<"Histogram does not exist"<<std::endl; + return; + } + }else if(saveChecked()==false || + (m_save->IsEnabled()==true && m_save->IsOn()==false)){ + std::vector<TH1*> his=m_hcontroller.getHistosFromIS(histoname); + if(his.size()!=1)return; + if(m_delhisto==true) delete m_histo; + m_histo=his[0]; + m_delhisto=true; + //std::cout<<"Got histo from IS."<<std::endl; + }else{ + TGListTreeItem *parent1=parent->GetParent(); + if(parent1==0)m_file->cd(); + else{ + TGListTreeItem *parent2=parent1->GetParent(); + if(parent2==0)m_file->cd(parent->GetText()); + else{ + char dir[128]; + sprintf(dir, "%s/%s",parent1->GetText(), parent->GetText()); + m_file->cd(dir); + } + } + if(m_delhisto==true) delete m_histo; + m_delhisto=false; + m_histo=(TH1*)gDirectory->Get(histoname); + //assert(m_histo!=0); + if(m_histo==0){ + std::cout<<"Histogram does not exist"<<std::endl; + return; + } + //std::cout<<"Got histo from file."<<std::endl; + } + m_histo->SetMinimum(0); + if(m_histo->GetDimension()==1)m_histo->Draw(); + else { + std::cout<<"Drawing 2-d histogram"<<std::endl; + m_histo->Draw("colz"); + } + m_canvas->GetCanvas()->Update(); +} + +int CalibGui::openFile(){ + if(currentScan()==0){ + std::cout<<"No Scan selected."<<std::endl; + return 1; + } + TGFileInfo fileinfo; + char runnum[128]; + sprintf(runnum,"%06d",m_globalconf->getRunNumber()); + TString runname; + runname = (getScanName()+"_"+runnum); + TString rcdir("/"+runname); + rcdir=m_globalconf->getDataDir()+rcdir; + m_rcdir=std::string(rcdir.Data()); + m_exportdir=std::string(runname.Data()); + TString filename(rcdir+"/histos.root"); + TString anfilename(rcdir+"/analysis.root"); + TString rcconfig(rcdir+"/globalconfig.txt"); + std::string topconfigname=m_globalconf->getConfigName()+".cfg"; + TString topconfig(rcdir+"/"+topconfigname); + TString scanconfig(rcdir+"/scanconfig_"+m_exportdir+".txt"); + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + + intStat = stat(rcdir.Data(),&stFileInfo); + if(intStat == 0) { //File exists + int retcode; + + new TGMsgBox(gClient->GetRoot(), 0, "Attention", "Data file exists. Overwrite?", + kMBIconExclamation, kMBYes | kMBCancel,&retcode); + if(retcode==kMBYes){ + char command[512]; + sprintf(command, "rm -rf %s",rcdir.Data()); + system(command); + } + else + { + if (!m_primList->isLoaded()) + return 1; + else + { + m_isrunning=false; + return 1; + } + } + } + // make new run directory + mkdir (rcdir.Data(),0777); + // copy configuration + writeGuiConfig(rcconfig.Data()); + m_globalconf->copyConfig(topconfig.Data()); + std::ofstream sc(scanconfig.Data()); + if (m_primList->isLoaded()){ + m_primList->getCurrentScan()->dump(sc, *m_primList->getCurrentScanConfig()); + }else{ + m_scan->print(sc); + } + std::string oldcfg=std::string(rcdir.Data())+"/config"; + std::string updcfg=std::string(rcdir.Data())+"/configUpdate/"; + mkdir (oldcfg.c_str(),0777); + mkdir (updcfg.c_str(),0777); + m_globalconf->setConfigDir(updcfg.c_str()); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + m_config[i]->copyConfig(oldcfg.c_str()); + } + } + delete m_file; + TDatime dt; + m_file=new TFile(filename.Data(),"recreate", Form("Scan: %s Date: %s", runname.Data(), dt.AsString()) ); + delete m_anfile; + if(std::string(currentScan()->getAnalysisType())!="NONE") { + m_anfile=new TFile(anfilename.Data(),"recreate",Form("Scan: %s Date: %s", runname.Data(), dt.AsString()) ); + } + else m_anfile=0; + return 0; +} + +void CalibGui::writeGuiConfig(const char *filename){ + std::ofstream of(filename); + m_globalconf->writeGuiConfig(of); + of.close(); +} +void CalibGui::readGuiConfig(const char* filename){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(filename,&stFileInfo); + if(intStat == 0) { //File exists + std::ifstream fin(filename); + m_globalconf->readGuiConfig(fin); + fin.close(); + }else{ + std::cout<<"File "<<filename<<" does not exist"<<std::endl; + } +} + +void CalibGui::printFromGui(){ + setupScan(); + m_scan->print(std::cout); +} + +int CalibGui::setupScan(){ + if(m_primList->isLoaded()){//already setup when loaded primlist + m_primList->setRunNumber(m_globalconf->getRunNumber()); + return 0; + } + std::string fetype=""; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + std::string type=m_config[i]->getType(); + if(fetype!="" && type!="Hitbus" && type.substr(0,4) != fetype.substr(0,4)){ + std::cout<<"No mixing of frontend flavors allowed."<<std::endl; + return -1; + } + if(type!="Hitbus" && fetype!="FEI4A")fetype=type; //FEI4A overrules FEI4B + } + } + m_scan->setupScan(fetype, m_globalconf->getRunNumber()); + return 0; +} + +void CalibGui::saveHistos(){ + m_cbinfo->addToMask(CallbackInfo::SAVE); + m_cbinfo->updateGui(); + m_file->cd(m_dir.c_str()); + + std::vector<TH1*> his = m_hcontroller.getHistosFromIS(".*"); + if(his.size()==0) + { + std::cout<<"CalibGui::saveHistos - Error, no histograms found on IS server"<<std::endl; + return; + } + for(size_t i=0;i<his.size();i++) + { + if(his.at(i)==0){ + std::cout<<"CalibGui::saveHistos - Error, empty histogram retrieved from IS server"<<std::endl; + continue; + } + //do we need to set histogram name? + his.at(i)->Write(); + delete his.at(i); + } +} + +void CalibGui::loopAction(int i, int j){ + PixScan* pixscan=currentScan(); + switch(pixscan->getLoopAction(i)){ + case PixScan::T0_SET: + m_controller.setupParameter( "CHARGE", pixscan->getTotTargetCharge()); + break; + case PixScan::TDAC_TUNING: + setupTdacTuning(j); + break; + case PixScan::TDAC_FAST_TUNING: + setupTdacFastTuning(j); + break; + case PixScan::GDAC_TUNING: + if(i==2)setupGdacTuningOuterLoop(); + else setupGdacTuning(j); + break; + case PixScan::OFFSET: + setupOffsetScan(j); + break; + case PixScan::GDAC_FAST_TUNING: + setupGdacFastTuning(j); + break; + case PixScan::GDAC_COARSE_FAST_TUNING: + setupGdacCoarseFastTuning(j); + break; + case PixScan::SETMASK: + setupMask(i,j); + break; + case PixScan::NO_ACTION: + break; + default: + break; + } +} + +void CalibGui::analyze(){ + std::cout<<"Analyzing"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::ANALYZE); + std::string type=currentScan()->getAnalysisType(); + AnalysisFactory af; + CalibAnalysis* ana=af.getAnalysis(type); + if(ana){ + ana->analyze(m_file, m_anfile, currentScan(), m_globalconf->getRunNumber(), m_config); + m_anfile->ReOpen("read"); //re-open file for reading + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + TGListTreeItem* anroot=m_tree->AddItem(root,"Analysis"); + m_anfile->cd(); + TList* histos=gDirectory->GetListOfKeys(); + std::vector<std::string> namevec; + for(int i=0;i<histos->GetEntries();i++){ + std::string hname=((TH1*)histos->At(i))->GetName(); + hname=CalibAnalysis::addPosition(hname.c_str(), m_config); + namevec.push_back(hname); + } + std::sort(namevec.begin(), namevec.end()); + for(size_t i=0;i<namevec.size();i++){ + TGListTreeItem* item=m_tree->AddItem(anroot,namevec[i].c_str()); + item->SetPictures(m_thp,m_thp); + } + updateTree(); + if(ana->configUpdate()==true){ + m_globalconf->updateAvailable(true); + } + delete ana; + } +} + +void CalibGui::setupGdacTuningOuterLoop(){ + std::vector<float> varValues=currentScan()->getLoopVarValues(2); + if(varValues.size()<1){ + std::cout<<"No outer loop for GDAC tuning. Not setting up TDAC values"<<std::endl; + return; + } + int val=(int)varValues[0]; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip; + if(m_config[i]->getType().substr(0,4)=="FEI4"){ + ncol=80; + nrow=336; + nchip=1; + }else{ + ncol=18; + nrow=160; + nchip=16; + } + for (int chip=0;chip<nchip;chip++){ + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FETrims.dacThresholdTrim[col][row]=val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FETrims.dacThresholdTrim[col][row]=val; + else m_config[i]->getModuleConfig()->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=val; + } + } + } + } +} + +void CalibGui::setupGdacTuning(int j){ + if(!saveChecked()){ + std::cout<<"**** Check Save/Analyze before running this scan. ***"<<std::endl; + return; + } + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + char subdir[128]; + sprintf(subdir, "loop1_%d", j); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval, maxstage; + if(m_config[i]->getType().substr(0,4)=="FEI4"){ + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=120; + }else{ + ncol=18; + nrow=160; + nchip=16; + maxval=32; + maxstage=32; + } + std::vector<float> varValues=currentScan()->getLoopVarValues(1); + int occlast=currentScan()->getLoopVarValues(0).size()-3; + int target=currentScan()->getThresholdTargetValue(); + int nstages=currentScan()->getMaskStageSteps(); + int npixtotal=nchip*ncol*nrow; + float npixused=float(nstages)/float(maxstage) * npixtotal; + float npixunused=(1.-float(nstages)/float(maxstage))*npixtotal; + TH2 *mean=0, *chi2=0, *occ0=0, *occmax=0; + char name[128]; + sprintf (name, "GDAC_settings_Mod_%d_it_%d", m_config[i]->getId(), j); + TH1F* threshhist=new TH1F(name, Form("GDAC settings module %d step %d", m_config[i]->getId(), j), + nchip, 0, nchip); + threshhist->SetMinimum(0); + threshhist->GetYaxis()->SetTitle("GDAC setting"); + threshhist->GetXaxis()->SetTitle("Chip"); + if(j!=0){ + mean=(TH2*)m_file->Get(Form( "loop2_0/loop1_%d/Mod_%d_Mean", j-1, m_config[i]->getId())); + chi2=(TH2*)m_file->Get(Form( "loop2_0/loop1_%d/Mod_%d_ChiSquare", j-1, m_config[i]->getId())); + occ0=(TH2*)m_file->Get(Form("loop2_0/loop1_%d/Mod_%d_Occupancy_Point_002", j-1, m_config[i]->getId())); + occmax=(TH2*)m_file->Get(Form( "loop2_0/loop1_%d/Mod_%d_Occupancy_Point_%03d", j-1, m_config[i]->getId(),occlast)); + if(mean==0 || chi2==0 || occ0==0 || occmax==0){ + std::cout<<"Did not find histo "<<mean<<" "<<chi2<<" "<<occ0<<" "<<occmax<<std::endl; + std::cout<<"occlast "<<occlast<<std::endl; + assert(0); + return; + } + } + for (int chip=0;chip<nchip;chip++){ + CORBA::Octet val=int(varValues[0]); //initial setting + if(varValues[0]==-1 || j!=0){ //val==-1 means retuning, use GDAC values from file + if(m_config[i]->getType()=="FEI4A") val=m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltFine; + else if(m_config[i]->getType()=="FEI4B") val=m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltFine; + else val=m_config[i]->getModuleConfig()->FEConfig[chip].FEGlobal.gdac; + } + if(j!=0){ //modify TDAC values appropriately + int repetitions = currentScan()->getRepetitions(); + int diffval=int(varValues[j]); + float empty=0; + float noisy=0; + float good=0; + float meanf=0; + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + if(occ0->GetBinContent(chip*ncol+col+1, row+1)!=0)noisy++; + else if (occmax->GetBinContent(chip*ncol+col+1, row+1)<repetitions*0.9)empty++; + else if (chi2->GetBinContent(chip*ncol+col+1, row+1)!=0){ + good++; + meanf+=mean->GetBinContent(chip*ncol+col+1, row+1); + } + } + } + if(good>0)meanf/=good; + if(noisy>npixused*0.50){ //more than 50 % of pixels in the noise + if((int)val+diffval<maxval)val+=diffval; + else { + val=maxval-1; + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at "<<maxval-1<<std::endl; + } + std::cout<<"Module "<< m_config[i]->getId()<<": More than 50 % of the pixels are in the noise. Moving to higher threshold."<<std::endl; + }else if (empty>npixunused+npixused*0.5){ //more than 50 % never reach threshold + if((int)val-diffval>0)val-=diffval; + else { + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at 0"<<std::endl; + val=0; + } + std::cout<<"Module "<< m_config[i]->getId()<<": More than 50 % of the pixels never reach threshold. Moving to lower threshold."<<std::endl; + }else if(good>0.3*npixused){ + if(meanf>target){ + if((int)val-diffval>0)val-=diffval; + else { + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at 0"<<std::endl; + val=0; + } + } else { + if((int)val+diffval<maxval)val+=diffval; + else { + val=maxval-1; + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at "<<maxval-1<<std::endl; + } + } + }else{ + std::cout<<"Module "<<m_config[i]->getId()<<": GDAC Tuning: No criteria match. Don't know what to do. good="<<good/npixused<<" empty="<<(empty-npixunused)/npixused<<" noisy="<<noisy/npixused<<std::endl; + } + } + std::cout<<"Setting GDAC to "<<(int)val<<std::endl; + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltFine=val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltFine=val; + else m_config[i]->getModuleConfig()->FEConfig[chip].FEGlobal.gdac=val; + threshhist->SetBinContent(1, val); + } + if(saveChecked()){ + TGListTreeItem* branch2=m_tree->FindChildByName(root,"loop2_0"); + TGListTreeItem* branch=m_tree->FindChildByName(branch2, subdir); + TGListTreeItem* item=m_tree->AddItem(branch,CalibAnalysis::addPosition(name, m_config).c_str()); + item->SetPictures(m_thp,m_thp); + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + else m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getModuleConfig()); + m_file->cd(Form("loop2_0/%s", subdir)); + threshhist->Write(); + threshhist->SetDirectory(gDirectory); + } + } + m_controller.downloadScanConfig(*(currentScanConfig())); +} + +void CalibGui::setupGdacFastTuning(int j){ + if(!saveChecked()){ + std::cout<<"**** Check Save/Analyze before running this scan. ***"<<std::endl; + return; + } + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + char subdir[128]; + sprintf(subdir, "loop1_%d", j); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval, maxstage; + if(m_config[i]->getType()=="FEI4A"){ + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=120; + } + else if(m_config[i]->getType()=="FEI4B"){ + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=24; + } + else{ + ncol=18; + nrow=160; + nchip=16; + maxval=32; + maxstage=32; + } + currentScanConfig()->scanLoop[0].dataPoints[0] = currentScan()->getThresholdTargetValue(); + int nstages=currentScan()->getMaskStageSteps(); + int npixtotal=nchip*ncol*nrow; + float npixused=float(nstages)/float(maxstage)*npixtotal; + std::vector<float> varValues=currentScan()->getLoopVarValues(1); + int repetitions = currentScan()->getRepetitions(); + double targetEff = 0.5; + TH2 *occ0=0; + char name[128]; + sprintf (name, "GDAC_settings_Mod_%d_it_%d", m_config[i]->getId(), j); + TH1F* threshhist=new TH1F(name, Form("GDAC settings module %d step %d", m_config[i]->getId(), j), + nchip, 0, nchip); + threshhist->SetMinimum(0); + threshhist->GetYaxis()->SetTitle("GDAC setting"); + threshhist->GetXaxis()->SetTitle("Chip"); + if(j!=0){ + occ0=(TH2*)m_file->Get(Form("loop2_0/loop1_%d/Mod_%d_Occupancy_Point_000", j-1, m_config[i]->getId())); + if(occ0==0){ + std::cout<<"Did not find occupancy histo "<<occ0<<std::endl; + assert(0); + return; + } + } + for (int chip=0;chip<nchip;chip++){ + CORBA::Octet val=int(varValues[0]); //initial setting + if(varValues[0]==-1 || j!=0){ //val==-1 means retuning, use GDAC values from file + if(m_config[i]->getType()=="FEI4A") val=m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltFine; + else if(m_config[i]->getType()=="FEI4B") val=m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltFine; + else val=m_config[i]->getModuleConfig()->FEConfig[chip].FEGlobal.gdac; + } + if(j!=0){ //modify GDAC values appropriately + float meanEff = 0.0; + int diffval=int(varValues[j]); + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++) meanEff += occ0->GetBinContent(chip*ncol+col+1, row+1) / repetitions; + } + meanEff /= npixused; + if (meanEff < targetEff) { + if ((int)val-diffval > 0) { + val-=diffval; + } + else { + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at 0"<<std::endl; + val=0; + } + } + else if (meanEff > targetEff) { + if ((int)val+diffval < maxval){ + val+=diffval; + } + else { + val=maxval-1; + std::cout<<"Module "<< m_config[i]->getId()<<": GDAC already at "<<maxval-1<<std::endl; + } + } + } + std::cout<<"Setting GDAC for module " << m_config[i]->getId() << " to " << (int)val << std::endl; + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltFine=val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltFine=val; + else m_config[i]->getModuleConfig()->FEConfig[chip].FEGlobal.gdac=val; + threshhist->SetBinContent(1, val); + } + if(saveChecked()){ + TGListTreeItem* branch2=m_tree->FindChildByName(root,"loop2_0"); + TGListTreeItem* branch=m_tree->FindChildByName(branch2, subdir); + TGListTreeItem* item=m_tree->AddItem(branch,CalibAnalysis::addPosition(name, m_config).c_str()); + item->SetPictures(m_thp,m_thp); + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + else m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getModuleConfig()); + m_file->cd(Form("loop2_0/%s", subdir)); + threshhist->Write(); + threshhist->SetDirectory(gDirectory); + } + } + m_controller.downloadScanConfig(*(currentScanConfig())); +} + +void CalibGui::setupGdacCoarseFastTuning(int j){ + if(!saveChecked()){ + std::cout<<"**** Check Save/Analyze before running this scan. ***"<<std::endl; + return; + } + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + char subdir[128]; + sprintf(subdir, "loop1_%d", j); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval, maxstage; + if(m_config[i]->getType()=="FEI4A"){ + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=120; + } + else { + ncol=80; + nrow=336; + nchip=1; + maxval=256; + maxstage=24; + } + currentScanConfig()->scanLoop[0].dataPoints[0] = currentScan()->getThresholdTargetValue(); + std::vector<float> varValues=currentScan()->getLoopVarValues(1); + char name[128]; + sprintf (name, "GDACCoarse_settings_Mod_%d_it_%d", m_config[i]->getId(), j); + TH1F* threshhist=new TH1F(name, Form("GDACCoarse settings module %d step %d", m_config[i]->getId(), j), + nchip, 0, nchip); + threshhist->SetMinimum(0); + threshhist->GetYaxis()->SetTitle("GDACCoarse setting"); + threshhist->GetXaxis()->SetTitle("Chip"); + for (int chip=0;chip<nchip;chip++) { + CORBA::Octet val = int(varValues[j]); //initial setting + CORBA::Octet fineval = int(maxval-1); + if ((int)val > maxval-1) { + val = maxval-1; + std::cout << "Module " << m_config[i]->getId() << ": GDACCoarse cannot be higher than " << (int)val << std::endl; + } + else if ((int)val < 0) { + val = int(0); + std::cout << "Module " << m_config[i]->getId() << ": GDACCoarse cannot be lower than " << (int)val << std::endl; + } + std::cout<<"Setting GDACCoarse for module " << m_config[i]->getId() << " to " << (int)val << std::endl; + if (m_config[i]->getType() == "FEI4A") { + m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltCoarse = val; + m_config[i]->getFEI4AConfig()->FEGlobal.Vthin_AltFine = fineval; + } + else if (m_config[i]->getType() == "FEI4B") { + m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltCoarse = val; + m_config[i]->getFEI4BConfig()->FEGlobal.Vthin_AltFine = fineval; + } + threshhist->SetBinContent(1, val); + } + if(saveChecked()){ + TGListTreeItem* branch2=m_tree->FindChildByName(root,"loop2_0"); + TGListTreeItem* branch=m_tree->FindChildByName(branch2, subdir); + TGListTreeItem* item=m_tree->AddItem(branch,CalibAnalysis::addPosition(name, m_config).c_str()); + item->SetPictures(m_thp,m_thp); + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + m_file->cd(Form("loop2_0/%s", subdir)); + threshhist->Write(); + threshhist->SetDirectory(gDirectory); + } + } + m_controller.downloadScanConfig(*(currentScanConfig())); +} + +void CalibGui::setupTdacTuning(int j){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + char subdir[128]; + sprintf(subdir, "loop1_%d", j); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval; + if(m_config[i]->getType().substr(0,4)=="FEI4"){ + ncol=80; + nrow=336; + nchip=1; + maxval=32; + }else{ + ncol=18; + nrow=160; + nchip=16; + maxval=128; + } + //ipc::PixelFEI4Config *cfg=m_config[i]->getFEI4Config(); + std::vector<float> varValues=currentScan()->getLoopVarValues(1); + int occlast=currentScan()->getLoopVarValues(0).size()-3; + int target=currentScan()->getThresholdTargetValue(); + TH2 *mean=0, *chi2=0, *occ0=0, *occmax=0; + char name[128]; + sprintf (name, "TDAC_settings_Mod_%d_it_%d", m_config[i]->getId(), j); + TH2F* threshhist=new TH2F(name, Form("TDAC settings module %d step %d", m_config[i]->getId(), j), + nchip*ncol, 0, nchip*ncol, nrow, 0, nrow); + threshhist->SetMinimum(0); + threshhist->GetXaxis()->SetTitle("Column"); + threshhist->GetYaxis()->SetTitle("Row"); + if(j!=0){ + mean=(TH2*)m_file->Get(Form( "loop1_%d/Mod_%d_Mean", j-1, m_config[i]->getId())); + chi2=(TH2*)m_file->Get(Form( "loop1_%d/Mod_%d_ChiSquare", j-1, m_config[i]->getId())); + occ0=(TH2*)m_file->Get(Form("loop1_%d/Mod_%d_Occupancy_Point_002", j-1, m_config[i]->getId())); + occmax=(TH2*)m_file->Get(Form( "loop1_%d/Mod_%d_Occupancy_Point_%03d", j-1, m_config[i]->getId(),occlast)); + if(mean==0 || chi2==0 || occ0==0 || occmax==0){ + std::cout<<"Did not find histo "<<mean<<" "<<chi2<<" "<<occ0<<" "<<occmax<<std::endl; + std::cout<<"occlast "<<occlast<<std::endl; + assert(0); + return; + } + } + for (int chip=0;chip<nchip;chip++){ + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + CORBA::Octet val=int(varValues[0]); //initial setting + if(varValues[0]==-1 || j!=0){ //val==-1 means retuning, use TDAC values from file + if(m_config[i]->getType()=="FEI4A") val=m_config[i]->getFEI4AConfig()->FETrims.dacThresholdTrim[col][row]; + else if(m_config[i]->getType()=="FEI4B") val=m_config[i]->getFEI4BConfig()->FETrims.dacThresholdTrim[col][row]; + else val=m_config[i]->getModuleConfig()->FEConfig[chip].FETrims.dacThresholdTrim[row][col]; + } + if(j!=0){ //modify TDAC values appropriately + int diffval=int(varValues[j]); + if(m_config[i]->getType()=="FEI3"){ + if(chi2->GetBinContent(chip*ncol+col+1, row+1)!=0){ + double m=mean->GetBinContent(chip*ncol+col+1, row+1); + if(m<target && val+diffval<128)val+=diffval; + else if(m>target && val>=diffval)val-=diffval; + }else if (occ0->GetBinContent(chip*ncol+col+1, row+1)!=0 && occmax->GetBinContent(chip*ncol+col+1, row+1)!=0 + && val+diffval<128){ + val+=diffval; + }else if (occ0->GetBinContent(chip*ncol+col+1, row+1)==0 && occmax->GetBinContent(chip*ncol+col+1, row+1)==0 && val!=0 + && val>=diffval){ + val-=diffval; + } + }else{ + if(chi2->GetBinContent(col+1, row+1)!=0){ + double m=mean->GetBinContent(col+1, row+1); + if(m>target && val+diffval<32)val+=diffval; + else if(m<target && val>=diffval)val-=diffval; + }else if (occ0->GetBinContent(col+1, row+1)==0 && occmax->GetBinContent(col+1, row+1)==0 + && val+diffval<32){ + val+=diffval; + }else if (occ0->GetBinContent(col+1, row+1)!=0 && occmax->GetBinContent(col+1, row+1)!=0 && val!=0 + && val>=diffval){ + val-=diffval; + } + } + } + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FETrims.dacThresholdTrim[col][row]=val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FETrims.dacThresholdTrim[col][row]=val; + else m_config[i]->getModuleConfig()->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=val; + threshhist->SetBinContent(chip*ncol+col+1, row+1, val); + } + } + } + if(saveChecked()){ + TGListTreeItem* branch=m_tree->FindChildByName(root,subdir); + TGListTreeItem* item=m_tree->AddItem(branch,CalibAnalysis::addPosition(name, m_config).c_str()); + item->SetPictures(m_thp,m_thp); + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + else m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getModuleConfig()); + m_file->cd(subdir); + threshhist->Write(); + threshhist->SetDirectory(gDirectory); + } + } + m_controller.downloadScanConfig(*(currentScanConfig())); +} + +void CalibGui::setupTdacFastTuning(int j){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + char subdir[128]; + sprintf(subdir, "loop1_%d", j); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval; + if(m_config[i]->getType().substr(0,4)=="FEI4"){ + ncol=80; + nrow=336; + nchip=1; + maxval=32; + }else{ + ncol=18; + nrow=160; + nchip=16; + maxval=128; + } + //ipc::PixelFEI4Config *cfg=m_config[i]->getFEI4Config(); + currentScanConfig()->scanLoop[0].dataPoints[0] = currentScan()->getThresholdTargetValue(); + std::vector<float> varValues=currentScan()->getLoopVarValues(1); + int repetitions = currentScan()->getRepetitions(); + double targetEff = 0.5; + TH2 *occ0=0; + char name[128]; + sprintf (name, "TDAC_settings_Mod_%d_it_%d", m_config[i]->getId(), j); + TH2F* threshhist=new TH2F(name, Form("TDAC settings module %d step %d", m_config[i]->getId(), j), + nchip*ncol, 0, nchip*ncol, nrow, 0, nrow); + threshhist->SetMinimum(0); + threshhist->GetXaxis()->SetTitle("Column"); + threshhist->GetYaxis()->SetTitle("Row"); + if(j!=0){ + occ0=(TH2*)m_file->Get(Form("loop1_%d/Mod_%d_Occupancy_Point_000", j-1, m_config[i]->getId())); + if(occ0==0){ + std::cout<<"Did not find occupancy histo "<<occ0<<std::endl; + assert(0); + return; + } + } + for (int chip=0;chip<nchip;chip++){ + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + CORBA::Octet val=int(varValues[0]); //initial setting + if(varValues[0]==-1 || j!=0){ //val==-1 means retuning, use TDAC values from file + if(m_config[i]->getType()=="FEI4A") val=m_config[i]->getFEI4AConfig()->FETrims.dacThresholdTrim[col][row]; + else if(m_config[i]->getType()=="FEI4B") val=m_config[i]->getFEI4BConfig()->FETrims.dacThresholdTrim[col][row]; + else val=m_config[i]->getModuleConfig()->FEConfig[chip].FETrims.dacThresholdTrim[row][col]; + } + if(j!=0){ //modify TDAC values appropriately + int diffval=int(varValues[j]); + if(m_config[i]->getType()=="FEI3"){ + double m= occ0->GetBinContent(chip*ncol+col+1, row+1) / repetitions; + if(m>targetEff && val+diffval<128)val+=diffval; + else if(m<targetEff && val>diffval)val-=diffval; + }else{ + double m=occ0->GetBinContent(col+1, row+1) / repetitions; + if(m<targetEff && val+diffval<32)val+=diffval; + else if(m>targetEff && val>diffval)val-=diffval; + } + } + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FETrims.dacThresholdTrim[col][row]=val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FETrims.dacThresholdTrim[col][row]=val; + else m_config[i]->getModuleConfig()->FEConfig[chip].FETrims.dacThresholdTrim[row][col]=val; + threshhist->SetBinContent(chip*ncol+col+1, row+1, val); + } + } + } + if(saveChecked()){ + TGListTreeItem* branch=m_tree->FindChildByName(root,subdir); + TGListTreeItem* item=m_tree->AddItem(branch,CalibAnalysis::addPosition(name, m_config).c_str()); + item->SetPictures(m_thp,m_thp); + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + else m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getModuleConfig()); + m_file->cd(subdir); + threshhist->Write(); + threshhist->SetDirectory(gDirectory); + } + } + m_controller.downloadScanConfig(*(currentScanConfig())); +} + +void CalibGui::setupOffsetScan(int j){ + ipc::ScanOptions* scanPar=currentScanConfig(); + if(j==0){ + scanPar->stagingMode = CORBA::string_dup("FEI4_ENA_SCAP"); + for(unsigned int k=0;k<scanPar->scanLoop[0].nPoints;k++) + scanPar->scanLoop[0].dataPoints[k]= k*3; + }else{ + scanPar->stagingMode = CORBA::string_dup("FEI4_ENA_BCAP"); + for(unsigned int k=0;k<scanPar->scanLoop[0].nPoints;k++) + scanPar->scanLoop[0].dataPoints[k]= k; + } + //m_controller.downloadScanConfig(*m_scan->getScanConfig()); + m_controller.downloadScanConfig(*(scanPar)); +} + +void CalibGui::setupMask(int loop_i, int j){ + //scanLoop loop_i loops through the different mask stages we want to cycle over + + std::vector<float> varValues; + if(loop_i==1){ + varValues=currentScan()->getLoopVarValues(1); + } + else if(loop_i==2){ + varValues=currentScan()->getLoopVarValues(2); + } + else{ + std::cout<<"CalibGui::setupMask error: invalid value loop_i = "<<loop_i<<std::endl; + return; + } + int stage = varValues[j]; + + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if (m_config[i]->isIncluded()==false)continue; + int ncol, nrow, nchip, maxval; + if(m_config[i]->getType().substr(0,4)=="FEI4"){ + ncol=80; + nrow=336; + nchip=1; + maxval=32; + }else{ + //Not supporting FEI3, because the masking bits are different in that case + std::cout<<"CalibGui::setupMask ERROR:only FEI4 supported"<<std::endl; + return; + //ncol=18; + //nrow=160; + //nchip=16; + //maxval=128; + } + + // stage = row + 336*col + 1 (row from 0-335, col from 0-79. We add 1 because we reserve stage==0 for special meaning) + int rowInj = (stage-1)%336; + int colInj = (stage-1)/336; + + for (int col=0;col<ncol;col++){ + for (int row=0;row<nrow;row++){ + + //enable: bit 0, largeCap: bit 1, smallCap: bit 2 + + //set enable for all bits on FE + int val = (1<<ipc::enable); + //set smallCap and largeCap just for the pixel we are injecting + if(col==colInj && row==rowInj){ + val |= (1<<ipc::largeCap); + val |= (1<<ipc::smallCap); + } + // std::cout<<"row "<<row<<" col "<<col<<" ; val = "<<val<<std::endl; + + if(m_config[i]->getType()=="FEI4A")m_config[i]->getFEI4AConfig()->FEMasks[col][row] = val; + else if(m_config[i]->getType()=="FEI4B")m_config[i]->getFEI4BConfig()->FEMasks[col][row] = val; + + } + } + + if(m_config[i]->getType()=="FEI4A") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4AConfig()); + else if(m_config[i]->getType()=="FEI4B") m_controller.downloadModuleConfig(m_config[i]->getRce(), m_config[i]->getId(), *m_config[i]->getFEI4BConfig()); + + } //end loop over i + + m_controller.downloadScanConfig(*(currentScanConfig())); + //This sets up mask stage, which sets Colpr_Mode to 3. This is necessary, since + //Colpr_Addr gets overwritten during configuration, so we need to be able to inject + //any arbitrary pixel + m_controller.setupMaskStage(stage); + +} + +PixScan* CalibGui::currentScan() +{ + if(m_primList->isLoaded()) + return m_primList->getCurrentScan(); + return m_scan->getPixScan(); +} +std::string CalibGui::getScanName(){ + if(m_primList->isLoaded())return m_primList->getCurrScanName(); + else return m_scan->getTypeString(); +} +ipc::ScanOptions* CalibGui::currentScanConfig() +{ + if(m_primList->isLoaded()) + return m_primList->getCurrentScanConfig(); + return m_scan->getScanConfig(); +} +void CalibGui::EndOfPrimListScan()//Called from the end of run loop, either move to next item +{ + if(!m_isrunning) + { + stopRun(); + return; + } + if(m_primList->getCurrentPause()!=0){ + m_cbinfo->addToMask(CallbackInfo::WAIT); + sleep(m_primList->getCurrentPause()); + } + if(m_primList->getCurrentUpdateConfig()) + { + m_globalconf->update(); + } + if(m_primList->currentScan+1 < m_primList->getNumScans() && m_isrunning){ + finishLogFile(); + m_primList->currentScan++; + setRun(true); + } + else{ + stopRun(); + } +} +void CalibGui::logScan(){ + LogData logdata; + m_scanLog->setAuthor("calibGui"); + m_scanLog->setScanName(getScanName().c_str()); + m_scanLog->setRunNumber(m_globalconf->getRunNumber()); + m_scanLog->setDebugging(debugChecked()); + logdata.comment=m_comment->GetText(); + logdata.exported=exportChecked(); + logdata.saved=saveChecked(); + if(saveChecked())logdata.datapath=m_globalconf->getDataDir(); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + std::ostringstream ss; + if(m_config[i]->isIncluded()){ + ss<<"Module: "<<m_config[i]->getModuleId()<<" FE: "<< m_config[i]->getId()<<" Cfg: "<< m_config[i]->getFilename(); + logdata.configs.push_back(ss.str()); + } + } + m_scanLog->logScan(logdata); +} +void CalibGui::finishLogFile(){ + std::string runstatus; + if(isRunning()==false)runstatus="Aborted"; + else if(getStatus()==CalibGui::OK)runstatus="OK"; + else runstatus="Failed"; + std::string lstatus; + if(isRunning()==false)lstatus="Aborted"; + else if(getStatus()==CalibGui::OK)lstatus="Done"; + else lstatus="Failed"; + m_scanLog->finishLogFile(runstatus, lstatus); +} + +//==================================================================== +int main(int argc, char **argv){ + // + // Initialize command line parameters with default values + // + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); +// +// Parse arguments +// + cmd.parse(arg_iter); + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(! partition_name.isNULL()) p_name= (const char*)partition_name; + IPCPartition* partition=new IPCPartition(p_name ); + //check if somebody else is using the partition + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + + TApplication theapp("app",&argc,argv); + new CalibGui(partition, gClient->GetRoot(),800,735); + theapp.Run(); + return 0; +} + + diff --git a/rce/rcecalib/server/CalibGui.hh b/rce/rcecalib/server/CalibGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..405a1b559f867654a5c45d3f49c523b4194a9c86 --- /dev/null +++ b/rce/rcecalib/server/CalibGui.hh @@ -0,0 +1,145 @@ +#ifndef CALIBGUI_HH +#define CALIBGUI_HH + +#include "TGMdiMainFrame.h" +#include <TTimer.h> +#include <TTimeStamp.h> +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include "TFile.h" +#include <string> +#include "ConfigGui.hh" +#include "GlobalConfigGui.hh" + +namespace RCE { +class PixScan; } +namespace ipc{ + class ScanOptions; +} +class PrimListGui; +class ScanGui; +class IPCController; +class IPCHistoController; +class IPCPartition; +class TGListTree; +class TGListTreeItem; +class TH1; +class TRootEmbeddedCanvas; +class IPCGuiCallback; +class DataExporter; +class ScanLog; +class CallbackInfo; + +class CalibGui: public TGMainFrame { +public: + CalibGui(IPCPartition *partition, const TGWindow *p,UInt_t w,UInt_t h); + virtual ~CalibGui(); + int startRun(); + int setupScan(); + void enableControls(bool on); + void handleFileMenu(Int_t); + void handlePlotMenu(Int_t); + void timeouts(); + void toggle(); + void quit(); + void stopRun(); + void analyze(); + void saveHistos(); + int openFile(); + void clearTree(); + void loopAction(int i, int j); + void setupTdacTuning(int j); + void setupTdacFastTuning(int j); + void setupGdacTuningOuterLoop(); + void setupGdacTuning(int j); + void setupGdacFastTuning(int j); + void setupGdacCoarseFastTuning(int j); + void setupOffsetScan(int j); + void setupMask(int loop_i, int j); + void updateTree(); + void runloop(); + void runScan(int pr); + void verifyConfiguration(); + void displayHisto(TGListTreeItem* item, int b); + TGLabel* getEventLabel(){return m_nEvents;} + void synchSave1(); + void synchSave2(); + std::string getScanName(); + bool saveChecked(){return m_save->IsDisabledAndSelected();} + bool exportChecked(){return m_export->IsDisabledAndSelected();} + bool debugChecked(){return m_debug->IsDisabledAndSelected();} + ConfigGui* getConfig(int i){return m_config[i];} + TGTextEntry *getComment(){return m_comment;} + enum Status{OK, FAILED, ABORTED}; + Status getStatus(){return m_status;} + bool isRunning(){return m_isrunning;} + void allOffA(){switchOn(0,0);} + void allOffC(){switchOn(1,0);} + void allOffA2(){switchOn(2,0);} + void allOffC2(){switchOn(3,0);} + void allOnA(){switchOn(0,1);} + void allOnC(){switchOn(1,1);} + void allOnA2(){switchOn(2,1);} + void allOnC2(){switchOn(3,1);} + void switchOn(int panel, bool on); + void getFirm(); + void finishLogFile(); + void logScan(); + void writeGuiConfig(const char* filename); + void readGuiConfig(const char* filename); + void printFromGui(); + + static void *runloop( void *ptr ); + +private: + RCE::PixScan* currentScan(); + ipc::ScanOptions* currentScanConfig(); + void EndOfPrimListScan(); + void setRun(Bool_t on); + bool running(){return m_isrunning;} + void fillHistoTree(TGListTreeItem* branch); + enum Filemenu {LOAD, SAVE, QUIT}; + enum Plotmenu {GIF, PDF}; + PrimListGui * m_primList; + IPCPartition *m_partition; + IPCController& m_controller; + IPCHistoController& m_hcontroller; + ConfigGui* m_config[ConfigGui::MAX_MODULES]; + ScanGui * m_scan; + TGTextButton *m_start, *m_quit, *m_print; + TGCheckButton *m_save, *m_export, *m_debug; + TGLabel *m_nEvents, *m_time, *m_rate, *m_irate; + TGLabel *m_nLoop1, *m_nLoop2; + TGTextEntry *m_comment; + TGHorizontalFrame *m_datapaneldd; + TTimer *m_timers; + TTimeStamp m_starttime; + unsigned m_nevt; + unsigned m_nevtMin; + double m_oneminago; + bool m_isrunning; + Status m_status; + std::string m_oldRunName; + TGListTree *m_tree; + TH1 *m_histo; + TRootEmbeddedCanvas *m_canvas; + TFile *m_file, *m_anfile; + std::string m_exportdir; + std::string m_rcdir; + std::string m_dir; + IPCGuiCallback* m_cb; + CallbackInfo *m_cbinfo; + TString m_homedir; + TString m_logfile; + bool m_delhisto; + TGCanvas *m_tgc; + GlobalConfigGui* m_globalconf; + DataExporter *m_dataExporter; + ScanLog *m_scanLog; + const TGPicture *m_thp; + + +ClassDef (CalibGui,0) +}; +#endif diff --git a/rce/rcecalib/server/CallbackInfo.cc b/rce/rcecalib/server/CallbackInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..582fc1c942577b97000152b18ca3eb2c24db4136 --- /dev/null +++ b/rce/rcecalib/server/CallbackInfo.cc @@ -0,0 +1,51 @@ +#include "CallbackInfo.hh" +#include "TGLabel.h" + +CallbackInfo::CallbackInfo(TGLabel* label): m_label(label), m_stage(0), m_mask(0){} + +void CallbackInfo::updateGui(){ + if(m_mask==0)return; + char a[128]; + for(int i=0;i<NBITS;i++){ + if((1<<i)&m_mask){ + m_mask=0; + switch(i){ + case FAILED: + m_label->SetText("Failed"); + break; + case DONE: + m_label->SetText("Done"); + break; + case VERIFY: + m_label->SetText("Verifying"); + break; + case WAIT: + m_label->SetText("Waiting"); + break; + case ANALYZE: + m_label->SetText("Analyzing"); + break; + case SAVE: + m_label->SetText("Saving Histos"); + break; + case STOP: + m_label->SetText("RCEs done"); + break; + case DOWNLOAD: + m_label->SetText("Downloading"); + break; + case FIT: + m_label->SetText("Fit"); + break; + case NEWSTAGE: + sprintf(a, "%d", m_stage); + m_label->SetText(a); + break; + case RUNNING: + m_label->SetText("Running"); + break; + } + break; + } + } +} diff --git a/rce/rcecalib/server/CallbackInfo.hh b/rce/rcecalib/server/CallbackInfo.hh new file mode 100644 index 0000000000000000000000000000000000000000..e5cf0034c035e08514e968465e46b0d3aca08532 --- /dev/null +++ b/rce/rcecalib/server/CallbackInfo.hh @@ -0,0 +1,20 @@ +#ifndef CALLBACKINFO_HH +#define CALLBACKINFO_HH + +class TGLabel; + +class CallbackInfo{ +public: + enum guistate {FAILED, DONE, VERIFY, WAIT, ANALYZE, SAVE, STOP, DOWNLOAD, FIT, NEWSTAGE, RUNNING, NBITS}; + CallbackInfo(TGLabel* label); + void addToMask(int val){m_mask|=(1<<val);} + void setStage(int stage){m_stage=stage;} + void updateGui(); + void clear(){m_mask=0;} + bool failed(){return ((m_mask&(1<<FAILED))!=0);} +private: + TGLabel* m_label; + int m_stage; + unsigned m_mask; +}; +#endif diff --git a/rce/rcecalib/server/CmdDecoder.cc b/rce/rcecalib/server/CmdDecoder.cc new file mode 100644 index 0000000000000000000000000000000000000000..bb5122dbfa804f514db710ac04dad224eb2af806 --- /dev/null +++ b/rce/rcecalib/server/CmdDecoder.cc @@ -0,0 +1,174 @@ +#ifdef RCE_V2 +#include "datCode.hh" +#include "rcecalib/server/CmdDecoder.hh" +#include DAT_PUBLIC( service, dynalink, RunnableModule.hh) +#include DAT_PUBLIC( service, dynalink, LinkingError.hh) +#include DAT_PUBLIC( service, dynalink, Linker.hh) +#include <stdio.h> +#include <arpa/inet.h> +extern "C"{ +#include <rtems/libio.h> +} +#else +#include "rcecalib/server/CmdDecoder.hh" +#include "rce/dynalink/RunnableModule.hh" +#include "rce/dynalink/LinkingError.hh" +#include "rce/dynalink/Linker.hh" +extern "C"{ + #include <librtemsNfs.h> +} +#endif +#include <stdlib.h> +#include <signal.h> +#include <iostream> +#include <sstream> +#include "namespace_aliases.hh" + +void CmdDecoder::run(){ + const char* command; + while(1){ + command=m_eth->receiveCommand(); + std::string reply=decode(command); + m_eth->reply(reply.c_str()); + } +} + +std::string CmdDecoder::decode(const char* msg){ + //split message by whitespace + std::vector<std::string> command; + std::istringstream iss(msg); + do { + std::string sub; + iss >> sub; + command.push_back(sub); + iss.peek(); + } while (iss); + if(command.size()==0)return "Bad Command"; + if(command[0]=="reboot")return cmdReboot(command); + else if(command[0]=="setenv")return cmdSetenv(command); + else if(command[0]=="mount")return cmdMount(command); + else if(command[0]=="runTask")return cmdLd(command); + else if(command[0]=="shutdown")return cmdShutdown(command); + else if(command[0]=="download")return cmdDownload(command); + else return "Unknown command"; + return "OK"; +} +std::string CmdDecoder::cmdReboot(std::vector<std::string>& command){ + if(command.size()>1 && command[1]=="-noshutdown"){ + // do nothing + }else if(m_running==true){ + cmdShutdown(command); + usleep(500000); + } + const char *cc_argv[] = + { + "reboot", /* always the name of the program */ + "-S", + "0" + }; + int cc_argc = sizeof( cc_argv ) / sizeof( cc_argv[ 0 ] ); + m_eth->reply("Rebooting..."); +#ifdef RCE_V2 + service::shell::Reboot_main(cc_argc, (char **)cc_argv); +#else + main_reboot(cc_argc, (char **)cc_argv); +#endif + return "OK"; +} +std::string CmdDecoder::cmdSetenv(std::vector<std::string>& cmd){ + if(cmd.size()!=3)return "Wrong number of parameters for setenv."; + setenv(cmd[1].c_str(),cmd[2].c_str(), 1); + return "OK"; +} +std::string CmdDecoder::cmdMount(std::vector<std::string>& cmd){ +#ifdef RCE_V2 + if(cmd.size()!=3)return "Wrong number of parameters for mount."; + //rpcUdpInit(); + //nfsInit( 0, 0 ); + printf("BOOTP server is %s. Use as NFS server.\n",inet_ntoa( rtems_bsdnet_bootp_server_address)); + mkdir(cmd[2].c_str(),S_IRWXU|S_IRWXG|S_IRWXO); + mount(cmd[1].c_str(), cmd[2].c_str(), "nfs", RTEMS_FILESYSTEM_READ_WRITE, ""); + // int stat=mount(inet_ntoa( rtems_bsdnet_bootp_server_address), (char*)cmd[1].c_str() ,(char*)cmd[2].c_str() ); + int stat=0; + if(stat==0){ + return "OK"; + }else{ + return "NFS mount failed."; + } +#else + if(cmd.size()!=3 && cmd.size()!=4)return "Wrong number of parameters for mount."; + rpcUdpInit(); + nfsInit( 0, 0 ); + int stat=0; + if(cmd.size()==3){ + printf("BOOTP server is %s. Use as NFS server.\n",inet_ntoa( rtems_bsdnet_bootp_server_address)); + stat=nfsMount(inet_ntoa( rtems_bsdnet_bootp_server_address), (char*)cmd[1].c_str() ,(char*)cmd[2].c_str() ); + }else{ + stat=nfsMount((char*)cmd[1].c_str(), (char*)cmd[2].c_str() ,(char*)cmd[3].c_str() ); + } + if(stat==0){ + return "OK"; + }else{ + return "NFS mount failed."; + } +#endif +} +std::string CmdDecoder::cmdLd(std::vector<std::string>& cmd){ + if(cmd.size()!=2)return "Wrong number of parameters for runTask."; + if(m_running==true)return "There is already a task running. Reboot first."; + const char *cc_argv[6]={"runTask", "-P", "100", "-N", "clb", ""}; + cc_argv[5]=cmd[1].c_str(); +#ifdef RCE_V2 + int stat=service::shell::RunTask_main(6,(char**)cc_argv); +#else + int stat=main_runTask(6,(char**)cc_argv); +#endif + if(stat==0){ + m_running=true; + pause(); + return "OK"; + }else{ + return "runTask failed."; + } +} +std::string CmdDecoder::cmdShutdown(std::vector<std::string>& cmd){ + if(m_running==false)return "Calibserver is not running."; + kill(getpid(),SIGUSR1); + return "OK"; +} + +std::string CmdDecoder::cmdDownload(std::vector<std::string>& cmd){ + if(cmd.size()!=3)return "Wrong number of parameters for download."; + if(m_running==true)return "There is already a module running."; + const char* ior=getenv("TDAQ_IPC_INIT_REF"); + if(ior==0 || std::string(ior).substr(0,4)!="IOR:")return "No IOR defined"; + int bufsize=atoi(cmd[1].c_str()); + unsigned char* aBuffer; + try{ + aBuffer = RCE::ELF::RunnableModule::getBuffer(bufsize); + }catch(...){ + return "Can't allocate an ELF image buffer."; + } + m_eth->reply("OK"); + std::string reply=m_eth->receiveModule(aBuffer, bufsize); + if(reply!="OK")return reply.c_str(); + RCE::ELF::RunnableModule* rmod=new(aBuffer) RCE::ELF::RunnableModule; + try{ + RCE::Dynalink::Linker &lnk(RCE::Dynalink::Linker::instance()); + lnk.clear(); + unsigned int name=0x43414c49; //CALI + unsigned int priority = 100; + unsigned int stack = RTEMS_MINIMUM_STACK_SIZE; + unsigned int mode = RTEMS_DEFAULT_MODES; + unsigned int attr = RTEMS_DEFAULT_ATTRIBUTES; + rmod->run(name, priority, stack, mode, attr); + }catch(RCE::Dynalink::LinkingError& e) { + char rs[256]; + sprintf(rs, "Linking error: %s", e.what()); + return rs; + } + std::cout<<"Loaded module at "<<std::hex<<rmod<<std::dec<<std::endl; + m_running=true; + pause(); + return "OK"; +} diff --git a/rce/rcecalib/server/CmdDecoder.hh b/rce/rcecalib/server/CmdDecoder.hh new file mode 100644 index 0000000000000000000000000000000000000000..ab3c7883e78402218773a8bb77f4791297d55088 --- /dev/null +++ b/rce/rcecalib/server/CmdDecoder.hh @@ -0,0 +1,41 @@ +#ifndef CMDDECODER_HH +#define CMDDECODER_HH + +#include <string> +#include <vector> +#include "rcecalib/server/EthPrimitive.hh" + +// shell commands need a declaration to be used in code. +#ifdef RCE_V2 +namespace service{ + namespace shell{ + int Reboot_main(int argc, char **argv); + int RunTask_main(int argc, char **argv); + } +} +#else +int main_reboot(int argc, char **argv); +int main_runTask(int argc, char **argv); +#endif +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; + +class CmdDecoder{ +public: + CmdDecoder(EthPrimitive* eth): m_eth(eth),m_running(false){}; + void run(); +private: + std::string decode(const char* msg); + std::string cmdReboot(std::vector<std::string>& cmd); + std::string cmdSetenv(std::vector<std::string>& cmd); + std::string cmdMount(std::vector<std::string>& cmd); + std::string cmdLd(std::vector<std::string>& cmd); + std::string cmdShutdown(std::vector<std::string>& cmd); + std::string cmdDownload(std::vector<std::string>& cmd); + + EthPrimitive* m_eth; + bool m_running; + +}; + +#endif diff --git a/rce/rcecalib/server/ConfigGui.cc b/rce/rcecalib/server/ConfigGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..34b6a0af49049a10b0c1ce4b77d863610684c057 --- /dev/null +++ b/rce/rcecalib/server/ConfigGui.cc @@ -0,0 +1,498 @@ +#include "rcecalib/server/ConfigGui.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/server/HitbusConfigFile.hh" +#include "rcecalib/server/AFPHPTDCConfigFile.hh" +#include "rcecalib/util/exceptions.hh" +#include <TGFileDialog.h> +#include <sys/stat.h> +#include <boost/regex.hpp> +#include "PixelModuleConfig.hh" +#include <iostream> + +std::string ConfigGui::m_rootdir=""; + +ConfigGui::ConfigGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options, const char* prefix): + TGVerticalFrame(p,w,h,options), m_modName(name), m_valid(false), m_cfg(0), m_cfgfei4a(0), m_cfgfei4b(0), m_cfghitbus(0), + m_filename("None"), m_id(-1) { + std::string namelabel(prefix); + namelabel+=name; + m_name=new TGLabel(this,namelabel.c_str()); + AddFrame(m_name,new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 2, 2, 0, 0)); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_name->SetTextFont(labelfont); + + TGHorizontalFrame *confnl = new TGHorizontalFrame(this, 2,2 ); + AddFrame(confnl,new TGLayoutHints(kLHintsExpandX )); + TGLabel *cfg=new TGLabel(confnl,"File:"); + confnl->AddFrame(cfg,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_configname=new TGLabel(confnl,"None"); + confnl->AddFrame(m_configname,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + //TGLabel *cfgkey=new TGLabel(confnl,"-"); + //confnl->AddFrame(cfgkey,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_key=new TGLabel(confnl,""); + confnl->AddFrame(m_key,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + + TGHorizontalFrame *confdnl = new TGHorizontalFrame(this, 2,2 ); + AddFrame(confdnl,new TGLayoutHints(kLHintsExpandX )); + TGLabel *cfgd=new TGLabel(confdnl,"Dir:"); + confdnl->AddFrame(cfgd,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_confdir=new TGLabel(confdnl,"None"); + confdnl->AddFrame(m_confdir,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + + TGHorizontalFrame *confidl = new TGHorizontalFrame(this, 2,2 ); + AddFrame(confidl,new TGLayoutHints(kLHintsExpandX )); + TGLabel *cfgid=new TGLabel(confidl,"FEID:"); + confidl->AddFrame(cfgid,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_idl=new TGLabel(confidl,"-1"); + confidl->AddFrame(m_idl,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_modid=new TGLabel(confidl,""); + confidl->AddFrame(m_modid,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + TGLabel *modid=new TGLabel(confidl,"ModID:"); + confidl->AddFrame(modid,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + + TGHorizontalFrame *buttonl = new TGHorizontalFrame(this, 2,2 ); + AddFrame(buttonl,new TGLayoutHints(kLHintsExpandX )); + m_choosebutton=new TGTextButton(buttonl,"Choose Config"); + buttonl->AddFrame(m_choosebutton,new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX ,2,2,0,0)); + m_choosebutton->Connect("Clicked()", "ConfigGui", this, "openFileWindow()"); + TGTextButton *reload=new TGTextButton(buttonl,"Reload"); + buttonl->AddFrame(reload,new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX ,2,2,0,0)); + reload->Connect("Clicked()", "ConfigGui", this, "setConfig()"); + + TGHorizontalFrame *conf2 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf2,new TGLayoutHints(kLHintsExpandX )); + + TGLabel *cfgtype=new TGLabel(conf2,"Type:"); + conf2->AddFrame(cfgtype,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_configtype=new TGLabel(conf2,""); + conf2->AddFrame(m_configtype,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + + m_inlink=new TGNumberEntry(conf2, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 15); + conf2->AddFrame(m_inlink,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 0, 2, 0, 0)); + TGLabel *linklabel2=new TGLabel(conf2,"Inlink:"); + conf2->AddFrame(linklabel2,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + + TGHorizontalFrame *conf1 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf1,new TGLayoutHints(kLHintsExpandX )); + + m_configvalid=new TGCheckButton(conf1,"Valid"); + // m_configvalid->SetEnabled(false); + m_configvalid->SetOn(false); + conf1->AddFrame(m_configvalid,new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandX ,2,2,0,0)); + m_configvalid->Connect("Toggled(Bool_t)", "ConfigGui", this, "dummy(Bool_t)"); + + + m_outlink=new TGNumberEntry(conf1, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 15); + conf1->AddFrame(m_outlink,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 0, 2, 0, 0)); + TGLabel *linklabel=new TGLabel(conf1,"Outlink:"); + conf1->AddFrame(linklabel,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + + + TGHorizontalFrame *conf3 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf3,new TGLayoutHints(kLHintsExpandX )); + + m_included=new TGCheckButton(conf3,"Included"); + m_included->SetOn(false); + conf3->AddFrame(m_included,new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandX ,2,2,0,0)); + m_included->Connect("Toggled(Bool_t)", "ConfigGui", this, "setIncluded(Bool_t)"); + + m_rce=new TGNumberEntry(conf3, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 99); + conf3->AddFrame(m_rce,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 0, 2, 0, 0)); + TGLabel *linklabel3=new TGLabel(conf3,"Rce:"); + conf3->AddFrame(linklabel3,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + + /* + TGHorizontalFrame *conf4 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf4,new TGLayoutHints(kLHintsExpandX )); + m_phase=new TGNumberEntry(conf4, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 3); + conf4->AddFrame(m_phase,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 0, 2, 0, 0)); + TGLabel *linklabel4=new TGLabel(conf4,"Phase:"); + conf4->AddFrame(linklabel4,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 0, 0)); + */ +} + +ConfigGui::~ConfigGui(){ + Cleanup(); +} + +void ConfigGui::openFileWindow(){ + const char *filetypes[] = { "Config files", "*.cfg", + "All files", "*", + 0, 0 }; + boost::cmatch matches; + boost::regex re("(^.*\\/)(.+\\.cfg)"); + std::string path(m_rootdir); + std::string filename; + if(boost::regex_search(m_filename.c_str(), matches, re)){ + if(matches.size()>2){ + path=std::string(matches[1].first, matches[1].second); + filename=std::string(matches[2].first, matches[2].second); + } + } + TGFileInfo fileinfo; + fileinfo.fIniDir=StrDup(path.c_str()); + fileinfo.fFilename=StrDup(filename.c_str()); + fileinfo.fFileTypes = filetypes; + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + m_filename=fileinfo.fFilename; + setConfig(); +} +void ConfigGui::setId(int id){ + m_id=id; + char a[128]; + sprintf(a, "%d", id); + updateText(m_idl, a); + setModuleName(); +} + +void ConfigGui::setModuleName(){ + char modname[128]; + sprintf(modname,"RCE%d_module_%d",getRce(), getId()); + m_modulename=modname; +} + +void ConfigGui::setConfig(){ + //printf("%s\n",filename); + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(m_filename.c_str(),&stFileInfo); + if(std::string(m_filename)=="None" || intStat != 0) { //File does not exist + resetConfig(); + }else{ + std::ifstream cfgFile(m_filename.c_str()); + std::string inpline; + getline(cfgFile, inpline); //read the first line to determine configuration format + cfgFile.close(); + boost::regex r1("TurboDAQ"); + boost::regex r2("FEI4A"); + boost::regex r3("FEI4B"); + boost::regex r4("Hitbus"); + boost::regex r5("Hptdc"); + if(boost::regex_search(inpline, r1)==true){ + TurboDaqFile turbo; + delete m_cfg; + delete m_cfgfei4a; + delete m_cfgfei4b; + delete m_cfghitbus; + delete m_cfghptdc; + m_cfgfei4a=0; + m_cfgfei4b=0; + m_cfghitbus=0; + m_cfghptdc=0; + m_cfg=new ipc::PixelModuleConfig; + try{ + turbo.readModuleConfig(m_cfg,m_filename); + }catch(rcecalib::Config_File_Error &err){ + ers::error(err); + resetConfig(); + return; + } + int id=strtol((const char*)m_cfg->idStr,0,10); + setId(id); + setType("FEI3"); + updateText(m_modid, (const char*)m_cfg->idStr); + }else if(boost::regex_search(inpline, r2)==true){ + FEI4AConfigFile fei4afile; + delete m_cfg; + delete m_cfgfei4b; + delete m_cfghitbus; + delete m_cfghptdc; + m_cfg=0; + m_cfgfei4b=0; + m_cfghitbus=0; + m_cfghptdc=0; + delete m_cfgfei4a; + m_cfgfei4a=new ipc::PixelFEI4AConfig; + try{ + fei4afile.readModuleConfig(m_cfgfei4a, m_filename); + }catch(rcecalib::Config_File_Error &err){ + ers::error(err); + resetConfig(); + return; + } + setType("FEI4A"); + updateText(m_modid, (const char*)m_cfgfei4a->idStr); + unsigned newmodid=parseModuleId((const char*)m_cfgfei4a->idStr,m_cfgfei4a->FEGlobal.Chip_SN); + setId(newmodid); + }else if(boost::regex_search(inpline, r3)==true){ + FEI4BConfigFile fei4bfile; + delete m_cfg; + delete m_cfgfei4a; + delete m_cfghitbus; + delete m_cfghptdc; + m_cfg=0; + m_cfgfei4a=0; + m_cfghitbus=0; + m_cfghptdc=0; + delete m_cfgfei4b; + m_cfgfei4b=new ipc::PixelFEI4BConfig; + try{ + fei4bfile.readModuleConfig(m_cfgfei4b, m_filename); + }catch(rcecalib::Config_File_Error &err){ + ers::error(err); + resetConfig(); + return; + } + setType("FEI4B"); + updateText(m_modid, (const char*)m_cfgfei4b->idStr); + unsigned newmodid=parseModuleId((const char*)m_cfgfei4b->idStr,m_cfgfei4b->FEGlobal.Chip_SN); + setId(newmodid); + } else if(boost::regex_search(inpline, r4)==true){ + HitbusConfigFile turbo; + delete m_cfg; + delete m_cfgfei4a; + delete m_cfgfei4b; + delete m_cfghitbus; + delete m_cfghptdc; + m_cfgfei4a=0; + m_cfgfei4b=0; + m_cfghptdc=0; + m_cfg=0; + m_cfghitbus=new ipc::HitbusModuleConfig; + try{ + turbo.readModuleConfig(m_cfghitbus,m_filename); + }catch(rcecalib::Config_File_Error &err){ + ers::error(err); + resetConfig(); + return; + } + int id=strtol((const char*)m_cfghitbus->idStr,0,10); + setId(id); + setType("Hitbus"); + updateText(m_modid, (const char*)m_cfghitbus->idStr); + } else if(boost::regex_search(inpline, r5)==true){ + AFPHPTDCConfigFile turbo; + delete m_cfg; + delete m_cfgfei4a; + delete m_cfgfei4b; + delete m_cfghitbus; + delete m_cfghptdc; + m_cfgfei4a=0; + m_cfgfei4b=0; + m_cfghitbus=0; + m_cfg=0; + m_cfghptdc=new ipc::AFPHPTDCModuleConfig; + try{ + turbo.readModuleConfig(m_cfghptdc,m_filename); + }catch(rcecalib::Config_File_Error &err){ + ers::error(err); + resetConfig(); + return; + } + int id=strtol((const char*)m_cfghptdc->idStr,0,10); + setId(id); + setType("HPTDC"); + updateText(m_modid, (const char*)m_cfghptdc->idStr); + }else{ + std::cout<<"Unknown configuration format."<<std::endl; + resetConfig(); + return; + } + + setValid(true); + setIncluded(true); + } + boost::cmatch matches; + std::string res="/([^/]*)\\.cfg$"; // parse what's hopefully the config file name + boost::regex re; + re=res; + if(boost::regex_search(m_filename.c_str(), matches, re)){ + if(matches.size()>1){ + std::string match(matches[1].first, matches[1].second); + res="(.*)__([0-9]+)$"; // parse what's hopefully the key + re=res; + if(boost::regex_search(match.c_str(), matches, re)){ + if(matches.size()>2){ + std::string match1(matches[1].first, matches[1].second); + std::string match2(matches[2].first, matches[2].second); + updateText(m_configname,match1.c_str()); + updateText(m_key,match2.c_str()); + }else{ + updateText(m_configname,match.c_str()); + updateText(m_key,""); + } + }else{ + updateText(m_configname,match.c_str()); + updateText(m_key,""); + } + }else{ + updateText(m_configname,"None"); + updateText(m_key,""); + } + }else{ + updateText(m_configname,"None"); + updateText(m_key,""); + } + res="/([^/]*)/[^/]*/*[^/]*$"; // parse what's hopefully the module name + re=res; + if(boost::regex_search(m_filename.c_str(), matches, re)){ + if(matches.size()>1){ + std::string match(matches[1].first, matches[1].second); + updateText(m_confdir, match.c_str()); + m_path=m_filename.substr(0,matches.position()+1); + }else{ + updateText(m_confdir, "None"); + } + }else{ + updateText(m_confdir, "None"); + } + Layout(); +} +unsigned ConfigGui::parseModuleId(const char* module, unsigned felong){ + boost::cmatch matches; + std::string res="([0-9]+)-([0-9]+)-([0-9]+)"; // parse what's hopefully the Module name + boost::regex re; + re=res; + unsigned fe=felong&0x3f; + if(boost::regex_search(module, matches, re)){ + if(matches.size()>3){ + std::string match1(matches[1].first, matches[1].second); + std::string match2(matches[2].first, matches[2].second); + std::string match3(matches[3].first, matches[3].second); + unsigned val1=strtoul(match1.c_str(),0,10); + unsigned val2=strtoul(match2.c_str(),0,10); + unsigned val3=strtoul(match3.c_str(),0,10); + return val1*1e6+val2*1e4+val3*1e2+fe; + }else{ + //std::cout<<"Module string not parsable or FE ID>99. Using SN"<<std::endl; + return felong; + } + } + //std::cout<<"Module string not parsable. Using SN"<<std::endl; + return felong; +} +void ConfigGui::resetConfig(){ + setIncluded(false); + setValid(false); + setType(""); + setInLink(0); + setOutLink(0); + setRce(0); + updateText(m_configname,"None"); + updateText(m_modid, "None"); + m_filename="None"; + setId(-1); +} +void ConfigGui::updateText(TGLabel* label, const char* newtext){ + unsigned len=strlen(label->GetText()->GetString()); + label->SetText(newtext); + if (strlen(newtext)>len)Layout(); +} + +void ConfigGui::setIncluded(bool on){ + if(m_configvalid->IsOn()) + m_included->SetOn(on); + else + m_included->SetOn(false); +} + +void ConfigGui::setValid(bool on){ + m_configvalid->SetOn(on); + m_valid=on; +} +void ConfigGui::setType(const char* type){ + updateText(m_configtype, type); +} +void ConfigGui::dummy(bool on){ + // disable clicking + m_configvalid->SetOn(m_valid); +} + +bool ConfigGui::isValid(){ + return m_valid; +} + +const std::string ConfigGui::getType(){ + return std::string(m_configtype->GetText()->Data()); +} + +bool ConfigGui::isIncluded(){ + return m_included->IsOn() || m_included->IsDisabledAndSelected(); +} +void ConfigGui::enableControls(bool on){ + m_choosebutton->SetEnabled(on); + if((m_included->GetState()==kButtonDisabled)==on) + m_included->SetEnabled(on); + m_inlink->SetState(on); + m_outlink->SetState(on); + m_rce->SetState(on); + m_configvalid->SetEnabled(on); + //m_phase->SetState(true); +} + +void ConfigGui::writeConfig(std::ofstream &ofile){ + copyConfig(ofile, m_filename.c_str()); +} + +void ConfigGui::copyConfig(std::ofstream &ofile, const char* filename){ + std::string fn(filename); + if(fn.substr(0,m_rootdir.size())==m_rootdir){ + ofile<<fn.substr(m_rootdir.size())<<std::endl; + }else{ + ofile<<filename<<std::endl; + } + ofile<<isIncluded()<<std::endl; + ofile<<getInLink()<<std::endl; + ofile<<getOutLink()<<std::endl; + ofile<<getRce()<<std::endl; + ofile<<getPhase()<<std::endl; +} +void ConfigGui::readConfig(std::ifstream &ifile){ + ifile>>m_filename; + if(m_filename[0]!='/')m_filename=m_rootdir+m_filename; //relative path + setConfig(); + bool incl; + ifile>>incl; + setIncluded(incl); + int link; + ifile >> link; + setInLink(link); + ifile >> link; + setOutLink(link); + ifile >> link; + setRce(link); + ifile >> link; + setPhase(link); +} +void ConfigGui::copyConfig(const char* dirname){ + if(getType()=="FEI3"){ + boost::cmatch matches; + std::string res="(.*)/[^/]*/[^/]*$"; // parse what's hopefully the module name + boost::regex re; + re=res; + if(boost::regex_search(m_filename.c_str(), matches, re)){ + if(matches.size()>1){ + std::string match(matches[1].first, matches[1].second); + char cmd[512]; + sprintf(cmd,"cp -r %s %s", match.c_str(), dirname); + system (cmd); + }else + std::cout<<"Bad config file name"<<std::endl; + }else + std::cout<<"Bad config file name"<<std::endl; + }else if(getType()=="FEI4A"){ + FEI4AConfigFile cf; + cf.writeModuleConfig(getFEI4AConfig(), dirname, getConfdir(), getConfigName(), getKey()); + }else if(getType()=="FEI4B"){ + FEI4BConfigFile cf; + cf.writeModuleConfig(getFEI4BConfig(), dirname, getConfdir(), getConfigName(), getKey()); + }else if(getType()=="Hitbus"){ + HitbusConfigFile cf; + cf.writeModuleConfig(getHitbusConfig(), dirname, getConfdir(), getConfigName(), getKey()); + }else if(getType()=="HPTDC"){ + AFPHPTDCConfigFile cf; + cf.writeModuleConfig(getHPTDCConfig(), dirname, getConfdir(), getConfigName(), getKey()); + }else{ + std::cout<<"Unknown config type"<<std::endl; + assert(0); + } +} + diff --git a/rce/rcecalib/server/ConfigGui.hh b/rce/rcecalib/server/ConfigGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..752f96db32644d7e508020be04c2807df0710fe1 --- /dev/null +++ b/rce/rcecalib/server/ConfigGui.hh @@ -0,0 +1,93 @@ +#ifndef CONFIGGUI_HH +#define CONFIGGUI_HH + +#include <TGButton.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include <TGLabel.h> +#include <string> +#include <fstream> + +namespace ipc{ + class PixelModuleConfig; + class PixelFEI4AConfig; + class PixelFEI4BConfig; + class HitbusModuleConfig; + class AFPHPTDCModuleConfig; +} +class ConfigGui: public TGVerticalFrame{ +public: + enum constants{MAX_MODULES=64}; + ConfigGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options, const char* prefix="Frontend "); + virtual ~ConfigGui(); + void setConfig(); + void openFileWindow(); + void setIncluded(bool on); + void setValid(bool on); + void resetConfig(); + void setType(const char* type); + void dummy(bool on); + bool isValid(); + const std::string getType(); + void enableControls(bool on); + bool isIncluded(); + ipc::PixelModuleConfig* getModuleConfig(){return m_cfg;} + ipc::PixelFEI4AConfig* getFEI4AConfig(){return m_cfgfei4a;} + ipc::PixelFEI4BConfig* getFEI4BConfig(){return m_cfgfei4b;} + ipc::HitbusModuleConfig* getHitbusConfig(){return m_cfghitbus;} + ipc::AFPHPTDCModuleConfig* getHPTDCConfig(){return m_cfghptdc;} + void setInLink(int link){m_inlink->SetIntNumber(link);} + int getInLink(){return m_inlink->GetIntNumber();} + void setOutLink(int link){m_outlink->SetIntNumber(link);} + int getOutLink(){return m_outlink->GetIntNumber();} + void setRce(int link){m_rce->SetIntNumber(link);setModuleName();} + int getRce(){return m_rce->GetIntNumber();} + void setPhase(int phase){}//{m_phase->SetIntNumber(phase);} //obsolete function + int getPhase(){return 0;}//{return m_phase->GetIntNumber();} //obsolete function + void setId(int id); + int getId(){return m_id;} + const char* getModuleName(){return m_modulename.c_str();} + const char* getConfdir(){return m_confdir->GetText()->Data();} + const char* getKey(){return m_key->GetText()->Data();} + const char* getConfigName(){return m_configname->GetText()->Data();} + const char* getModuleId(){return m_modid->GetText()->Data();} + std::string getPath(){return m_path;} + void setModuleName(); + void updateText(TGLabel* label, const char* newtext); + void readConfig(std::ifstream &ifile); + void writeConfig(std::ofstream &ofile); + void copyConfig(std::ofstream &ofile, const char* filename); + void copyConfig(const char* dirname); + void setFilename(const char* filename){m_filename=filename;} + const char* getFilename(){return m_filename.c_str();} + const char* getName(){return m_modName.c_str();} + static void setRootDir(std::string s){ + m_rootdir=s; + } + static std::string getRootDir(){ + return m_rootdir; + } +private: + unsigned parseModuleId(const char* module, unsigned fe); + TGLabel *m_name, *m_configname, *m_idl, *m_key, *m_confdir, *m_modid, *m_configtype; + TGTextButton *m_choosebutton; + TGCheckButton *m_configvalid, *m_included; + TGNumberEntry *m_inlink, *m_outlink, *m_rce, *m_phase; + std::string m_modName; + bool m_valid; + ipc::PixelModuleConfig *m_cfg; + ipc::PixelFEI4AConfig *m_cfgfei4a; + ipc::PixelFEI4BConfig *m_cfgfei4b; + ipc::HitbusModuleConfig *m_cfghitbus; + ipc::AFPHPTDCModuleConfig *m_cfghptdc; + std::string m_filename; + std::string m_modulename; + std::string m_path; + int m_id; + + static std::string m_rootdir; + + ClassDef(ConfigGui,0); +}; + +#endif diff --git a/rce/rcecalib/server/CosmicDataReceiver.cc b/rce/rcecalib/server/CosmicDataReceiver.cc new file mode 100644 index 0000000000000000000000000000000000000000..6e5f3112dcd528dcbde05d243b57de4c4938c3d3 --- /dev/null +++ b/rce/rcecalib/server/CosmicDataReceiver.cc @@ -0,0 +1,268 @@ +#include "CosmicDataReceiver.hh" + +#include "CosmicGui.hh" + +#include "eudaq/TransportFactory.hh" +#include "eudaq/Event.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" + +#include "CosmicMonitoringGuiEmbedded.hh" + +void * CosmicDataReceiver_thread(void * arg) +{ + CosmicDataReceiver * cdr = static_cast<CosmicDataReceiver *>(arg); + cdr->DataThread(); + return 0; +} + +CosmicDataReceiver::CosmicDataReceiver(CosmicGui * gui, + IPCController* controller, + std::vector<ModuleInfo*> modinfo, + std::vector<int> rcesAll, + unsigned runnum, + const std::string & listenAddress, + const std::string& outputFile, + bool writeEudet, bool writeRaw) : +m_gui(gui), +m_dataserver(eudaq::TransportFactory::CreateServer(listenAddress)), +m_thread(), +m_done(false), +m_listening(true) +{ + m_dataproc=new CosmicOfflineDataProc(controller, modinfo, rcesAll, runnum, outputFile, writeEudet, writeRaw); + m_dataserver->SetCallback(eudaq::TransportCallback(this, &CosmicDataReceiver::DataHandler)); + pthread_attr_init(&m_threadattr); + pthread_create(&m_thread, &m_threadattr, CosmicDataReceiver_thread, this); +} + +CosmicDataReceiver::~CosmicDataReceiver() +{ + usleep(250000); //wait for buffer to flush + m_done = true; + pthread_join(m_thread, 0); + delete m_dataproc; + if (m_connection.size()>0){ + for(size_t i_connect =0; i_connect<m_connection.size(); i_connect++){ + delete m_connection[i_connect]; + } + m_connection.clear(); + } + delete m_dataserver; + +} + +void CosmicDataReceiver::OnReceive(counted_ptr<eudaq::Event> ev) +{ + // std::cout << "<CosmicDataReceiver::OnReceive> : Function called!" << std::endl; + // ev->Print(std::cout); + + // counted_ptr<eudaq::DetectorEvent> event((eudaq::DetectorEvent*)eudaq::EventFactory::Create(ser)); + eudaq::DetectorEvent* dev = (eudaq::DetectorEvent*)ev.get(); + m_gui->monitoringGui->addEvent(dev); + if(dev->GetEventNumber()!=0)m_gui->incrementNevents(); + + return; +} + +void CosmicDataReceiver::DataThread() +{ + try + { + while (!m_done) m_dataserver->Process(100000); + } + catch (const std::exception & e) + { + std::cout << "Error: Uncaught exception: " << e.what() << "\n" + << "DataThread is dying..." << std::endl; + } + catch (...) + { + std::cout << "Error: Uncaught unrecognised exception: \n" + << "DataThread is dying..." << std::endl; + } + + return; +} + +void CosmicDataReceiver::DataHandler(eudaq::TransportEvent & ev) +{ + static int cout_count; // keep track of how many RECEIVE cout printout has been printed + static const int cout_limit = 3; + + // std::vector<unsigned char> begdata(ev.packet.begin(), ev.packet.end()); + // std::cout<<"received data packet with size = "<<begdata.size()<<std::endl; + + + // Note: the type of ev.id is "eudaq::ConnectionInfo" + switch (ev.etype) + { + case (eudaq::TransportEvent::CONNECT): + std::cout << "<CosmicDataReceiver::DataHandler> : CONNECT" << std::endl; + if (m_listening) + { + m_dataserver->SendPacket("OK EUDAQ DATA DataCollector", ev.id, true); + } + else + { + m_dataserver->SendPacket("ERROR EUDAQ DATA CosmicDataReceiver not accepting connections", + ev.id, true); + m_dataserver->Close(ev.id); + } + break; + + case (eudaq::TransportEvent::DISCONNECT): + std::cout << "<CosmicDataReceiver::DataHandler> : DISCONNECT" << std::endl; + if (m_connection.size()==0) + { + std::cout << "<CosmicDataReceiver::DataHandler> : Warning: disconnect attempted when no " + << "m_connection is set." << std::endl; + } + else { + + int id_connect=-1; + int nConnections = m_connection.size(); + for(int i_connect = 0; i_connect<nConnections; i_connect++){ + if (ev.id.Matches(*m_connection[i_connect])){ + id_connect = i_connect; + break; + } + } + + if(id_connect>=0){ + delete m_connection[id_connect]; + m_connection.erase(m_connection.begin() + id_connect); //remove this element from vector + } + else{ + std::cout << "<CosmicDataReceiver::DataHandler> : Warning: attempted to disconnect " + << "from "<<ev.id<<", but this does not exist in m_connection list." << std::endl; + } + + } + break; + + case (eudaq::TransportEvent::RECEIVE): + if (cout_count < cout_limit) + { + cout_count++; + std::cout << "<CosmicDataReceiver::DataHandler> : RECEIVE" << std::endl; + } + else if (cout_count == cout_limit) + { + cout_count++; + std::cout << "<CosmicDataReceiver::DataHandler> : RECEIVE (output limit reached, no more cout for future events)." << std::endl; + } + + + if (ev.id.GetState() == 0) // Waiting for identification + { + + size_t i0 = 0, i1 = ev.packet.find(' '); + if (i1 == std::string::npos) break; + std::string part(ev.packet, i0, i1); + if (part != "OK") break; + i0 = i1+1; + i1 = ev.packet.find(' ', i0); + if (i1 == std::string::npos) break; + part = std::string(ev.packet, i0, i1-i0); + if (part != "EUDAQ") break; + i0 = i1+1; + i1 = ev.packet.find(' ', i0); + if (i1 == std::string::npos) break; + part = std::string(ev.packet, i0, i1-i0); + if (part != "DATA") break; + i0 = i1+1; + i1 = ev.packet.find(' ', i0); + part = std::string(ev.packet, i0, i1-i0); + ev.id.SetType(part); + i0 = i1+1; + i1 = ev.packet.find(' ', i0); + part = std::string(ev.packet, i0, i1-i0); + ev.id.SetName(part); + + m_dataserver->SendPacket("OK", ev.id, true); + ev.id.SetState(1); + std::string name = ev.id.GetName(); + if (name != std::string("CosmicGuiDataSender")) + { + // This is not the data sender for the cosmic gui; do nothing + std::cout << "name is: " << name << std::endl; + break; + } + else + { + //Check to see if this connection is already made; if it's not, add it. + int id_connect=-1; + int nConnections = m_connection.size(); + for(int i_connect = 0; i_connect<nConnections; i_connect++){ + if (ev.id.Matches(*m_connection[i_connect])){ + id_connect = i_connect; + break; + } + } + + if(id_connect<0){ + // eudaq::ConnectionInfo* newConnection = ev.id.Clone(); + m_connection.push_back(0); + size_t nConnections = m_connection.size(); + m_connection[nConnections-1] = ev.id.Clone(); + } + else{ + std::cout << "<CosmicDataReceiver::DataHandler> : Request to connect " + << "to "<<ev.id<<", but this connection already exists. Ignoring." << std::endl; + } + + } + } + else + { + + if (m_connection.size() == 0) + { + std::cout << "<CosmicDataReceiver::DataHandler> : Receiving but m_connection is not set." + << std::endl; + } + else + { + + int id_connect=-1; + int nConnections = m_connection.size(); + for(int i_connect = 0; i_connect<nConnections; i_connect++){ + if (ev.id.Matches(*m_connection[i_connect])){ + id_connect = i_connect; + break; + } + } + + if (id_connect < 0){ + std::cout << "<CosmicDataReceiver::DataHandler> : Received data, but do not recognize the " + << " ev.id : "<<ev.id<<" , so ignoring data."<<std::endl; + break; + } + + std::vector<unsigned char> data(ev.packet.begin(), ev.packet.end()); + size_t i=0; + while(i<data.size()){ + // int length=data[i]<<8|data[i+1]; + unsigned short length=*(unsigned short*)&data[i]; + if(length==0){ + std::cout<<"Length 0 event"<<std::endl; + break; + } + unsigned short link=*(unsigned short*)&data[i+2]; + //unsigned short link=data[i+2]<<8|data[i+3]; + int retval=m_dataproc->processData(link, &data[i+4], length); + if(retval==1)break;//resynch + i+=length+4; + } + + } + } + break; + + default: + std::cout << "<CosmicDataReceiver::DataHandler> : Unknown event type: " << ev.id << std::endl; + } + + return; +} diff --git a/rce/rcecalib/server/CosmicDataReceiver.hh b/rce/rcecalib/server/CosmicDataReceiver.hh new file mode 100644 index 0000000000000000000000000000000000000000..0f029e6b6950171b98a0b9fa5bd80ab0269f2026 --- /dev/null +++ b/rce/rcecalib/server/CosmicDataReceiver.hh @@ -0,0 +1,45 @@ +#ifndef COSMICDATARECEIVER_HH +#define COSMICDATARECEIVER_HH + +#include <pthread.h> +#include <string> + +class CosmicGui; +class ModuleInfo; +class IPCController; + +#include "rcecalib/eudaq/TransportServer.hh" +#include "rcecalib/eudaq/Event.hh" +#include "rcecalib/dataproc/CosmicEventReceiver.hh" +#include "rcecalib/server/CosmicOfflineDataProc.hh" + +class CosmicDataReceiver: public CosmicEventReceiver +{ + public: + CosmicDataReceiver(CosmicGui * gui, + IPCController* controller, + std::vector<ModuleInfo*> modinfo, + std::vector<int> rcesAll, + unsigned runnum, + const std::string & listenAddress, const std::string& outputFile, + bool writeEudet, bool writeRaw); + ~CosmicDataReceiver(); + + void OnReceive(counted_ptr<eudaq::Event> ev); + + void DataThread(); + + private: + void DataHandler(eudaq::TransportEvent & ev); + + CosmicGui * m_gui; // Pointer to the gui to pass information back + eudaq::TransportServer * m_dataserver; // Receives the data packets + pthread_t m_thread; + pthread_attr_t m_threadattr; + bool m_done; + bool m_listening; + std::vector<eudaq::ConnectionInfo*> m_connection; + CosmicOfflineDataProc* m_dataproc; +}; + +#endif diff --git a/rce/rcecalib/server/CosmicGui.cc b/rce/rcecalib/server/CosmicGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..0bf347216109d15820d41fba2400a891b5e89467 --- /dev/null +++ b/rce/rcecalib/server/CosmicGui.cc @@ -0,0 +1,1373 @@ +#include <ipc/partition.h> +#include <ipc/core.h> +#include "rcecalib/server/CosmicDataReceiver.hh" +#include "rcecalib/server/CosmicGui.hh" +#include "rcecalib/server/GlobalConfigGui.hh" +#include "rcecalib/util/VerifyErrors.hh" +#include "rcecalib/server/CosmicMonitoringGuiEmbedded.hh" +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/ScanLog.hh" +#include "rcecalib/server/atlasimage.hh" +#include "rcecalib/config/FEI3/JJFormatter.hh" +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FEI4/FEI4BFormatter.hh" +#include "rcecalib/config/afp-hptdc/AFPHPTDCFormatter.hh" +#include "rcecalib/config/ModuleInfo.hh" +#include "ScanOptions.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TGIcon.h" +#include "TGMenu.h" +#include "TGTab.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TStyle.h> +#include <cmdl/cmdargs.h> +#include <iostream> +#include <time.h> +#include <sys/stat.h> +#include <fstream> +#include <list> +#include <netdb.h> + + +#include <boost/property_tree/ptree.hpp> + +#include <is/infoT.h> +#include <is/infodictionary.h> + +using namespace RCE; + +CosmicGui::~CosmicGui(){ + Cleanup(); + if (m_dataReceiver) delete m_dataReceiver; + m_dataReceiver = 0; +} + +CosmicGui::CosmicGui(IPCController& controller, bool autostart, const TGWindow *p,UInt_t w,UInt_t h) + : TGMainFrame(p,w,h), m_controller(controller), m_realTime(true), m_dataReceiver(0) +{ + + // connect x icon on window manager + Connect("CloseWindow()","CosmicGui",this,"quit()"); + + TGMenuBar *menubar=new TGMenuBar(this,1,1,kHorizontalFrame | kRaisedFrame); + TGLayoutHints *menubarlayout=new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + // menu "File" + TGPopupMenu* filepopup=new TGPopupMenu(gClient->GetRoot()); + filepopup->AddEntry("&Load Config",LOAD); + filepopup->AddEntry("&Save Config",SAVE); + filepopup->AddSeparator(); + filepopup->AddEntry("Save &Histograms",HISTOS); + filepopup->AddEntry("Save &Screenshot",SCREENSHOT); + filepopup->AddSeparator(); + filepopup->AddEntry("&Quit",QUIT); + menubar->AddPopup("&File",filepopup,menubarlayout); + + AddFrame(menubar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,2)); + + filepopup->Connect("Activated(Int_t)","CosmicGui",this,"handleFileMenu(Int_t)"); + + TGTab* fTab = new TGTab(this); + AddFrame(fTab,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY )) ; + TGCompositeFrame *tab0 = fTab->AddTab("Main"); + TGCompositeFrame *tab1 = fTab->AddTab("Config DUT 1-16"); + TGCompositeFrame *tab2 = fTab->AddTab("Config Telescope 1-16"); + TGCompositeFrame *datapanelt2x = fTab->AddTab("Config DUT 17-32"); + TGCompositeFrame *datapanelt2bx = fTab->AddTab("Config Telescope 17-32"); + TGCompositeFrame *tab3 = fTab->AddTab("Monitoring"); + + TGVerticalFrame* mainframe=new TGVerticalFrame(tab0,2,2,kSunkenFrame); + TGHorizontalFrame *datapanel1 = new TGHorizontalFrame(mainframe, 2, 2, kSunkenFrame); + mainframe->AddFrame(datapanel1,new TGLayoutHints(kLHintsExpandX ,0,0,0,20)); + TGHorizontalFrame *datapanel44 = new TGHorizontalFrame(mainframe, 2, 2, kSunkenFrame); + mainframe->AddFrame(datapanel44,new TGLayoutHints(kLHintsExpandX ,0,0,0,20)); + TGHorizontalFrame *datapanel2 = new TGHorizontalFrame(mainframe, 2, 2, kSunkenFrame); + mainframe->AddFrame(datapanel2,new TGLayoutHints(kLHintsExpandX )); + TGHorizontalFrame *datapanel3 = new TGHorizontalFrame(mainframe, 2, 2, kSunkenFrame); + mainframe->AddFrame(datapanel3,new TGLayoutHints(kLHintsExpandX)); + TGHorizontalFrame *datapanel5 = new TGHorizontalFrame(mainframe, 2, 2, kSunkenFrame); + mainframe->AddFrame(datapanel5,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + tab0->AddFrame(mainframe,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + TGVerticalFrame *datapanel4[4]; + datapanel4[0] = new TGVerticalFrame(tab1, 2, 2, kSunkenFrame); + tab1->AddFrame(datapanel4[0],new TGLayoutHints(kLHintsExpandX)); + datapanel4[1] = new TGVerticalFrame(tab2, 2, 2, kSunkenFrame); + tab2->AddFrame(datapanel4[1],new TGLayoutHints(kLHintsExpandX)); + datapanel4[2] = new TGVerticalFrame(datapanelt2x, 2, 2, kSunkenFrame); + datapanelt2x->AddFrame(datapanel4[2],new TGLayoutHints(kLHintsExpandX)); + datapanel4[3] = new TGVerticalFrame(datapanelt2bx, 2, 2, kSunkenFrame); + datapanelt2bx->AddFrame(datapanel4[3],new TGLayoutHints(kLHintsExpandX)); + + + + int modperpanel=ConfigGui::MAX_MODULES/4; + for(int j=0;j<4;j++){ + TGHorizontalFrame *datapanelb=new TGHorizontalFrame(datapanel4[j]); + datapanel4[j]->AddFrame(datapanelb,new TGLayoutHints(kLHintsExpandX )); + TGTextButton *alloff=new TGTextButton(datapanelb,"All Off"); + alloff->SetMargins(15,25,0,0); + datapanelb->AddFrame(alloff,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,2,2,2,2)); + TGTextButton *allon=new TGTextButton(datapanelb,"All On"); + allon->SetMargins(15,25,0,0); + datapanelb->AddFrame(allon,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,2,2,2,2)); + if(j==0){ + alloff->Connect("Clicked()", "CosmicGui", this,"allOffA()"); + allon->Connect("Clicked()", "CosmicGui", this,"allOnA()"); + }else if(j==1){ + alloff->Connect("Clicked()", "CosmicGui", this,"allOffC()"); + allon->Connect("Clicked()", "CosmicGui", this,"allOnC()"); + }else if(j==2){ + alloff->Connect("Clicked()", "CosmicGui", this,"allOffA2()"); + allon->Connect("Clicked()", "CosmicGui", this,"allOnA2()"); + }else if(j==3){ + alloff->Connect("Clicked()", "CosmicGui", this,"allOffC2()"); + allon->Connect("Clicked()", "CosmicGui", this,"allOnC2()"); + } + TGHorizontalFrame *datapanelc[4]; + for(int i=0;i<4;i++){ + datapanelc[i] = new TGHorizontalFrame(datapanel4[j]); + datapanel4[j]->AddFrame(datapanelc[i],new TGLayoutHints(kLHintsExpandX |kLHintsExpandY)); + } + char modname[128]; + for (int i=0;i<modperpanel;i++){ + if(j%2==0) sprintf(modname, "DUT FE %d", 1+i+(j/2)*16); + else sprintf(modname, "Telescope FE %d", 1+i+(j/2)*16); + m_config[i+modperpanel*j]=new ConfigGui(modname, datapanelc[i/(modperpanel/4)],1,1, kSunkenFrame, ""); + datapanelc[i/(modperpanel/4)]->AddFrame(m_config[i+modperpanel*j],new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,1,1)); + } + } + + std::vector<ConfigGui*> vec_config(m_config,m_config+ConfigGui::MAX_MODULES); + monitoringGui = new CosmicMonitoringGuiEmbedded(tab3,1,1,kSunkenFrame,vec_config); + tab3->AddFrame(monitoringGui,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY)); + + m_globalconf=new GlobalConfigGui(m_config, ".cosmicDaq.rc", datapanel1, 1, 1, kSunkenFrame); + datapanel1->AddFrame(m_globalconf,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2)); + + m_isrunning=false; + m_nevtMin=0; + m_nevt=0; + m_timers=new TTimer; + m_timers->Connect("Timeout()","CosmicGui",this,"timeouts()"); + m_timerm=new TTimer; + m_timerm->Connect("Timeout()","CosmicGui",this,"timeoutm()"); + m_timerl=new TTimer; + m_timerl->Connect("Timeout()","CosmicGui",this,"timeoutl()"); + + FontStruct_t maskfont= gClient->GetFontByName("-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1"); + TGVerticalFrame *startmenu = new TGVerticalFrame(datapanel2, 0, 0, kSunkenFrame); + datapanel2->AddFrame(startmenu, new TGLayoutHints(kLHintsTop|kLHintsLeft, 2,2,0,2)); + TGLabel *startmenulabel=new TGLabel(startmenu,"Run Options:"); + startmenulabel->SetTextFont(maskfont); + startmenu->AddFrame(startmenulabel,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 0, 50)); + + m_start=new TGTextButton(startmenu,"Start Run"); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_start->SetFont(labelfont); + m_start->SetMargins(10,40,10,10); + startmenu->AddFrame(m_start,new TGLayoutHints(kLHintsCenterY | kLHintsCenterX ,2,2,5,5)); + m_start->Connect("Clicked()", "CosmicGui", this, "toggle()"); + + TGHorizontalFrame *maxevents = new TGHorizontalFrame(startmenu); + startmenu->AddFrame(maxevents, new TGLayoutHints(kLHintsCenterY|kLHintsLeft,0,0,5,5)); + + m_maxtrue = new TGCheckButton(maxevents); + maxevents->AddFrame(m_maxtrue, new TGLayoutHints(kLHintsLeft|kLHintsCenterY)); + TGLabel *maximum=new TGLabel(maxevents,"Max Evts"); + maxevents->AddFrame(maximum, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,0,0,0,0)); + m_maxevents=new TGNumberEntry(maxevents, 0, 10, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMin, 0); + maxevents->AddFrame(m_maxevents, new TGLayoutHints(kLHintsCenterY|kLHintsLeft,5,0,5,5)); + TGVerticalFrame *fileframe= new TGVerticalFrame(startmenu, 0, 0, kSunkenFrame); + startmenu->AddFrame(fileframe,new TGLayoutHints(kLHintsCenterY|kLHintsCenterX ,10,0,20,10)); + TGLabel *filelabel=new TGLabel(fileframe,"File Format:"); + fileframe->AddFrame(filelabel,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 2, 0)); + m_eudetfile=new TGCheckButton(fileframe,"Eudet"); + fileframe->AddFrame(m_eudetfile,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,15,0,3,3)); + m_rawfile=new TGCheckButton(fileframe,"Raw"); + fileframe->AddFrame(m_rawfile,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,15,0,3,3)); + m_writeRootFile=new TGCheckButton(fileframe,"ROOT"); + fileframe->AddFrame(m_writeRootFile,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,15,0,3,3)); + + + TGVerticalFrame *trigmenu1 = new TGVerticalFrame(datapanel2, 0, 0, kSunkenFrame); + datapanel2->AddFrame(trigmenu1,new TGLayoutHints(kLHintsCenterY ,2,0,0,0)); + + TGLabel *tscl=new TGLabel(trigmenu1,"Trigger Sources:"); + tscl->SetTextFont(maskfont); + trigmenu1->AddFrame(tscl,new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 0, 0, 0, 0)); + m_scint=new TGCheckButton(trigmenu1,"Scintillators"); + trigmenu1->AddFrame(m_scint,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,0,0,0,0)); + m_eudet=new TGCheckButton(trigmenu1,"Eudet Trg"); + trigmenu1->AddFrame(m_eudet,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,0,0,0,0)); + TGVerticalFrame *trigmenu7 = new TGVerticalFrame(trigmenu1, 0, 0, kSunkenFrame); + trigmenu1->AddFrame(trigmenu7,new TGLayoutHints(kLHintsCenterX ,5,0,0,0)); + TGHorizontalFrame *trigmenu7a = new TGHorizontalFrame(trigmenu7); + trigmenu7->AddFrame(trigmenu7a,new TGLayoutHints(kLHintsCenterX ,0,0,0,0)); + TGVerticalFrame *trigmenu7b = new TGVerticalFrame(trigmenu7a); + trigmenu7a->AddFrame(trigmenu7b,new TGLayoutHints(kLHintsCenterX ,0,0,0,0)); + TGVerticalFrame *trigmenu7c = new TGVerticalFrame(trigmenu7a); + trigmenu7a->AddFrame(trigmenu7c,new TGLayoutHints(kLHintsCenterX ,0,0,0,0)); + m_HSIO1=new TGCheckButton(trigmenu7b,"HSIO Ext 1"); + trigmenu7b->AddFrame(m_HSIO1,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,0,0,15,0)); + m_HSIO2=new TGCheckButton(trigmenu7b,"HSIO Ext 2"); + trigmenu7b->AddFrame(m_HSIO2,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,0,0,0,0)); + m_hsiologic=new TGButtonGroup(trigmenu7c, 2, 1, 2, 0, "Logic"); + trigmenu7c->AddFrame(m_hsiologic, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 0, 0)); + new TGRadioButton(m_hsiologic, "OR", 0); + new TGRadioButton(m_hsiologic, "AND", 1); + m_hsiologic->SetButton(1); + m_hsiostate=1; + m_hsiologic->Connect("Pressed(Int_t)", "CosmicGui", this, "setHsioLogic(Int_t)"); + + TGVerticalFrame *trigmenu4 = new TGVerticalFrame(trigmenu1, 0, 0, kSunkenFrame); + trigmenu1->AddFrame(trigmenu4,new TGLayoutHints(kLHintsCenterX ,15,0,0,0)); + m_cyclic=new TGCheckButton(trigmenu4,"Cyclic Trg"); + trigmenu4->AddFrame(m_cyclic,new TGLayoutHints(kLHintsCenterY | kLHintsLeft ,0,0,0,0)); + TGLabel *cperiodl=new TGLabel(trigmenu4,"Cyclic Period (ticks)"); + trigmenu4->AddFrame(cperiodl,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 3, 3, 0, 0)); + m_cperiod=new TGNumberEntry(trigmenu4,0,10,-1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); + trigmenu4->AddFrame(m_cperiod,new TGLayoutHints(kLHintsCenterY |kLHintsCenterX, 0, 0, 3, 3)); + TGVerticalFrame *trigmenuhb = new TGVerticalFrame(trigmenu1, 0, 0, kSunkenFrame); + trigmenu1->AddFrame(trigmenuhb,new TGLayoutHints(kLHintsCenterX ,15,0,0,0)); + m_hitbus=new TGCheckButton(trigmenuhb,"Hitbus"); + trigmenuhb->AddFrame(m_hitbus,new TGLayoutHints(kLHintsTop | kLHintsLeft ,0,0,0,0)); + m_hbinput=new TGButtonGroup(trigmenuhb, 4, 1, 4, 0, "Logic"); + trigmenuhb->AddFrame(m_hbinput, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 0, 0)); + new TGRadioButton(m_hbinput, "Chip 1", 1); + new TGRadioButton(m_hbinput, "Chip 2", 2); + new TGRadioButton(m_hbinput, "1 OR 2", 3); + new TGRadioButton(m_hbinput, "1 AND 2", 4); + m_hbstate=1; + m_hbinput->Connect("Pressed(Int_t)", "CosmicGui", this, "setHbLogic(Int_t)"); + + + TGVerticalFrame *hbframe= new TGVerticalFrame(datapanel2, 0, 0, kSunkenFrame); + datapanel2->AddFrame(hbframe,new TGLayoutHints(kLHintsTop ,5,0,0,0)); + TGLabel *hbchiplabel=new TGLabel(hbframe,"Hitbus Chips:"); + hbchiplabel->SetTextFont(maskfont); + hbframe->AddFrame(hbchiplabel,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 0, 0)); + TGTab* hTab = new TGTab(hbframe); + hbframe->AddFrame(hTab,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY )) ; + TGCompositeFrame *tabh[2]; + tabh[0] = hTab->AddTab("Hitbus Chip 1"); + tabh[1] = hTab->AddTab("Hitbus Chip 2"); + for (int k=0;k<2;k++){ + TGHorizontalFrame *trigmenu5 = new TGHorizontalFrame(tabh[k]); + tabh[k]->AddFrame(trigmenu5,new TGLayoutHints(kLHintsCenterY ,15,2,2,2)); + TGVerticalFrame *planeframe= new TGVerticalFrame(trigmenu5); + trigmenu5->AddFrame(planeframe, new TGLayoutHints(kLHintsCenterY)); + m_tp[k][0]=new TGCheckButton(planeframe,"TA1"); + m_tp[k][1]=new TGCheckButton(planeframe,"TA2"); + m_tp[k][2]=new TGCheckButton(planeframe,"TA3"); + m_tp[k][3]=new TGCheckButton(planeframe,"TB1"); + m_tp[k][4]=new TGCheckButton(planeframe,"TB2"); + m_tp[k][5]=new TGCheckButton(planeframe,"TB3"); + for (int i=0;i<3;i++) + planeframe->AddFrame(m_tp[k][i],new TGLayoutHints(kLHintsTop | kLHintsLeft ,2,0,0,0)); + TGLabel *hcl=new TGLabel(planeframe,"RCE"); + planeframe->AddFrame(hcl,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 0, 10, 0)); + m_hbrce[k]=new TGNumberEntry(planeframe,0,2,-1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); + planeframe->AddFrame(m_hbrce[k],new TGLayoutHints(kLHintsCenterY |kLHintsLeft, 0, 0, 3, 10)); + for (int i=3;i<6;i++) + planeframe->AddFrame(m_tp[k][i],new TGLayoutHints(kLHintsTop | kLHintsLeft ,2,0,0,0)); + TGVerticalFrame *logframe= new TGVerticalFrame(trigmenu5); + trigmenu5->AddFrame(logframe, new TGLayoutHints(kLHintsTop)); + m_talogic[k]=new TGButtonGroup(logframe, "TA Logic"); + logframe->AddFrame(m_talogic[k], new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 0, 0)); + new TGRadioButton(m_talogic[k], "OR", 0); + new TGRadioButton(m_talogic[k], "AND", 1); + m_talogic[k]->SetButton(0); + m_tastate[k]=0; + m_tablogic[k]=new TGButtonGroup(logframe, 1, 2, 5, 0, "TA to TB"); + logframe->AddFrame(m_tablogic[k], new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 0, 0)); + new TGRadioButton(m_tablogic[k], "OR", 0); + new TGRadioButton(m_tablogic[k], "AND", 1); + m_tablogic[k]->SetButton(0); + m_tabstate[k]=0; + m_tblogic[k]=new TGButtonGroup(logframe, "TB Logic"); + logframe->AddFrame(m_tblogic[k], new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 0, 0)); + new TGRadioButton(m_tblogic[k], "OR", 0); + new TGRadioButton(m_tblogic[k], "AND", 1); + m_tblogic[k]->SetButton(0); + } + m_talogic[0]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTaLogic0(Int_t)"); + m_tablogic[0]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTabLogic0(Int_t)"); + m_tblogic[0]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTbLogic0(Int_t)"); + m_talogic[1]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTaLogic1(Int_t)"); + m_tablogic[1]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTabLogic1(Int_t)"); + m_tblogic[1]->Connect("Pressed(Int_t)", "CosmicGui", this, "setTbLogic1(Int_t)"); + TGHorizontalFrame *hbdel = new TGHorizontalFrame(hbframe); + hbframe->AddFrame(hbdel,new TGLayoutHints(kLHintsBottom ,15,2,2,2)); + TGLabel *hmdellabel=new TGLabel(hbdel,"D-:"); + hbdel->AddFrame(hmdellabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_hbdelaym=new TGNumberEntry(hbdel, 0, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 31); + hbdel->AddFrame(m_hbdelaym,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + m_hbdelay=new TGNumberEntry(hbdel, 0, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 31); + hbdel->AddFrame(m_hbdelay,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 0, 2, 2, 0)); + TGLabel *hdellabel=new TGLabel(hbdel,"D+:"); + hbdel->AddFrame(hdellabel,new TGLayoutHints(kLHintsRight|kLHintsCenterY, 2, 2, 2, 0)); + + + TGVerticalFrame *discframe= new TGVerticalFrame(datapanel2, 0, 0, kSunkenFrame); + datapanel2->AddFrame(discframe,new TGLayoutHints(kLHintsTop ,5,0,0,0)); + + TGLabel *scint=new TGLabel(discframe,"Scintillators"); + scint->SetTextFont(maskfont); + discframe->AddFrame(scint,new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,0,0,0,0)); + TGHorizontalFrame *trigmenu6 = new TGHorizontalFrame(discframe); + discframe->AddFrame(trigmenu6,new TGLayoutHints(kLHintsCenterY ,15,2,2,2)); + TGVerticalFrame *aframe= new TGVerticalFrame(trigmenu6); + trigmenu6->AddFrame(aframe, new TGLayoutHints(kLHintsTop,0,0,0,0)); + TGLabel *ahcl=new TGLabel(aframe,"Scint:"); + aframe->AddFrame(ahcl,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 0, 0, 0)); + m_NAND[0]=new TGCheckButton(aframe,"0"); + m_NAND[1]=new TGCheckButton(aframe,"1"); + m_NAND[2]=new TGCheckButton(aframe,"2"); + m_NAND[3]=new TGCheckButton(aframe,"3"); + for (int i=0;i<4;i++){ + aframe->AddFrame(m_NAND[i],new TGLayoutHints(kLHintsTop|kLHintsLeft ,2,0,0,0)); + } + TGVerticalFrame *alogframe= new TGVerticalFrame(trigmenu6); + trigmenu6->AddFrame(alogframe, new TGLayoutHints(kLHintsTop)); + TGLabel *bhcl = new TGLabel(alogframe,"Logic:"); + alogframe->AddFrame(bhcl, new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 0, 0, 0)); + m_NANDlogic[0]=new TGCheckButton(alogframe,"Anti"); + m_NANDlogic[1]=new TGCheckButton(alogframe,"Anti"); + m_NANDlogic[2]=new TGCheckButton(alogframe,"Anti"); + m_NANDlogic[3]=new TGCheckButton(alogframe,"Anti"); + for (int i=0;i<4;i++){ + alogframe->AddFrame(m_NANDlogic[i], new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 0,0)); + } + + TGHorizontalFrame *delayframe= new TGHorizontalFrame(discframe); + discframe->AddFrame(delayframe, new TGLayoutHints(kLHintsCenterY|kLHintsCenterX, 2, 2, 2, 2)); + TGVerticalFrame *delayframe1= new TGVerticalFrame(delayframe); + delayframe->AddFrame(delayframe1, new TGLayoutHints(kLHintsCenterY|kLHintsCenterX)); + TGVerticalFrame *delayframe2= new TGVerticalFrame(delayframe); + delayframe->AddFrame(delayframe2, new TGLayoutHints(kLHintsCenterY|kLHintsCenterX)); + + + TGLabel *delay0label=new TGLabel(delayframe1,"Sc0 Del:"); + delayframe1->AddFrame(delay0label,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 2, 2, 2, 0)); + m_delay0=new TGNumberEntry(delayframe1, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 63); + delayframe1->AddFrame(m_delay0,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 0, 0, 0, 0)); + + TGLabel *delay1label=new TGLabel(delayframe1,"Sc1 Del:"); + delayframe1->AddFrame(delay1label,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 2, 2, 2, 0)); + m_delay1=new TGNumberEntry(delayframe1, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 63); + delayframe1->AddFrame(m_delay1,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 0, 0, 0, 0)); + + + TGLabel *delay2label=new TGLabel(delayframe2,"Sc2 Del:"); + delayframe2->AddFrame(delay2label,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 2, 2, 2, 0)); + m_delay2=new TGNumberEntry(delayframe2, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 63); + delayframe2->AddFrame(m_delay2,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 0, 0, 0, 0)); + + TGLabel *delay3label=new TGLabel(delayframe2,"Sc3 Del:"); + delayframe2->AddFrame(delay3label,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 2, 2, 2, 0)); + m_delay3=new TGNumberEntry(delayframe2, 0, 2, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 63); + delayframe2->AddFrame(m_delay3,new TGLayoutHints(kLHintsLeft|kLHintsCenterY|kLHintsCenterX, 0, 0, 0, 0)); + + + TGVerticalFrame *quitmenu = new TGVerticalFrame(datapanel2, 0, 0); + datapanel2->AddFrame(quitmenu, new TGLayoutHints(kLHintsTop|kLHintsCenterX, 0, 0, 0, 0)); + + TGVerticalFrame *phasebusyframe=new TGVerticalFrame(quitmenu, 0, 0, kSunkenFrame); + quitmenu->AddFrame(phasebusyframe, new TGLayoutHints(kLHintsTop|kLHintsExpandX|kLHintsCenterX, 2, 2, 2, 2)); + TGLabel *phasebusylabel=new TGLabel(phasebusyframe,"Phase busy"); + phasebusylabel->SetTextFont(maskfont); + phasebusyframe->AddFrame(phasebusylabel, new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 0, 0, 0, 0)); + + m_phasebusyen=new TGCheckButton(phasebusyframe, "Enable"); + phasebusyframe->AddFrame(m_phasebusyen, new TGLayoutHints(kLHintsTop|kLHintsLeft, 2, 2, 2, 2)); + m_phasebusysel=new TGButtonGroup(phasebusyframe, 2, 2, 4, 0, "Active phase"); + phasebusyframe->AddFrame(m_phasebusysel, new TGLayoutHints(kLHintsTop|kLHintsLeft, 2, 0, 0, 0)); + new TGRadioButton(m_phasebusysel, "0->0", 0); + new TGRadioButton(m_phasebusysel, "0->1", 1); + new TGRadioButton(m_phasebusysel, "1->1", 3); + new TGRadioButton(m_phasebusysel, "1->0", 2); + m_phasebusysel->Connect("Pressed(Int_t)", "CosmicGui", this, "setTriggerActivePhase(Int_t)"); + m_phasebusysel->SetButton(0); + m_phasebusystate=0; + + TGHorizontalFrame *tempframe= new TGHorizontalFrame(quitmenu); + quitmenu->AddFrame(tempframe, new TGLayoutHints(kLHintsTop|kLHintsCenterX|kLHintsExpandX, 2, 2, 2, 2)); + TGVerticalFrame *tempframe1= new TGVerticalFrame(tempframe,0,0,kSunkenFrame); + tempframe->AddFrame(tempframe1, new TGLayoutHints(kLHintsTop|kLHintsCenterX|kLHintsExpandX)); + TGLabel *tempmenulabel=new TGLabel(tempframe1,"FE Temperatures:"); + tempmenulabel->SetTextFont(maskfont); + tempframe1->AddFrame(tempmenulabel,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 0, 0)); + m_tempenable=new TGCheckButton(tempframe1,"Read Temps"); + m_tempenable->Connect("Clicked()", "CosmicGui", this, "synchSave2()"); + tempframe1->AddFrame(m_tempenable,new TGLayoutHints(kLHintsTop | kLHintsLeft ,2,2,2,2)); + m_templog=new TGCheckButton(tempframe1,"Log Temps"); + m_templog->Connect("Clicked()", "CosmicGui", this, "synchSave1()"); + tempframe1->AddFrame(m_templog,new TGLayoutHints(kLHintsTop | kLHintsLeft ,2,2,2,5)); + TGLabel *tempfreqlabel=new TGLabel(tempframe1,"Frequency:"); + tempframe1->AddFrame(tempfreqlabel,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 0, 0)); + m_tempfreq=new TGComboBox(tempframe1,100); + tempframe1->AddFrame(m_tempfreq,new TGLayoutHints(kLHintsTop | kLHintsCenterX,2,2,2,2)); + m_tempfreq->AddEntry("0.1 Hz", 400000000); + m_tempfreq->AddEntry("0.2 Hz", 200000000); + m_tempfreq->AddEntry("0.5 Hz", 80000000); + m_tempfreq->AddEntry("1 Hz", 40000000); + m_tempfreq->Resize(100,20); + + m_quit=new TGTextButton(quitmenu,"Quit"); + m_quit->Connect("Clicked()", "CosmicGui", this,"quit()"); + m_quit->SetFont(labelfont); + m_quit->SetMargins(15,30,10,10); + quitmenu->AddFrame(m_quit,new TGLayoutHints(kLHintsCenterY | kLHintsCenterX ,2,2,15,5)); + + TGLabel *timelabel=new TGLabel(datapanel3,"Time:"); + datapanel3->AddFrame(timelabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_time=new TGLabel(datapanel3,"0 s "); + datapanel3->AddFrame(m_time,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 30, 0, 0)); + m_time->SetTextFont(labelfont); + + TGLabel *nevlabel=new TGLabel(datapanel3,"Events:"); + datapanel3->AddFrame(nevlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_nEvents=new TGLabel(datapanel3,"0 "); + datapanel3->AddFrame(m_nEvents,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_nEvents->SetTextFont(labelfont); + + TGLabel *ratelabel=new TGLabel(datapanel3,"Total Rate:"); + datapanel3->AddFrame(ratelabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_rate=new TGLabel(datapanel3,"0.00 Hz "); + datapanel3->AddFrame(m_rate,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_rate->SetTextFont(labelfont); + + TGLabel *iratelabel=new TGLabel(datapanel3,"Current Rate:"); + datapanel3->AddFrame(iratelabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_irate=new TGLabel(datapanel3,"0.00 Hz "); + datapanel3->AddFrame(m_irate,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_irate->SetTextFont(labelfont); + + TGLabel *ihitlabel=new TGLabel(datapanel3,"Hits per Event:"); + datapanel3->AddFrame(ihitlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_hpe=new TGLabel(datapanel3,"0.00 "); + datapanel3->AddFrame(m_hpe,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 10, 0)); + m_hpe->SetTextFont(labelfont); + + + + TGLabel *latencylabel=new TGLabel(datapanel44,"Latency:"); + datapanel44->AddFrame(latencylabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + latencylabel->SetTextFont(maskfont); + latencylabel=new TGLabel(datapanel44,"DUT"); + datapanel44->AddFrame(latencylabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_l1alatency=new TGNumberEntry(datapanel44, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 255); + datapanel44->AddFrame(m_l1alatency,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + latencylabel=new TGLabel(datapanel44,"Telescope"); + datapanel44->AddFrame(latencylabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_l1alatencytel=new TGNumberEntry(datapanel44, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 255); + datapanel44->AddFrame(m_l1alatencytel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + + TGLabel *ntrglabel=new TGLabel(datapanel44,"Consec. Trgs:"); + ntrglabel->SetTextFont(maskfont); + datapanel44->AddFrame(ntrglabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 20, 2, 2, 0)); + ntrglabel=new TGLabel(datapanel44,"DUT"); + datapanel44->AddFrame(ntrglabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_ntrg=new TGNumberEntry(datapanel44, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 16); + datapanel44->AddFrame(m_ntrg,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + ntrglabel=new TGLabel(datapanel44,"Telescope"); + datapanel44->AddFrame(ntrglabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_ntrgtel=new TGNumberEntry(datapanel44, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 1, 16); + datapanel44->AddFrame(m_ntrgtel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + + + TGLabel *delaylabel=new TGLabel(datapanel44,"Trg Delay:"); + delaylabel->SetTextFont(maskfont); + datapanel44->AddFrame(delaylabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 20, 2, 2, 0)); + m_trgdelay=new TGNumberEntry(datapanel44, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 255); + datapanel44->AddFrame(m_trgdelay,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + + TGLabel *deadtimelabel=new TGLabel(datapanel44,"Deadtime:"); + deadtimelabel->SetTextFont(maskfont); + datapanel44->AddFrame(deadtimelabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_deadtime=new TGNumberEntry(datapanel44, 0, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 65535); + datapanel44->AddFrame(m_deadtime,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 2, 0)); + + + TGPicturePool tgpool(0,0); + const TGPicture* pic=tgpool.GetPicture("atlas",const_cast<char**>(atlas_detector_small)); + TGIcon* tgi=new TGIcon(datapanel5 ,pic,300,196); + datapanel5->AddFrame(tgi,new TGLayoutHints(kLHintsCenterX|kLHintsCenterY, 0, 2, 10, 0)); + // m_controller.writeHWregister(4,1); + // sleep(1); + // unsigned counter4=m_controller.readHWregister(9); + // unsigned counter10=m_controller.readHWregister(10); + // unsigned l1counter=m_controller.readHWregister(11); + // unsigned counter4m=m_controller.readHWregister(12); + // unsigned counter10m=m_controller.readHWregister(13); + // unsigned counter10e=m_controller.readHWregister(14); + // unsigned tdccounter=m_controller.readHWregister(15); + // std::cout<<"Counter 4: "<<counter4<<" Counter 10: "<<counter10<<std::endl; + // std::cout<<"Counter 4m: "<<counter4m<<" Counter 10m: "<<counter10m<<std::endl; + // std::cout<<"Counter 10e: "<<counter10e<<" TDC counter: "<<(tdccounter&0xffff)<<std::endl; + // std::cout<<"l1counter: "<<l1counter<<std::endl; + + std::string rcfile=getenv("HOME"); + rcfile+="/.cosmicDaq.rc"; + + readConfig(rcfile.c_str()); + + m_scanLog=new ScanLog; + + SetWindowName("Cosmic Telescope DAQ"); + Resize(w,h); + Layout(); + MapSubwindows(); + MapWindow(); + if(autostart==true)m_start->Clicked(); + } +void CosmicGui::toggle(){ + setRun(!running()); +} +void CosmicGui::synchSave1(){ + if(m_templog->IsOn()==true && m_tempenable->IsOn()==false){ + m_tempenable->SetOn(true); + } +} +void CosmicGui::synchSave2(){ + if(m_templog->IsOn()==true && m_tempenable->IsOn()==false){ + m_templog->SetOn(false); + } +} + +void CosmicGui::setRun(Bool_t on){ + if (on){ + //unsigned statusd=m_controller.readHWregister(4); + //std::cout<<"Statusd before run "<<std::hex<<statusd<<std::dec<<std::endl; + /* + if(m_oldRunName==m_name->GetText()){ + time_t t=time(0); + struct tm* thetime; + thetime=localtime(&t); + char runnr[128]; + sprintf(runnr,"cosmic%04d%02d%02d%02d%02d%02d",thetime->tm_year+1900,thetime->tm_mon+1,thetime->tm_mday, + thetime->tm_hour, thetime->tm_min, thetime->tm_sec); + m_name->SetText(runnr); + m_oldRunName=runnr; + } + */ + int status=startRun(); + if(status==0){ + m_timers->Start(1000,kFALSE); // update every second + m_timerm->Start(5000,kFALSE); // update every 5 second + m_timerl->Start(60000,kFALSE); // update every minut} + m_starttime.Set(); + m_oneminago=m_starttime.AsDouble(); + m_nevtMin=0; + m_nevt=0; + enableControls(false); + m_start->SetDown(true); + m_isrunning=true; + m_start->SetText("Running"); + m_rate->SetText("Starting..."); + m_irate->SetText("Starting..."); + } + }else{ + stopRun(); + enableControls(true); + m_timers->Stop(); + m_timerm->Stop(); + m_timerl->Stop(); + m_start->SetText("Start Run"); + m_isrunning=false; + m_start->SetDown(false); + m_irate->SetText("0.00 Hz"); + m_nEvents->SetText(Form("%u", m_nevt)); + /* + m_nevt = m_controller.getNEventsProcessed(); + char labelstring[128]; + sprintf(labelstring,"%u",m_nevt); + m_nEvents->SetText(labelstring); + */ + } +} +//int counter=0; +void CosmicGui::timeouts(){ + // 1 s timeout, update number of events + m_nEvents->SetText(Form("%u", m_nevt)); + //std::cout<<"nevents = "<<m_nevt<<std::endl; + //counter++; + //std::cout<<counter<<" "<<m_nevt<<std::endl; + // unsigned status=m_controller.readHWregister(3); + // std::cout<<"Status "<<std::hex<<status<<std::dec<<std::endl; + // unsigned statusd=m_controller.readHWregister(4); + // std::cout<<"Statusd "<<std::hex<<statusd<<std::dec<<std::endl; + TTimeStamp currenttime; + currenttime.Set(); + int timediff=(int)(currenttime.AsDouble()-m_starttime.AsDouble()+.5); + m_time->SetText(Form("%d s", timediff)); + m_hpe->SetText(Form("%.3f",monitoringGui->getHitsPerEvent()) ); + if(m_maxtrue->IsDisabledAndSelected()){ + unsigned maxevents; + maxevents = m_maxevents->GetIntNumber(); + if(m_nevt>=maxevents){ + setRun(false); + setRun(true); + } + } + +} +void CosmicGui::timeoutm(){ + // 5 s timeout, update monitoring display + monitoringGui->updateDisplay(); +} + +void CosmicGui::timeoutl(){ + // 60 s timeout, update rates + TTimeStamp currenttime; + currenttime.Set(); + double timediff=currenttime.AsDouble()-m_starttime.AsDouble(); + assert(timediff>0); + double nevtmin=float(m_nevt-m_nevtMin); + double rate=double(m_nevt)/timediff; + double tmin=currenttime.AsDouble()-m_oneminago; + double ratemin=nevtmin/tmin; + m_oneminago=currenttime.AsDouble(); + m_nevtMin=m_nevt; + char labelstring[128]; + sprintf(labelstring,"%.2f Hz",rate); + m_rate->SetText(labelstring); + sprintf(labelstring,"%.2f Hz",ratemin); + m_irate->SetText(labelstring); +} + +int CosmicGui::openFile(PixScan *scan){ + struct stat stFileInfo; + int intStat; + intStat = stat(m_globalconf->getDataDir(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Data directory "<<m_globalconf->getDataDir()<<" does not exist"<<std::endl; + return 1; + } + char runnum[128]; + sprintf(runnum,"%06d",m_globalconf->getRunNumber()); + TString runname; + runname = (std::string("cosmic_")+runnum); + TString rcdir(TString("/")+runname); + rcdir=m_globalconf->getDataDir()+rcdir; + m_fullpath=std::string(rcdir.Data())+"/"+runname+".raw"; + m_rootfile=std::string(rcdir.Data())+"/"+runname+".root"; + m_tempfile=std::string(rcdir.Data())+"/"+"temperatures.txt"; + TString rcconfig(rcdir+"/globalconfig.txt"); + std::string topconfigname=m_globalconf->getConfigName()+".cfg"; + TString topconfig(rcdir+"/"+topconfigname); + TString scanconfig(rcdir+"/scanconfig_"+runname+".txt"); + // Attempt to get the file attributes + intStat = stat(rcdir.Data(),&stFileInfo); + if(intStat == 0) { //File exists + int retcode; + new TGMsgBox(gClient->GetRoot(), 0, "Attention", "Data file exists. Overwrite?", + kMBIconExclamation, kMBYes | kMBCancel,&retcode); + if(retcode==kMBYes){ + char command[512]; + sprintf(command, "rm -rf %s",rcdir.Data()); + system(command); + } else { + return 1; + } + } + if(not m_eudetfile->IsOn() && not m_rawfile->IsOn() && not m_writeRootFile->IsOn()){ + int retcode; + new TGMsgBox(gClient->GetRoot(), 0, "Attention", "No file format has been selected. Is this OK?", + kMBIconExclamation, kMBYes | kMBCancel,&retcode); + if(retcode==kMBYes){ + char command[512]; + sprintf(command, "rm -rf %s",rcdir.Data()); + system(command); + } + else { + return 1; + } + } + + // make new run directory + mkdir (rcdir.Data(),0777); + + // copy configuration + writeConfig(rcconfig.Data()); + + m_globalconf->copyConfig(topconfig.Data()); + std::ofstream sc(scanconfig.Data()); + ipc::ScanOptions options; + scan->convertScanConfig(options); + scan->setRunNumber(m_globalconf->getRunNumber()); + scan->dump(sc, options); + std::string oldcfg=std::string(rcdir.Data())+"/config"; + mkdir (oldcfg.c_str(),0777); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + m_config[i]->copyConfig(oldcfg.c_str()); + } + } + return 0; +} + +int CosmicGui::startRun(){ + char name[512]; + int newrunno=m_globalconf->incrementRunNumber(); + writeStdConfig(); // remember in case we crash + const std::string port = "33000"; + if (m_realTime == true) + { + std::stringstream ss("tcp://"); + ss<<getenv("ORBHOST"); + ss << ":" << port; + std::string address = ss.str(); + std::cout << "<CosmicGui::startRun> : Server address is: " << address << std::endl; + sprintf(name,"CosmicGui|%05d|%s",newrunno,address.c_str()); + } + //configure all valid modules + std::map<int,unsigned int> linkmap; + std::map<int,int> rcemap; + std::map<int, unsigned long long> multiplexer; + //bool valid=false; + //set up RCEs first + m_controller.removeAllRces(); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + m_controller.addRce(m_config[i]->getRce()); + rcemap[m_config[i]->getRce()]=1; + multiplexer[m_config[i]->getRce()]=0; + } + } + //now set up modules + + for(size_t i=0;i<m_moduleinfo.size();i++){ + delete m_moduleinfo[i]->getFormatter(); + delete m_moduleinfo[i]; + } + m_moduleinfo.clear(); + m_rce.clear(); + if(rcemap.size()==0){ + std::cout<<"No modules included. Adding RCE 0 in case you want to run without modules"<<std::endl; + m_controller.addRce(0); + m_rce.push_back(0); + rcemap[0]=1; + } + //Default Trigger IF + int retval=m_controller.setupTrigger(); + if(retval!=0){//Object not found, i.e. bad RCE specified. + new TGMsgBox(gClient->GetRoot(), 0, "Attention", + Form("RCE %d specified in config does not exist.", retval-1000), + kMBIconExclamation, kMBOk); + return 1; + } + int dutmult=m_ntrg->GetIntNumber(); + dutmult==0 ? dutmult=15 : dutmult=dutmult-1; + int telmult=m_ntrgtel->GetIntNumber(); + telmult==0 ? telmult=15 : telmult=telmult-1; + m_controller.removeAllModules(); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + //valid=true; + unsigned rce=m_config[i]->getRce(); + unsigned outlink=m_config[i]->getOutLink(); + assert(linkmap.find(outlink+1000*rce)==linkmap.end()); + linkmap[outlink+1000*rce]=1; + unsigned inlink=m_config[i]->getInLink(); + int id=m_config[i]->getId(); + const char* modname=m_config[i]->getName(); + //Multiplexer optimization parameters + if(std::string(modname).substr(0,9)=="Telescope"){ + multiplexer[rce]|=telmult<<(outlink*4); + }else{ + multiplexer[rce]|=dutmult<<(outlink*4); + } + if(m_config[i]->getType()=="FEI4A"){ + printf("FEI4A: addModule (%s, %d, %d, %d, %d)\n",modname, 0, inlink, outlink, rce); + m_controller.addModule(modname, "FEI4A",id, inlink, outlink, rce, "FEI4A"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 1, 336, 80, new FEI4AFormatter(id))); + m_rce.push_back(rce); + ipc::PixelFEI4AConfig *cfg=m_config[i]->getFEI4AConfig(); + m_controller.downloadModuleConfig(rce, id,*cfg); + // assert(m_controller.writeHWregister(15,0x80)==0); //setup mux + } else if(m_config[i]->getType()=="FEI4B"){ + ipc::PixelFEI4BConfig *cfg=m_config[i]->getFEI4BConfig(); + AbsFormatter* formatter=new FEI4BFormatter(id); + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + pt->put("HitDiscCnfg",cfg->FEGlobal.HitDiscCnfg); + formatter->configure(pt); + delete pt; + printf("FEI4B: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, rce); + m_controller.addModule(modname, "FEI4B",id, inlink, outlink, rce, "FEI4B"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 1, 336, 80, formatter)); + m_rce.push_back(rce); + m_controller.downloadModuleConfig(rce, id,*cfg); + } else if(m_config[i]->getType()=="FEI3"){ + printf("FEI3: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, rce); + m_controller.addModule(modname, "FEI3",id, inlink, outlink, rce, "JJ"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 16, 160, 18, new JJFormatter(id))); + m_rce.push_back(rce); + ipc::PixelModuleConfig *cfg=m_config[i]->getModuleConfig(); + m_controller.downloadModuleConfig(rce, id,*cfg); + } else if(m_config[i]->getType()=="Hitbus"){ + printf("Hitbus: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, rce); + m_controller.addModule(modname, "Hitbus",id, inlink, outlink, rce, ""); + ipc::HitbusModuleConfig *cfg=m_config[i]->getHitbusConfig(); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else if(m_config[i]->getType()=="HPTDC"){ + ipc::AFPHPTDCModuleConfig *cfg=m_config[i]->getHPTDCConfig(); + printf("AFP-HPTDC: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, rce); + AbsFormatter* formatter=new AFPHPTDCFormatter(id); + //this formatter needs to be configured. + boost::property_tree::ptree *pt=new boost::property_tree::ptree; + for(int l=0;l<2;l++){ + for(int j=0;j<12;j++){ + for(int k=0;k<1024;k++){ + char name[32]; + sprintf(name, "c_%d_%d_%d", l, j, k); + pt->put(name, cfg->calib[l][j][k]); + } + } + } + formatter->configure(pt); + delete pt; + m_controller.addModule(modname, "HPTDC",id, inlink, outlink, rce, ""); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 1, 12, 1, formatter)); + m_rce.push_back(rce); + m_controller.downloadModuleConfig(rce, id ,*cfg); + } else { + std::cout<<"Unknown config type"<<std::endl; + assert(0); + } + } + } + + unsigned goodHSIOconnection; + for (std::map <int, int>::const_iterator it = rcemap.begin(); it != rcemap.end(); ++it){ + int rce=it->first; + goodHSIOconnection=m_controller.writeHWregister(rce, 3,0); //Mode 0=normal 1=tdccalib 2=eudaq + assert(goodHSIOconnection==0); + // Reset delays + goodHSIOconnection=m_controller.writeHWregister(rce, 7,0); + assert(goodHSIOconnection==0); + //Delay 0 + for(int i=0;i<m_delay0->GetIntNumber();i++){ + goodHSIOconnection=m_controller.writeHWregister(rce, 5,1); + assert(goodHSIOconnection==0); + } + //Delay 1 + for(int i=0;i<m_delay1->GetIntNumber();i++){ + goodHSIOconnection=m_controller.writeHWregister(rce, 5,2); + assert(goodHSIOconnection==0); + } + //Delay 2 + for(int i=0;i<m_delay2->GetIntNumber();i++){ + goodHSIOconnection=m_controller.writeHWregister(rce, 5,4); + assert(goodHSIOconnection==0); + } + //Delay 3 + for(int i=0;i<m_delay3->GetIntNumber();i++){ + goodHSIOconnection=m_controller.writeHWregister(rce, 5,8); + assert(goodHSIOconnection==0); + } + //Hitbus delay + goodHSIOconnection=m_controller.writeHWregister(rce, 28,m_hbdelay->GetIntNumber()); + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 29,m_hbdelaym->GetIntNumber()); + assert(goodHSIOconnection==0); + //Multiplexer optimization + //goodHSIOconnection=m_controller.writeHWregister(rce, 22,multiplexer[rce]&0xffffffff); + //assert(goodHSIOconnection==0); + //goodHSIOconnection=m_controller.writeHWregister(rce, 23,multiplexer[rce]>>32); + //assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 23,0xf0000000); //TDC multiplicity 16 + assert(goodHSIOconnection==0); + + //Configure phase busy trigger + int phaseBusySel = 0; + phaseBusySel |= int(m_phasebusyen->IsOn()); + phaseBusySel |= m_phasebusystate<<1; + if (it == rcemap.begin()) { + std::cout << "PhaseBusy trigger " << ((phaseBusySel&1) ? "ON" : "OFF") << " (Mask: " << + bool(phaseBusySel&4) << bool(phaseBusySel&2) << ")" << std::endl; + } + goodHSIOconnection=m_controller.writeHWregister(rce, 34,phaseBusySel); // set busy 3 out of 4 phases + assert(goodHSIOconnection==0); + //goodHSIOconnection=m_controller.writeHWregister(rce, 33, 100); // buffer length records + //assert(goodHSIOconnection==0); + //Configure Temperature ADC readout + goodHSIOconnection=m_controller.writeHWregister(rce, 31,m_tempfreq->GetSelected()); + assert(goodHSIOconnection==0); + goodHSIOconnection=m_controller.writeHWregister(rce, 32,m_tempenable->IsOn()); + assert(goodHSIOconnection==0); + + //Disc Buttons + + unsigned N_ANDbtn=0; + for (int i=0;i<4;i++){ + if(m_NAND[i]->IsOn()){ + N_ANDbtn|=(1<<i); + } + if(m_NANDlogic[i]->IsOn()){ + N_ANDbtn|=(1<<(i+8)); + } + } + unsigned extlogic=0; + if(m_HSIO1->IsOn()&&!m_HSIO2->IsOn())extlogic=0; //for completeness + else if (!m_HSIO1->IsOn() && m_HSIO2->IsOn())extlogic=1; + else if (m_HSIO1->IsOn() && m_HSIO2->IsOn() && m_hsiostate==0)extlogic=2; + else if (m_HSIO1->IsOn() && m_HSIO2->IsOn() && m_hsiostate==1)extlogic=3; + N_ANDbtn|=extlogic<<14; + goodHSIOconnection=m_controller.writeHWregister(rce, 6, N_ANDbtn); + // Hitbus setup + goodHSIOconnection=m_controller.writeHWregister(rce, 30, m_hbstate); + m_controller.sendHWcommand(rce, 17); // Tell the HSIO that the RCE is present. + } + + for (int k=0;k<2;k++){ + if(rcemap.find(m_hbrce[k]->GetIntNumber())==rcemap.end())continue; + unsigned hitbusconfig=0; + for (int i=0;i<2;i++){ + for (int j=0;j<3;j++) + if(m_tp[k][i*3+j]->IsOn())hitbusconfig|=(1<<(i*4+j)); + } + if(m_tastate[k]==1)hitbusconfig|=(1<<3); + if(m_tbstate[k]==1)hitbusconfig|=(1<<7); + if(m_tabstate[k]==1)hitbusconfig|=(1<<8); + m_controller.writeHWregister(m_hbrce[k]->GetIntNumber(), 21,hitbusconfig); + } + + + PixScan scn(PixScan::COSMIC_DATA, PixLib::EnumFEflavour::PM_FE_I2); + ipc::ScanOptions options; + // Set calibration (i.e. output file) name + // Or the ip address of the linux host: tcp://xxx.xxx.xxx.xxx + + scn.setName(name); + // Override l1a latency + scn.setLVL1Latency(m_l1alatency->GetIntNumber()); + scn.setSecondaryLatency(m_l1alatencytel->GetIntNumber()); + // Set number of triggers per L1A + scn.setConsecutiveLvl1TrigA(0,m_ntrg->GetIntNumber()); + scn.setConsecutiveLvl1TrigA(1,m_ntrgtel->GetIntNumber()); + scn.setTriggerMask(m_scint->IsOn()|(m_cyclic->IsOn()<<1)|(m_eudet->IsOn()<<2)| + ((m_HSIO1->IsOn() || m_HSIO2->IsOn())<<3)|(m_hitbus->IsOn()<<4)); + //scn.setHitbusConfig(hitbusconfig); + scn.setEventInterval(m_cperiod->GetIntNumber()); + scn.setStrobeLVL1Delay(m_trgdelay->GetIntNumber()); + scn.setDeadtime(m_deadtime->GetIntNumber()); + scn.convertScanConfig(options); + + int of=openFile(&scn); + if(of!=0)return 1; + + monitoringGui->setup(true, m_writeRootFile->IsOn(), m_rootfile.c_str(), + m_templog->IsOn(), m_tempfile.c_str()); + + if (m_realTime == true) + { + // Set-up to receive the data properly + std::cout << "CosmicGui: starting CosmicDataReceiver at tcp://" << port << std::endl; + std::vector<ModuleInfo*> modinfo=getModuleInfo(); + std::vector<int> rcesAll=getRces(); + unsigned runNo=m_globalconf->getRunNumber(); + IPCController* controller=getController(); + m_dataReceiver = new CosmicDataReceiver(this, controller, modinfo, rcesAll, + runNo, "tcp://" + port, m_fullpath, m_eudetfile->IsOn(), m_rawfile->IsOn()); + } + + + m_controller.downloadScanConfig(options); + logScan(); + m_controller.startScan(); + + return 0; +} + +void CosmicGui::stopRun(){ + m_controller.stopWaitingForData(); + std::cout<<"called stopwaitingfordata"<<std::endl; + monitoringGui->saveHistos(m_globalconf->getRunNumber(), m_globalconf->getDataDir()); + finishLogFile(); + bool idle=false; + for(int i=0;i<50;i++){ + if(m_controller.getScanStatus()==0){ + std::cout<<"called getstatus"<<std::endl; + idle=true; + break; + } + usleep(100000); + } + assert(idle); + /* + std::cout<<"Verifying HW configuration"<<std::endl; + int retval=m_controller.verifyModuleConfigHW(); + if(retval&0x100)std::cout<<"No formatter defined. Skipping register readback."<<std::endl; + if(retval&0x1)std::cout<<"Global register readback failed for unknown reasons."<<std::endl; + if(retval&0x2)std::cout<<"Global register readback differs from original configuration."<<std::endl; + if(retval&0x4)std::cout<<"Pixel register read back wrong number of words."<<std::endl; + if(retval&0x8)std::cout<<"Pixel register readback differs from original configuration."<<std::endl; + if(retval==0)std::cout<<"Register verification successful."<<std::endl; + */ + m_controller.resetFE(); //also sweeps events stuck in the buffer + m_controller.removeAllModules(); + //unsigned goodHSIOconnection=m_controller.writeHWregister(3,0); //Normal operating mode + //assert(goodHSIOconnection==0); + //goodHSIOconnection=m_controller.writeHWregister(0,0); //Inhibit all channels + //assert(goodHSIOconnection==0); + // unsigned l1counter=m_controller.readHWregister(11); + // unsigned counter4=m_controller.readHWregister(9); + // unsigned counter4m=m_controller.readHWregister(12); + // unsigned counter10m=m_controller.readHWregister(13); + // unsigned counter10=m_controller.readHWregister(10); + // unsigned counter10e=m_controller.readHWregister(14); + // unsigned tdccounter=m_controller.readHWregister(15); + // std::cout<<"Counter 4: "<<counter4<<" Counter 10: "<<counter10<<std::endl; + // std::cout<<"Counter 4m: "<<counter4m<<" Counter 10m: "<<counter10m<<std::endl; + // std::cout<<"Counter 10e: "<<counter10e<<" TDC counter: "<<(tdccounter&0xffff)<<std::endl; + // std::cout<<"l1counter: "<<l1counter<<std::endl; + + if (m_dataReceiver) delete m_dataReceiver; + m_dataReceiver = 0; + if(m_writeRootFile->IsDisabledAndSelected())monitoringGui->closeRootFile(); + if(m_templog->IsDisabledAndSelected())monitoringGui->closeTempFile(); + + return; +} + +void CosmicGui::verifyConfiguration(){ + std::cout<<"Verifying HW configuration"<<std::endl; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(m_config[i]->isIncluded()){ + unsigned rce=m_config[i]->getRce(); + unsigned id=m_config[i]->getId(); + std::cout<<"Frontend "<<id<<" on RCE "<<rce<<" Outlink "<<m_config[i]->getOutLink()<<":"<<std::endl; + int retval=m_controller.verifyModuleConfigHW(rce, id); + if(retval&ModuleVerify::NO_FORMATTER)std::cout<<"No formatter defined. Skipping register readback."<<std::endl; + if(retval&ModuleVerify::GLOBAL_READBACK_FAILED)std::cout<<"Global register readback failed for unknown reasons."<<std::endl; + if(retval&ModuleVerify::GLOBAL_READBACK_DIFFERENT)std::cout<<"Global register readback differs from original configuration."<<std::endl; + if(retval&ModuleVerify::PIXEL_WRONG_N_WORDS)std::cout<<"Pixel register read back wrong number of words."<<std::endl; + if(retval&ModuleVerify::PIXEL_READBACK_DIFFERENT)std::cout<<"Pixel register readback differs from original configuration."<<std::endl; + if(retval==ModuleVerify::OK)std::cout<<"Register verification successful."<<std::endl; + } + } +} +void CosmicGui::enableControls(bool on){ + m_tempenable->SetEnabled(on); + m_templog->SetEnabled(on); + m_tempfreq->SetEnabled(on); + m_quit->SetEnabled(on); + m_delay0->SetState(on); + m_delay1->SetState(on); + m_delay2->SetState(on); + m_delay3->SetState(on); + m_maxevents->SetState(on); + m_l1alatency->SetState(on); + m_l1alatencytel->SetState(on); + m_ntrg->SetState(on); + m_ntrgtel->SetState(on); + m_trgdelay->SetState(on); + m_deadtime->SetState(on); + m_hbdelay->SetState(on); + m_hbdelaym->SetState(on); + m_cperiod->SetState(on); + m_scint->SetEnabled(on); + m_eudet->SetEnabled(on); + m_cyclic->SetEnabled(on); + m_HSIO1->SetEnabled(on); + m_HSIO2->SetEnabled(on); + m_hsiologic->SetState(on); + m_hitbus->SetEnabled(on); + m_hbinput->SetState(on); + m_eudetfile->SetEnabled(on); + m_rawfile->SetEnabled(on); + m_writeRootFile->SetEnabled(on); + m_maxtrue->SetEnabled(on); + for (int k=0;k<2;k++){ + for (int i=0;i<6;i++) + m_tp[k][i]->SetEnabled(on); + m_talogic[k]->SetState(on); + m_tblogic[k]->SetState(on); + m_tablogic[k]->SetState(on); + m_hbrce[k]->SetState(on); + } + for (int i=0;i<4;i++){ + m_NAND[i]->SetEnabled(on); + m_NANDlogic[i]->SetEnabled(on); + } + for(int i=0;i<ConfigGui::MAX_MODULES;i++) + m_config[i]->enableControls(on); + m_globalconf->enableControls(on); + m_phasebusysel->SetState(on); + m_phasebusyen->SetEnabled(on); +} + +void CosmicGui::writeConfig(const char* filename){ + std::cout<<"Writing config to "<<filename<<std::endl; + std::ofstream ofile(filename); + + ofile<<m_trgdelay->GetIntNumber()<<std::endl; + ofile<<m_deadtime->GetIntNumber()<<std::endl; + ofile<<m_hbdelay->GetIntNumber()<<std::endl; + ofile<<m_hbdelaym->GetIntNumber()<<std::endl; + ofile<<m_l1alatency->GetIntNumber()<<std::endl; + ofile<<m_l1alatencytel->GetIntNumber()<<std::endl; + ofile<<m_ntrg->GetIntNumber()<<std::endl; + ofile<<m_ntrgtel->GetIntNumber()<<std::endl; + ofile<<m_delay0->GetIntNumber()<<std::endl; + ofile<<m_delay1->GetIntNumber()<<std::endl;; + ofile<<m_delay2->GetIntNumber()<<std::endl; + ofile<<m_delay3->GetIntNumber()<<std::endl; + ofile<<m_maxevents->GetIntNumber()<<std::endl; + ofile<<m_scint->IsOn()<<std::endl; + ofile<<m_cyclic->IsOn()<<std::endl; + ofile<<m_eudet->IsOn()<<std::endl; + ofile<<m_HSIO1->IsOn()<<std::endl; + ofile<<m_HSIO2->IsOn()<<std::endl; + ofile<<m_hsiostate<<std::endl; + ofile<<m_hitbus->IsOn()<<std::endl; + ofile<<m_hbstate<<std::endl; + ofile<<m_cperiod->GetIntNumber()<<std::endl; + ofile<<m_maxtrue->IsOn()<<std::endl; + for (int k=0;k<2;k++){ + for (int i=0;i<6;i++) + ofile<<m_tp[k][i]->IsOn()<<std::endl; + ofile<<m_tastate[k]<<std::endl; + ofile<<m_tbstate[k]<<std::endl; + ofile<<m_tabstate[k]<<std::endl; + ofile<<m_hbrce[k]->GetIntNumber()<<std::endl; + } + for (int i=0;i<4;i++){ + ofile<<m_NAND[i]->IsOn()<<std::endl; + } + for (int i=0;i<4;i++){ + ofile<<m_NANDlogic[i]->IsOn()<<std::endl; + } + ofile<<m_eudetfile->IsOn()<<std::endl; + ofile<<m_rawfile->IsOn()<<std::endl; + ofile<<m_writeRootFile->IsOn()<<std::endl; + ofile<<m_tempenable->IsOn()<<std::endl; + ofile<<m_templog->IsOn()<<std::endl; + ofile<<m_tempfreq->GetSelected()<<std::endl; + ofile<<m_phasebusyen->IsOn()<<std::endl; + ofile<<m_phasebusystate<<std::endl; + m_globalconf->writeGuiConfig(ofile); +} + +void CosmicGui::readConfig(const char* filename){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(filename,&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<std::endl<<"No config file "<<filename<<" found."<<std::endl; + return; + } + std::ifstream ifile(filename); + int td, dt, hb, lat, nt, del0, del1, del2, del3, maxevnt, maxt, trg, trgper, fi, pbusy; + ifile>>td; + m_trgdelay->SetIntNumber(td); + ifile>>dt; + m_deadtime->SetIntNumber(dt); + ifile>>hb; + m_hbdelay->SetIntNumber(hb); + ifile>>hb; + m_hbdelaym->SetIntNumber(hb); + ifile>>lat; + m_l1alatency->SetIntNumber(lat); + ifile>>lat; + m_l1alatencytel->SetIntNumber(lat); + ifile>>nt; + m_ntrg->SetIntNumber(nt); + ifile>>nt; + m_ntrgtel->SetIntNumber(nt); + ifile>>del0; + m_delay0->SetIntNumber(del0); + ifile>>del1; + m_delay1->SetIntNumber(del1); + ifile>>del2; + m_delay2->SetIntNumber(del2); + ifile>>del3; + m_delay3->SetIntNumber(del3); + ifile>>maxevnt; + m_maxevents->SetIntNumber(maxevnt); + ifile>>trg; + m_scint->SetOn(trg); + ifile>>trg; + m_cyclic->SetOn(trg); + ifile>>trg; + m_eudet->SetOn(trg); + ifile>>trg; + m_HSIO1->SetOn(trg); + ifile>>trg; + m_HSIO2->SetOn(trg); + ifile>>trg; + m_hsiostate=trg; + m_hsiologic->SetButton(trg); + ifile>>trg; + m_hitbus->SetOn(trg); + ifile>>trg; + m_hbstate=trg; + m_hbinput->SetButton(trg); + ifile>>trg; + m_cperiod->SetIntNumber(trg); + ifile>>maxt; + m_maxtrue->SetOn(maxt); + for (int k=0;k<2;k++){ + for (int i=0;i<6;i++){ + ifile>>trgper; + m_tp[k][i]->SetOn(trgper); + } + ifile>>trgper; + m_tastate[k]=trgper; + m_talogic[k]->SetButton(trgper); + ifile>>trgper; + m_tbstate[k]=trgper; + m_tblogic[k]->SetButton(trgper); + ifile>>trgper; + m_tabstate[k]=trgper; + m_tablogic[k]->SetButton(trgper); + ifile>>trgper; + m_hbrce[k]->SetIntNumber(trgper); + } + for (int i=0;i<4;i++){ + ifile>>trgper; + m_NAND[i]->SetOn(trgper); + } + for (int i=0;i<4;i++){ + ifile>>trgper; + m_NANDlogic[i]->SetOn(trgper); + } + ifile>>fi; + m_eudetfile->SetOn(fi); + ifile>>fi; + m_rawfile->SetOn(fi); + ifile>>fi; + m_writeRootFile->SetOn(fi); + ifile>>fi; + m_tempenable->SetOn(fi); + ifile>>fi; + m_templog->SetOn(fi); + ifile>>fi; + m_tempfreq->Select(fi,0); + ifile>>pbusy; + m_phasebusyen->SetOn(pbusy); + ifile>>pbusy; + m_phasebusystate=pbusy; + m_phasebusysel->SetButton(pbusy); + m_globalconf->readGuiConfig(ifile); +} + +void CosmicGui::quit(){ + writeStdConfig(); + gApplication->Terminate(0); +} + +void CosmicGui::writeStdConfig(){ + std::string rcfile=getenv("HOME"); + rcfile+="/.cosmicDaq.rc"; + writeConfig(rcfile.c_str()); +} + +void CosmicGui::handleFileMenu(int item){ + TGFileInfo fileinfo; + const char* types[]={"Teststand config", "*.tcf", "All files", "*", 0,0}; + fileinfo.fFileTypes=types; + if(item==QUIT)quit(); + else if(item==LOAD){ + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + readConfig(fileinfo.fFilename); + } + else if(item==SAVE){ + new TGFileDialog(gClient->GetRoot(), 0, kFDSave, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + writeConfig(fileinfo.fFilename); + } +} + +void CosmicGui::logScan(){ + LogData logdata; + m_scanLog->setAuthor("cosmicGui"); + m_scanLog->setScanName("CosmicData"); + m_scanLog->setRunNumber(m_globalconf->getRunNumber()); + m_scanLog->setDebugging(false); + //logdata.comment=m_comment->GetText(); + logdata.exported=false; + logdata.saved=true; + logdata.datapath=m_globalconf->getDataDir(); + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + std::ostringstream ss; + if(m_config[i]->isIncluded()){ + ss<<"Module: "<<m_config[i]->getModuleId()<<" FE: "<< m_config[i]->getId()<<" Cfg: "<< m_config[i]->getFilename(); + logdata.configs.push_back(ss.str()); + } + } + m_scanLog->logScan(logdata); +} +void CosmicGui::finishLogFile(){ + std::string runstatus="OK"; + std::string lstatus="Done"; + m_scanLog->finishLogFile(runstatus, lstatus); +} + +void CosmicGui::switchOn(int panel, bool on){ + int modperpanel=ConfigGui::MAX_MODULES/4; + for (int i=panel*modperpanel;i<(panel+1)*modperpanel;i++){ + m_config[i]->setIncluded(on); + } +} + + + +//==================================================================== +int main(int argc, char **argv){ + // + // Initialize command line parameters with default values + // + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdArgBool start('s', "start", "Start run when GUI comes up."); + CmdLine cmd(*argv, &partition_name, &start, NULL); + CmdArgvIter arg_iter(--argc, ++argv); +// +// Parse arguments +// + cmd.parse(arg_iter); + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(! partition_name.isNULL()) p_name= (const char*)partition_name; + try{ + IPCPartition p(p_name ); + IPCController controller(p); + new IPCHistoManager(p,"RceIsServer", "dummy"); + + gROOT->SetStyle("Plain"); + TApplication theapp("app",&argc,argv); + new CosmicGui(controller, start, gClient->GetRoot(),800, 735); + theapp.Run(); + return 0; + }catch(...){ + std::cout<<"Partition "<<p_name<<" does not exist."<<std::endl; + exit(0); + } +} + + diff --git a/rce/rcecalib/server/CosmicGui.hh b/rce/rcecalib/server/CosmicGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..d3287539a3d5f48431115d8c3a91e12156f6129b --- /dev/null +++ b/rce/rcecalib/server/CosmicGui.hh @@ -0,0 +1,108 @@ +#ifndef COSMICGUI_HH +#define COSMICGUI_HH + +#include "TGMdiMainFrame.h" +#include <TTimer.h> +#include <TTimeStamp.h> +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include <TGButtonGroup.h> +#include <TGComboBox.h> +#include "ConfigGui.hh" +#include <string> + +class GlobalConfigGui; +class IPCController; +class CosmicDataReceiver; +class CosmicMonitoringGuiEmbedded; +class ModuleInfo; +class ScanLog; +namespace RCE{ + class PixScan; +} + +class CosmicGui: public TGMainFrame { + friend class CosmicDataReceiver; +public: + enum Filemenu {LOAD, SAVE, QUIT, HISTOS, SCREENSHOT}; + CosmicGui(IPCController &c, bool autostart, const TGWindow *p,UInt_t w,UInt_t h); + virtual ~CosmicGui(); + void toggle(); + void synchSave1(); + void synchSave2(); + void timeouts(); + void timeoutm(); + void timeoutl(); + int startRun(); + void stopRun(); + void verifyConfiguration(); + void enableControls(bool on); + void quit(); + void writeStdConfig(); + void handleFileMenu(Int_t); + void readConfig(const char* filename); + void writeConfig(const char* filename); + void incrementNevents(){m_nevt++;} + std::vector<ModuleInfo*>& getModuleInfo(){return m_moduleinfo;} + std::vector<int>& getRces(){return m_rce;} + int getL1AperTrig(){return m_ntrg->GetIntNumber();} + int getRunNumber(){return m_runno->GetIntNumber();} + IPCController* getController(){return &m_controller;} + void allOffA(){switchOn(0,0);} + void allOffC(){switchOn(1,0);} + void allOffA2(){switchOn(2,0);} + void allOffC2(){switchOn(3,0);} + void allOnA(){switchOn(0,1);} + void allOnC(){switchOn(1,1);} + void allOnA2(){switchOn(2,1);} + void allOnC2(){switchOn(3,1);} + void switchOn(int panel, bool on); + void setTaLogic0(Int_t i){m_tastate[0]=i;} + void setTaLogic1(Int_t i){m_tastate[1]=i;} + void setTbLogic0(Int_t i){m_tbstate[0]=i;} + void setTbLogic1(Int_t i){m_tbstate[1]=i;} + void setTabLogic0(Int_t i){m_tabstate[0]=i;} + void setTabLogic1(Int_t i){m_tabstate[1]=i;} + void setHbLogic(Int_t i){m_hbstate=i;} + void setHsioLogic(Int_t i){m_hsiostate=i;} + void setTriggerActivePhase(Int_t i){m_phasebusystate=i;} + +private: + void setRun(Bool_t on); + bool running(){return m_isrunning;} + int maxRunNum(); + void logScan(); + void finishLogFile(); + int openFile(RCE::PixScan*); + + IPCController& m_controller; + ConfigGui* m_config[ConfigGui::MAX_MODULES]; + TGTextButton* m_start, *m_quit; + TGLabel *m_nEvents, *m_time, *m_rate, *m_irate, *m_hpe; + TGNumberEntry *m_delay0, *m_delay1, *m_delay2, *m_delay3, *m_l1alatency, *m_l1alatencytel, *m_trgdelay, *m_ntrg, *m_ntrgtel, *m_runno, *m_deadtime, *m_cperiod, *m_hbdelay, *m_hbdelaym, *m_maxevents; + TGNumberEntry *m_hbrce[2]; + TGCheckButton *m_scint, *m_cyclic, *m_eudet, *m_HSIO1, *m_HSIO2, *m_hitbus, *m_NAND[4], *m_NANDlogic[4], *m_eudetfile, *m_rawfile, *m_writeRootFile, *m_maxtrue, *m_tempenable, *m_templog; + TGCheckButton *m_tp[2][6], *m_phasebusyen; + TGButtonGroup *m_talogic[2], *m_tblogic[2], *m_tablogic[2], *m_hbinput, *m_hsiologic, *m_phasebusysel; + TGComboBox *m_tempfreq; + int m_tastate[2], m_tbstate[2], m_tabstate[2], m_hbstate, m_hsiostate, m_phasebusystate; + bool m_isrunning; + bool m_realTime; + TTimer *m_timers, *m_timerm, *m_timerl; + TTimeStamp m_starttime; + unsigned m_nevt; + unsigned m_nevtMin; + double m_oneminago; + std::string m_oldRunName; + CosmicDataReceiver * m_dataReceiver; + CosmicMonitoringGuiEmbedded* monitoringGui; + std::vector<ModuleInfo*> m_moduleinfo; + std::vector<int> m_rce; + std::string m_fullpath, m_rootfile, m_tempfile; + ScanLog *m_scanLog; + GlobalConfigGui* m_globalconf; + +ClassDef (CosmicGui,0) +}; +#endif diff --git a/rce/rcecalib/server/CosmicMonitoringGui.cc b/rce/rcecalib/server/CosmicMonitoringGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..1ef0ccc51682a5ec87bd5bc824df778c66b5f7ce --- /dev/null +++ b/rce/rcecalib/server/CosmicMonitoringGui.cc @@ -0,0 +1,97 @@ +#include "rcecalib/server/CosmicMonitoringGui.hh" +#include "rcecalib/server/CosmicMonitoringGuiEmbedded.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TH1.h" +#include "TGIcon.h" +#include "TGMenu.h" +#include "TCanvas.h" +#include "TGCanvas.h" +#include "TGListTree.h" +#include "TRootEmbeddedCanvas.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TStyle.h> +#include <assert.h> +#include <iostream> +#include <time.h> +#include <sys/stat.h> +#include <fstream> +#include <list> +#include <pthread.h> +#include <vector> +#include "eudaq/Event.hh" +#include "config/FormattedRecord.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/FileSerializer.hh" +#include "eudaq/counted_ptr.hh" + + + + +CosmicMonitoringGui::~CosmicMonitoringGui(){ +} + +CosmicMonitoringGui::CosmicMonitoringGui(const char* filename, int nevt, const TGWindow *p,UInt_t w,UInt_t h) + : TGMainFrame(p,w,h) { + + // connect x icon on window manager + Connect("CloseWindow()","CosmicMonitoringGui",this,"quit()"); + + TGMenuBar *menubar=new TGMenuBar(this,1,1,kHorizontalFrame | kRaisedFrame); + TGLayoutHints *menubarlayout=new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + // menu "File" + TGPopupMenu* filepopup=new TGPopupMenu(gClient->GetRoot()); + //filepopup->AddEntry("&Load Config",LOAD); + //filepopup->AddEntry("&Save Config",SAVE); + filepopup->AddSeparator(); + filepopup->AddEntry("&Quit",QUIT); + menubar->AddPopup("&File",filepopup,menubarlayout); + + AddFrame(menubar, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 0,0,0,2)); + + filepopup->Connect("Activated(Int_t)","CosmicMonitoringGui",this,"handleFileMenu(Int_t)"); + + embededGui = new CosmicMonitoringGuiEmbedded(filename, nevt, this,1,1,kChildFrame); + AddFrame(embededGui,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY)); + + SetWindowName("Monitoring GUI"); + Resize(w,h); + Layout(); + MapSubwindows(); + MapWindow(); +} +void CosmicMonitoringGui::quit(){ + gApplication->Terminate(0); +} + + +void CosmicMonitoringGui::handleFileMenu(int item){ + if(item==QUIT)quit(); +} + +//==================================================================== +int main(int argc, char **argv){ + // + // Initialize command line parameters with default values +// +// Declare command object and its argument-iterator +// +// + + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + const char *filename=argv[1]; + std::cout<<"Filename "<<filename<<std::endl; + int nevt=10000000; + if(argc==3)nevt=atoi(argv[2]); + std::cout<<"Nevt "<<nevt<<std::endl; + TApplication theapp("app",&argc,argv); + new CosmicMonitoringGui(filename, nevt, gClient->GetRoot(),800,600); + theapp.Run(); + return 0; +} + + diff --git a/rce/rcecalib/server/CosmicMonitoringGui.hh b/rce/rcecalib/server/CosmicMonitoringGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..65f8fcc1ac93b591a98c63e1346fe5ff8e6bdd6d --- /dev/null +++ b/rce/rcecalib/server/CosmicMonitoringGui.hh @@ -0,0 +1,28 @@ +#ifndef COSMICMONITORINGGUI_HH +#define COSMICMONITORINGGUI_HH + +#include "TGMdiMainFrame.h" +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include "TFile.h" +#include "TH2F.h" +#include <string> + + +class CosmicMonitoringGuiEmbedded; + +class CosmicMonitoringGui: public TGMainFrame { +public: + CosmicMonitoringGui(const char* filename, int nevt, const TGWindow *p,UInt_t w,UInt_t h); + virtual ~CosmicMonitoringGui(); + void handleFileMenu(Int_t); + void quit(); +private: + + CosmicMonitoringGuiEmbedded* embededGui; + enum Filemenu {LOAD, SAVE, QUIT}; + +ClassDef (CosmicMonitoringGui,0) +}; +#endif diff --git a/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.cc b/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.cc new file mode 100644 index 0000000000000000000000000000000000000000..8baee90c83d53fa0fa3f06b22986f09b5119e723 --- /dev/null +++ b/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.cc @@ -0,0 +1,1297 @@ +#include "rcecalib/server/CosmicMonitoringGuiEmbedded.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "TApplication.h" +#include "TGMsgBox.h" +#include "TH1.h" +#include "TGIcon.h" +#include "TGMenu.h" +#include "TCanvas.h" +#include "TGCanvas.h" +#include "TGListTree.h" +#include "TRootEmbeddedCanvas.h" +#include <TGFileDialog.h> +#include <TROOT.h> +#include <TStyle.h> +#include <assert.h> +#include <math.h> +#include <iostream> +#include <time.h> +#include <sys/stat.h> +#include <time.h> +#include <fstream> +#include <list> +#include <pthread.h> +#include <vector> +#include "eudaq/Event.hh" +#include "config/FormattedRecord.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/FileSerializer.hh" +#include "eudaq/counted_ptr.hh" + +int hitbusEdge(unsigned word, int j){ + for (int i=9;i>=0;i--){ + if((word&(1<<((2-j)+3*i)))!=0){ + return 9-i; + } + } + return -1; +} + +CosmicMonitoringGuiEmbedded::~CosmicMonitoringGuiEmbedded(){ + Cleanup(); + for(int i=0;i<MAX_RCE_NUM;i++)delete [] m_linkToIndex[i]; + delete [] m_linkToIndex; +} + +void CosmicMonitoringGuiEmbedded::init(){ + TGVerticalFrame* datapanel=new TGVerticalFrame(this,1,1, kSunkenFrame); + // scan panel + TGHorizontalFrame *datapanel5 = new TGHorizontalFrame(datapanel, 2, 2, kSunkenFrame); + datapanel->AddFrame(datapanel5,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + AddFrame(datapanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + TGVerticalFrame *treepanel = new TGVerticalFrame(datapanel5, 150, 2, kSunkenFrame); + datapanel5->AddFrame(treepanel,new TGLayoutHints(kLHintsExpandY)); + TGVerticalFrame *plotpanel = new TGVerticalFrame(datapanel5, 2, 2, kSunkenFrame); + datapanel5->AddFrame(plotpanel,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY)); + + m_tgc=new TGCanvas(treepanel, 300,100); + //TGViewPort* vp=tgc->GetViewPort(); + m_tree=new TGListTree(m_tgc, kHorizontalFrame); + m_tree->Connect("Clicked(TGListTreeItem*, Int_t)","CosmicMonitoringGuiEmbedded", this, "displayHisto(TGListTreeItem*, Int_t)"); + //tree->AddItem(0,"/"); + treepanel->AddFrame(m_tgc,new TGLayoutHints(kLHintsExpandY)); + m_canvas=new TRootEmbeddedCanvas("Canvas",plotpanel,100,100); + m_canvas->GetCanvas()->GetPad(0)->SetRightMargin(0.15); + m_www=0; m_hhh=0; + gStyle->SetPalette(1); + gStyle->SetOptStat(10); + plotpanel->AddFrame(m_canvas,new TGLayoutHints(kLHintsExpandY|kLHintsExpandX)); + m_linkToIndex=new int*[MAX_RCE_NUM]; + for(int i=0;i<MAX_RCE_NUM;i++)m_linkToIndex[i]=0; + +} + + +void CosmicMonitoringGuiEmbedded::setup(bool online, bool writeRootFile, const char* rootfile, + bool writeTemps, const char* tempfile){ + + std::cout<<"Setting up monitoring histograms"<<std::endl; + m_writeRootFile=writeRootFile; + m_logtemps=writeTemps; + if(m_nMods>0){ + delete [] m_nhits; + for (int i=0;i<m_nMods;i++){ + delete [] m_pixx[i]; + delete [] m_pixy[i]; + delete [] m_value[i]; + delete [] m_timing[i]; + delete [] m_hitincluster[i]; + delete [] m_posx[i]; + delete [] m_posy[i]; + delete [] m_posz[i]; + } + delete [] m_pixx; + delete [] m_pixy; + delete [] m_value; + delete [] m_timing; + delete [] m_hitincluster; + delete [] m_posx; + delete [] m_posy; + delete [] m_posz; + } + m_starttime_sec=(unsigned)time(0); + m_lasttime_sec= -1; + m_nMods = 0; + m_nRces = 0; + m_triggerPhase=-1; + m_linkmap.clear(); + for(int i=0;i<MAX_RCE_NUM;i++){ + delete [] m_linkToIndex[i]; + m_linkToIndex[i]=0; + } + m_outlinks.clear(); + m_rceNums.clear(); + m_rces.clear(); + m_fetype.clear(); + m_timeStampLimit=5.0; + m_nev=0; + m_hitsperevent=0; + m_nScreenshots=0; + m_histo=0; + m_graph=0; + for (int i=0;i<MAX_RCES;i++){ + m_tdc[i]=0; + for(int k=0;k<2;k++)for(int l=0;l<3;l++)m_hitbus[i][k][l]=0; + } + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(i!=ConfigGui::MAX_MODULES-1){ + m_corxx[i]=0; + m_corxy[i]=0; + m_coryy[i]=0; + m_coryx[i]=0; + } + m_tempsec[i]=0; + m_tempmin[i]=0; + m_occ[i]=0; + m_toth[i]=0; + m_bx[i]=0; + m_afptdc[i]=0; + m_timestamp[i]=0; + m_projx[i]=0; + m_projy[i]=0; + m_corrindex[i]=-1; + } + + if(online){ + + for (unsigned int i=0; i<m_config.size(); i++){ + if(m_config[i]->isIncluded()){ + //valid=true; + m_lastcount[i]=0; + unsigned outlink=m_config[i]->getOutLink(); + unsigned rceNum=m_config[i]->getRce(); + addRce(rceNum); + + std::cout<<"\tModule "<<i<<": outlink "<<outlink<<" , RCE "<<rceNum<<std::endl; + createLink(outlink,rceNum); //this increments m_nMods + + if(m_config[i]->getType()=="FEI4A" || m_config[i]->getType()=="FEI4B"){ + m_fetype.push_back(4); + }else if(m_config[i]->getType()=="FEI3"){ + m_fetype.push_back(3); + }else if(m_config[i]->getType()=="Hitbus"){ + m_fetype.push_back(9); + }else if(m_config[i]->getType()=="HPTDC"){ + m_fetype.push_back(11); + } + else { + std::cout<<"Unknown FE type"<<std::endl; + assert(0); + } + } + } + + } + else{ //offline/standalone executable + + std::string chanDefName = "cosmicChannelDefs.txt"; + std::ifstream cha(chanDefName.data()); + if (!cha.is_open()){ + + std::cout << "Cannot find "<<chanDefName<<std::endl; + bool success = setupChannelsFromFile(m_filename); + + if(!success){ + std::cout<<"Couldn't read "<<m_filename<<" ; instead setting default values for channels"<<std::endl; + + createLink(11,0); + createLink(12,0); + createLink(13,0); + createLink(14,0); + createLink(0,0); + + m_fetype.push_back(3); + m_fetype.push_back(3); + m_fetype.push_back(3); + m_fetype.push_back(3); + m_fetype.push_back(4); + + addRce(0); + } + + } + else{ + + //Read in channel definitions from text file (for standalone cosmicMonitoringGui only) + std::cout<<"Reading in channel definitions from "<<chanDefName<<std::endl; + int upl, rce, fet; + while(!cha.eof()){ + cha>>upl>>rce>>fet; + + createLink(upl,rce); + addRce(rce); + m_fetype.push_back(fet); + + std::cout<<"Module "<<(m_nMods-1)<<" : uplink "<<upl<<" ; RCE "<<rce<<" ; FEI"<<fet<<std::endl; + + } + + } + + } //end if(!online) + + // These are needed even when no root file is written. + m_nhits=new Int_t[m_nMods]; + m_pixx=new Int_t*[m_nMods]; + m_pixy=new Int_t*[m_nMods]; + m_value=new Int_t*[m_nMods]; + m_timing=new Int_t*[m_nMods]; + m_hitincluster=new Int_t*[m_nMods]; + m_posx=new Double_t*[m_nMods]; + m_posy=new Double_t*[m_nMods]; + m_posz=new Double_t*[m_nMods]; + for (int i=0;i<m_nMods;i++){ + m_pixx[i]=new Int_t[MAXHIT]; + m_pixy[i]=new Int_t[MAXHIT]; + m_value[i]=new Int_t[MAXHIT]; + m_timing[i]=new Int_t[MAXHIT]; + m_hitincluster[i]=new Int_t[MAXHIT]; + m_posx[i]=new Double_t[MAXHIT]; + m_posy[i]=new Double_t[MAXHIT]; + m_posz[i]=new Double_t[MAXHIT]; + } + for (int i=0;i<m_nMods;i++){ + for(int j=0;j<MAXHIT;j++){ + m_hitincluster[i][j]=0; + m_posx[i][j]=0; + m_posy[i][j]=0; + m_posz[i][j]=0; + } + } + fillHistoTree(); + if(writeRootFile==true)setupRootFile(rootfile); + if(writeTemps==true)m_tempfile=new std::ofstream(tempfile); + +} + +CosmicMonitoringGuiEmbedded::CosmicMonitoringGuiEmbedded(const TGWindow *p,UInt_t w,UInt_t h,UInt_t options, const std::vector<ConfigGui*> config) + : TGVerticalFrame(p,w,h,options), m_config(config), m_nMods(0), m_evfile(0) { + init(); +} + +CosmicMonitoringGuiEmbedded::CosmicMonitoringGuiEmbedded(const char* filename, int nevt, const TGWindow *p,UInt_t w,UInt_t h,UInt_t options) + : TGVerticalFrame(p,w,h,options), m_filename(filename),m_nMods(0), m_evfile(0) { + + init(); + setup(false, false, 0, false, 0); //online==false + + readFile(m_filename, nevt); +// TFile a("out.root","recreate"); +// tdc->Write(); + // a.Close(); +} + +void CosmicMonitoringGuiEmbedded::clearTree(){ + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + if(root) {m_tree->DeleteChildren(root); + root->SetOpen(false); + updateTree(); + } +} + +void CosmicMonitoringGuiEmbedded::updateTree(){ + int x=m_tgc->GetViewPort()->GetX(); + int y=m_tgc->GetViewPort()->GetY(); + int w=m_tgc->GetViewPort()->GetWidth(); + int h=m_tgc->GetViewPort()->GetHeight(); + m_tree->DrawRegion(x,y,w,h); +} + +void CosmicMonitoringGuiEmbedded::updateHisto(){ + m_histo->SetMinimum(0); + if(m_histo->GetDimension()==1){ + m_canvas->GetCanvas()->SetCanvasSize(m_ww, m_wh); + if(std::string(m_histo->GetName()).substr(0,4)=="proj")gStyle->SetOptStat(1110); + else gStyle->SetOptStat(10); + m_histo->Draw(); + }else{ + gStyle->SetOptStat(10); + int nx=m_histo->GetNbinsX(); + int wh=0; + if(nx==144){ //FEI3 + wh=int(m_ww*0.944/0.4/144*320*0.05); + }else{ //FEI4 + wh=int(m_ww*0.944/0.25/80*336*0.05); + } + m_canvas->GetCanvas()->SetCanvasSize(m_ww, wh); + m_histo->Draw("colz"); + } +} + +void CosmicMonitoringGuiEmbedded::updateGraph(){ + m_canvas->GetCanvas()->SetCanvasSize(m_ww, m_wh); + m_graph->Draw("AP"); +} + +void CosmicMonitoringGuiEmbedded::fillHistoTree(){ + + char name[128], title[128]; + + clearTree(); + for (size_t i=0;i<m_histlist.size();i++){ + delete m_histlist[i]; + } + m_histlist.clear(); + for (int i=0;i<m_nMods;i++){ + if(m_fetype[i]==4){ + sprintf(name,"tempmin%d",i); + sprintf(title,"Temperature by minute Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + m_tempmin[i]=new TGraph; + m_tempmin[i]->SetMinimum(-40); + m_tempmin[i]->SetMarkerStyle(22); + m_tempmin[i]->SetName(name); + m_tempmin[i]->SetTitle(title); + m_tempmin[i]->Expand(1000); + m_histlist.push_back(m_tempmin[i]); + sprintf(name,"tempsec%d",i); + sprintf(title,"Temperature 60 sec Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + m_tempsec[i]=new TH1F(name, title, 60,0,60); + m_tempsec[i]->SetOption("p"); + m_tempsec[i]->SetMarkerStyle(22); + m_histlist.push_back(m_tempsec[i]); + }else{ + m_tempmin[i]=0; + m_tempsec[i]=0; + } + sprintf(name,"occ%d",i); + sprintf(title,"Occupancy Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + if(m_fetype[i]==4){ + m_occ[i]=new TH2F(name,title, 80,0,80,336,0, 336); //FEI4 + m_histlist.push_back(m_occ[i]); + m_occ[i]->SetMinimum(0); + } else if(m_fetype[i]==3) { + m_occ[i]=new TH2F(name,title, 8*18,0,8*18,2*160,0, 2*160); + m_histlist.push_back(m_occ[i]); + m_occ[i]->SetMinimum(0); + }else{ + m_occ[i]=0; + } + if(m_fetype[i]==4){ + m_projx[i]=new TH1F(Form("projx%d%d",m_outlinks[i],m_rceNums[i]), + Form("X projection Mod %d RCE %d", m_outlinks[i],m_rceNums[i]), + 80,0,20); + m_projx[i]->GetXaxis()->SetTitle("x (mm)"); + m_projy[i]=new TH1F(Form("projy%d%d",m_outlinks[i],m_rceNums[i]), + Form("Y projection Mod %d RCE %d", m_outlinks[i],m_rceNums[i]), + 336,0,16.8); + m_projy[i]->GetXaxis()->SetTitle("y (mm)"); + m_histlist.push_back(m_projx[i]); + m_histlist.push_back(m_projy[i]); + } else if(m_fetype[i]==3) { + m_projx[i]=new TH1F(Form("projx%d%d",m_outlinks[i],m_rceNums[i]), + Form("X projection Mod %d RCE %d", m_outlinks[i],m_rceNums[i]), + 144,0,57.6); + m_projx[i]->GetXaxis()->SetTitle("x (mm)"); + m_projy[i]=new TH1F(Form("projy%d%d",m_outlinks[i],m_rceNums[i]), + Form("Y projection Mod %d RCE %d", m_outlinks[i],m_rceNums[i]), + 320,0,16); + m_projy[i]->GetXaxis()->SetTitle("y (mm)"); + m_histlist.push_back(m_projx[i]); + m_histlist.push_back(m_projy[i]); + }else{ + m_projx[i]=0; + m_projy[i]=0; + } + sprintf(name,"tot%d",i); + sprintf(title,"ToT Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + if(m_fetype[i]==4){ + m_toth[i]=new TH1F(name,title, 60,-.5,59.5); + m_histlist.push_back(m_toth[i]); + } else if(m_fetype[i]==3) { + m_toth[i]=new TH1F(name,title, 256,-.5,255.5); + m_histlist.push_back(m_toth[i]); + } else + m_toth[i]=0; + + if(m_fetype[i]==3 || m_fetype[i]==4){ + sprintf(title,"Timing Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + sprintf(name,"bx%d",i); + m_bx[i]=new TH1F(name,title, 16,-.5,15.5); + m_histlist.push_back(m_bx[i]); + + // sprintf(title,"ToT Vs Timestamp Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + //sprintf(name,"tstamp%d",i); + //m_timestamp[i]=new TH1F(name, title, 5000,0.0,m_timeStampLimit); + //m_histlist.push_back(m_timestamp[i]); + m_timestamp[i]=0; + }else{ + m_bx[i]=0; + m_timestamp[i]=0; + } + if(m_fetype[i]==11){ // AFP HPTDC board + m_afptdc[i]=new TH1F*[12]; + for(int j=0;j<12;j++){ + sprintf(title,"TDC RCE%d-Board%d-Channel%d",m_rceNums[i],m_outlinks[i],j); + sprintf(name,"bx%d_%d",i,j); + m_afptdc[i][j]=new TH1F(name,title, 1024,-.5,1023.5); + m_histlist.push_back(m_afptdc[i][j]); + } + }else{ + m_afptdc[i]=0; + } + + + if(m_fetype[i]==3 || m_fetype[i]==4){ + int j=i+1; + if(j==m_nMods) j=0; //wrap around + while(m_fetype[j]!=3 && m_fetype[j]!=4){ + if(i==j)break; + j=j+1; + if(j==m_nMods)j=0; //wrap around + } + if(i!=j && m_corrindex[j]!=i){ + + int nX[2] = {8*18, 80}; + int nY[2] = {2*160, 336}; + int idxI =0, idxJ = 0; + + if(m_fetype[i]==4){ + idxI = 1; + } + if(m_fetype[j]==4){ + idxJ = 1; + } + sprintf(title,"Col-Col Correlation Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + sprintf(name,"corxx%d%d",i,j); + m_corxx[i]=new TH2F(name,title, nX[idxI],0,nX[idxI],nX[idxJ],0,nX[idxJ]); + + sprintf(title,"Col-Row Correlation Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + sprintf(name,"corxy%d%d",i,j); + m_corxy[i]=new TH2F(name,title, nX[idxI],0,nX[idxI],nY[idxJ],0,nY[idxJ]); + + sprintf(title,"Row-Row Correlation Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + sprintf(name,"coryy%d%d",i,j); + m_coryy[i]=new TH2F(name,title, nY[idxI],0,nY[idxI],nY[idxJ],0,nY[idxJ]); + + sprintf(title,"Row-Col Correlation Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + sprintf(name,"coryx%d%d",i,j); + m_coryx[i]=new TH2F(name,title, nY[idxI],0,nY[idxI],nX[idxJ],0,nX[idxJ]); + + m_histlist.push_back(m_corxx[i]); + m_histlist.push_back(m_corxy[i]); + m_histlist.push_back(m_coryy[i]); + m_histlist.push_back(m_coryx[i]); + m_corrindex[i]=j; + }else{ + m_corxx[i]=0; + m_corxy[i]=0; + m_coryy[i]=0; + m_coryx[i]=0; + } + } + } + + for (int i=0;i<m_nRces;i++){ + sprintf(title,"TDC for RCE %d",m_rces[i]); + sprintf(name,"tdc%d",i); + m_tdc[i]=new TH1F(name, title, 64,-.5,63.5); + m_histlist.push_back(m_tdc[i]); + for (int j=0;j<m_nMods;j++){ + if(m_fetype[j]==9){ + for(int k=0;k<2;k++){ + char tel[8]; + if(k==0)sprintf(tel,"A"); + else sprintf(tel,"B"); + for (int l=0;l<3;l++){ + sprintf(title,"Timing hitbus data RCE %d telescope %s FE %d", i, tel, l+1); + sprintf(name, "hbtiming_%d_%s_%d", i, tel, l+1); + m_hitbus[i][k][l]=new TH1F(name, title, 10,0,10); + m_histlist.push_back(m_hitbus[i][k][l]); + } + } + break; + } + } + } + + TGListTreeItem* root=m_tree->FindChildByName(0,"Histos"); + if (!root) root = m_tree->AddItem(0,"Histos"); + TGListTreeItem* occr=m_tree->AddItem(root,"Occupancy"); + TGListTreeItem* prxr=m_tree->AddItem(root,"Projection X"); + TGListTreeItem* pryr=m_tree->AddItem(root,"Projection Y"); + TGListTreeItem* timingr=m_tree->AddItem(root,"Timing"); + TGListTreeItem* totr=m_tree->AddItem(root,"ToT"); + TGListTreeItem* corr=m_tree->AddItem(root,"Correlation"); + TGListTreeItem* corrmods[m_nMods]; + for (int i=0;i<m_nMods;i++){ + sprintf(name,"Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + corrmods[i]=m_tree->AddItem(corr, name); + } + TGListTreeItem* tempr=m_tree->AddItem(root,"Temperatures"); + TGListTreeItem* tdcr=m_tree->AddItem(root,"TDC"); + // TGListTreeItem* tstampr=m_tree->AddItem(root,"Timestamp"); + TGListTreeItem* hitbusr=m_tree->AddItem(root,"Hitbus Timing"); + TGListTreeItem* afpr=m_tree->AddItem(root,"AFP TDC"); + const TGPicture *thp = gClient->GetPicture("h1_t.xpm"); + + for (int i=0;i<m_nRces;i++){ + char mtit[128]; + sprintf(mtit,"TDC for RCE %d",m_rces[i]); + m_tree->AddItem(tdcr,mtit, m_tdc[i], thp, thp); + } + + for (int i=0;i<m_nRces;i++){ + char mtit[128]; + if(m_hitbus[i][0][0]!=0){ + for(int k=0;k<2;k++){ + char tel[8]; + if(k==0)sprintf(tel,"A"); + else sprintf(tel,"B"); + for(int l=0;l<3;l++){ + sprintf(mtit, "RCE %d Telescope %s FE %d", i, tel, l+1); + m_tree->AddItem(hitbusr, mtit, m_hitbus[i][k][l], thp, thp); + } + } + } + } + + + for(int i=0;i<m_nMods;i++){ + char mtit[128]; + sprintf(mtit,"Mod%d-RCE%d",m_outlinks[i],m_rceNums[i]); + if(m_tempsec[i]!=0)m_tree->AddItem(tempr,Form("%s-sec", mtit),m_tempsec[i], thp, thp); + if(m_tempmin[i]!=0)m_tree->AddItem(tempr,Form("%s-min", mtit),m_tempmin[i], thp, thp); + if(m_occ[i]!=0)m_tree->AddItem(occr,mtit,m_occ[i], thp, thp); + if(m_projx[i]!=0)m_tree->AddItem(prxr,mtit,m_projx[i], thp, thp); + if(m_projy[i]!=0)m_tree->AddItem(pryr,mtit,m_projy[i], thp, thp); + if(m_toth[i]!=0)m_tree->AddItem(totr,mtit,m_toth[i], thp, thp); + if(m_bx[i]!=0)m_tree->AddItem(timingr,mtit, m_bx[i], thp, thp); + //if(m_timestamp[i]!=0)m_tree->AddItem(tstampr,mtit, m_timestamp[i], thp, thp); + if(m_afptdc[i]!=0){ + TGListTreeItem* mfpr=m_tree->AddItem(afpr,mtit); + for(int j=0;j<12;j++){ + sprintf(mtit, "Ch%d", j); + m_tree->AddItem(mfpr, mtit, m_afptdc[i][j], thp, thp); + } + } + if(m_corxx[i]!=0){ + int j=m_corrindex[i]; + sprintf(mtit,"Col-Col Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + m_tree->AddItem(corrmods[i],mtit, m_corxx[i], thp, thp); + sprintf(mtit,"Col-Row Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + m_tree->AddItem(corrmods[i],mtit, m_corxy[i], thp, thp); + sprintf(mtit,"Row-Row Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + m_tree->AddItem(corrmods[i],mtit, m_coryy[i], thp, thp); + sprintf(mtit,"Row-Col Mod%d-RCE%d x Mod%d-RCE%d",m_outlinks[i],m_rceNums[i],m_outlinks[j],m_rceNums[j]); + m_tree->AddItem(corrmods[i],mtit, m_coryx[i], thp, thp); + } + } + + root->SetOpen(true); + timingr->SetOpen(true); + totr->SetOpen(true); + occr->SetOpen(true); + tempr->SetOpen(true); + prxr->SetOpen(true); + pryr->SetOpen(true); + corr->SetOpen(true); + afpr->SetOpen(true); + for (int i=0;i<m_nMods;i++){ + corrmods[i]->SetOpen(true); + } +} + +void CosmicMonitoringGuiEmbedded::displayHisto(TGListTreeItem* item, int b){ + TGListTreeItem *parent=item->GetParent(); + if(parent==0)return; + if(std::string(parent->GetText())=="Histos")return; + if(std::string(parent->GetText())=="Correlation")return; + if(std::string(parent->GetText())=="AFP TDC")return; + TObject *t=(TObject*)item->GetUserData(); + if(t->InheritsFrom("TH1")){ + m_histo=(TH1*)item->GetUserData(); + m_graph=0; + }else if(t->InheritsFrom("TGraph")){ + m_graph=(TGraph*)item->GetUserData(); + m_histo=0; + } + updateDisplay(); +} + +void CosmicMonitoringGuiEmbedded::updateDisplay(){ + if(m_www!=GetWidth()|| + m_hhh!=GetHeight()){ + m_www=GetWidth(); + m_hhh=GetHeight(); + m_ww=m_canvas->GetCanvas()->GetWw(); + m_wh=m_canvas->GetCanvas()->GetWh(); + } + m_canvas->GetCanvas()->Clear(""); + m_canvas->GetCanvas()->Update(); + if(m_histo!=0) updateHisto(); + else if(m_graph!=0){ + m_graphmutex.Lock(); //ROOT crashes if the graph is updated between Draw() and canvas Update() + updateGraph(); + } + m_canvas->GetCanvas()->Update(); + if(m_graph!=0)m_graphmutex.UnLock(); +} + +unsigned CosmicMonitoringGuiEmbedded::nextcurrent(unsigned char* p){ + unsigned current=*(unsigned*)&p[m_indx]; + //unsigned current=(p[m_indx]<<24) | (p[m_indx+1]<<16) | (p[m_indx+2]<<8) | p[m_indx+3]; + m_indx+=4; + return current; +} +unsigned CosmicMonitoringGuiEmbedded::getWord(unsigned char *p, int word){ + return *(unsigned*)&p[word*4]; + //return (p[word*4]<<24) | (p[word*4+1]<<16) | (p[word*4+2]<<8) | p[word*4+3]; +} + + +bool CosmicMonitoringGuiEmbedded::setupChannelsFromFile(const char* filename) +{ + std::cout<<"Setting up channels based on first event in file "<<filename<<std::endl; + eudaq::FileDeserializer fs(filename); + bool itWorked=false; + + if(fs.HasData()){ + + eudaq::DetectorEvent* dev=(eudaq::DetectorEvent*)eudaq::EventFactory::Create(fs); + dev=(eudaq::DetectorEvent*)eudaq::EventFactory::Create(fs); //get the second event in file (first event is just a file header) + + if(dev->IsEORE() || dev->IsBORE()) return false; + eudaq::RawDataEvent::data_t pixblock; + + int rce=-1; + int link=-1; + + for(unsigned k=0;k<dev->NumEvents();k++){ + + eudaq::RawDataEvent* rev=(eudaq::RawDataEvent*)dev->GetEvent(k); + + int totalBlocks = rev->NumBlocks(); + int currentBlock = 0; + + if(rev->GetSubType()=="APIX-CT"){ + eudaq::RawDataEvent::data_t block0=rev->GetBlock(0); + + size_t blockSize = block0.size(); + const unsigned tdcSize = 10; //number of 4-byte words of TDC data per RCE + + int nTDC = blockSize/(4*tdcSize); + + for(int iTDC=0; iTDC<nTDC; iTDC++){ + int firstWord = iTDC*tdcSize; + unsigned rceNum=getWord(&block0[0],firstWord+0); + rceNum = rceNum&0xff; + addRce(rceNum); + } + currentBlock = 1; + + }else if(rev->GetSubType()=="CTEL"){ + currentBlock = 0; + totalBlocks = 1; + }else{ + //std::cout<<"Unknown data block. Skipping."<<std::endl; + continue; + } + + + while(currentBlock<totalBlocks){ + + pixblock=rev->GetBlock(currentBlock); + m_indx=0; + + while (m_indx<pixblock.size()){ + unsigned currentu=nextcurrent(&pixblock[0]); + + FormattedRecord current(currentu); + if(current.isHeader()){ + link=current.getLink(); + bool newlink = createLink(link,rce); + if(newlink){ + m_fetype.push_back(4); //hard-code FEI4 for now + } + } + else if(current.isHeaderTwo()){ + rce = current.getRCE(); + } + else{ + continue; + } + + } + currentBlock++; + } //end loop over all the pixel blocks in event + + } //end loop over all the 'events' + + itWorked=true; + } + return itWorked; + +} + + +bool CosmicMonitoringGuiEmbedded::readFile(const char* filename,int nevt) +{ + //This reads in a file in the EUDET format + + std::cout<<"Reading file "<<filename<<std::endl; + + m_nev = ntrg = highesttot = 0; + eudaq::FileDeserializer fs(filename); + while(fs.HasData()){ + eudaq::DetectorEvent* dev=(eudaq::DetectorEvent*)eudaq::EventFactory::Create(fs); + if(m_nev>nevt)break; + //if(nev==10)break; + // dev->Print(std::cout); + addEvent(dev); + } + std::cout<<"\n----------Summary---------------------"<<std::endl; + std::cout<<"Highest ToT: "<<highesttot<<std::endl; + //need to subtract 2 from m_nev because of the end-of-file and begin-of-file + std::cout<<(m_nev-2)<<" events. "<<ntrg<<" triggers, summed over all frontends."<<std::endl; + + return true; +} +bool CosmicMonitoringGuiEmbedded::addEvent(const eudaq::DetectorEvent* dev, bool refresh){ + eudaq::RawDataEvent::data_t pixblock; + if(dev->IsEORE() || dev->IsBORE()) return false; + // std::cout<<std::endl<<"Adding a new event!!!"<<std::endl; + + int l1id=-1; + int link=-1; + int bxid=0; + int rce=-1; + int firstbxid=-1; + int oldrce=-1; + int oldbxid[MAX_LINKS]; + std::vector<int> modtot; + for(int i=0;i<m_nMods;i++){ + modtot.push_back(0); + m_nhits[i]=0; + oldbxid[m_outlinks[i]]=-1; + } + + //std::vector<double> timeStamps; + //for(int i=0; i<m_nRces; i++){ + //timeStamps.push_back(0); + //} + + + for(unsigned k=0;k<dev->NumEvents();k++){ + eudaq::RawDataEvent* rev=(eudaq::RawDataEvent*)dev->GetEvent(k); + + int totalBlocks = rev->NumBlocks(); + int currentBlock = 0; + m_triggerPhase = -1; + + if(rev->GetSubType()=="APIX-CT"){ + m_nev++; + if((m_nev-1)%10000==0){ + std::cout<<"Event "<<(m_nev-1)<<std::endl; + if(m_nev>1){ + for (int i=0;i<m_nMods;i++){ + if(m_occ[i]==0)continue; + float rate=0; + if(m_occ[i]->GetEntries()-m_lastcount[i]>0)rate=(m_occ[i]->GetEntries()-m_lastcount[i])/10000; + std::cout<<"Hits per event for "<<m_rceNums[i]<<" "<<m_outlinks[i]<<": "<<rate <<std::endl; + m_lastcount[i]=m_occ[i]->GetEntries(); + if((m_nMods>1 && i==1)||m_nMods==1)m_hitsperevent=rate; + } + } + } + // std::cout<<"event "<<m_nev<<" contains "<<dev->NumEvents()<<" 'events' "<<std::endl; + + eudaq::RawDataEvent::data_t block0=rev->GetBlock(0); + + size_t blockSize = block0.size(); + const unsigned tdcSize = 10; //number of 4-byte words of TDC data per RCE + + int nTDC = blockSize/(4*tdcSize); + + //for(unsigned int i=0;i<(blockSize/4);i++){ + // std::cout<<std::hex<<getWord(&block0[0],i)<<std::dec<<std::endl; + //} + + int oldBitpos=-1; + for(int iTDC=0; iTDC<nTDC; iTDC++){ + + int firstWord = iTDC*tdcSize; + + unsigned rceNum=getWord(&block0[0],firstWord+0); + rceNum = rceNum&0xff; + + unsigned counter1=getWord(&block0[0],firstWord+3); + unsigned counter2=getWord(&block0[0],firstWord+4); + unsigned long long counter=counter2; + counter=(counter<<32) | counter1; + //printf("%llx\n",counter); + int bitpos=-1; + for (int j=0;j<64;j++){ + if(((counter>>j)&1)==0){ + bitpos=j; + break; + } + } + // if(bitpos!=-1)std::cout<<"Phase is " <<bitpos*.4<<" ns"<<std::endl; + + for(int iRce=0; iRce<m_nRces; iRce++){ + if(m_rces[iRce]==rceNum){ + if(bitpos!=-1){ + m_tdc[iRce]->Fill(bitpos); + m_triggerPhase = bitpos; + if (oldBitpos!=-1 && oldBitpos!=bitpos){ + std::cout<<"TDC value mismatch between RCEs"<<std::endl; + } + oldBitpos=bitpos; + } + break; + } + } + + for(int iRce=0; iRce<m_nRces; iRce++){ + if(m_rces[iRce]==rceNum){ + if(m_hitbus[iRce][0][0]!=0){ + for(int k=0;k<2;k++){ + for (int l=0;l<3;l++){ + int edge=hitbusEdge(k==0?counter1 : counter2,l); + if(edge!=-1)m_hitbus[iRce][k][l]->Fill(edge); + } + } + } + break; + } + } + + + + unsigned trgtime1=getWord(&block0[0],firstWord+5); + unsigned trgtime2=getWord(&block0[0],firstWord+6); + unsigned deadtime1=getWord(&block0[0],firstWord+7); + unsigned deadtime2=getWord(&block0[0],firstWord+8); + unsigned long long trgtime=trgtime1; + trgtime=(trgtime<<32) | trgtime2; + unsigned long long deadtime=deadtime1; + deadtime=(deadtime<<32) | deadtime2; + //unsigned hitbusword=(getWord(&block0[0],firstWord+9)&0xf000000)>>24; + //std::cout<<"Trigtime "<<trgtime<<std::endl; + //std::cout<<"Deadtime "<<deadtime<<std::endl; + //double timeStampSeconds = trgtime * 25.6e-9; + //std::cout<<"event "<<m_nev<<" on RCE "<<rceNum<<"\t\t Time stamp: "<<timeStampSeconds<<" sec."<<std::endl; + //rebinTimestamps(timeStampSeconds); + // unsigned eudaqtrg=getWord(&block0[0],firstWord+9); + // std::cout<<"Eudaq trigger word: "<<eudaqtrg<<std::endl; + //for(int iRce=0; iRce<m_nRces; iRce++){ + //if(m_rces[iRce]==rceNum){ + //timeStamps[iRce] = timeStampSeconds; + //} + //} + + if(m_writeRootFile==true && iTDC==0){ + m_eventinfo.timestamp=time(NULL); + m_eventinfo.framenumber=m_nev; + m_eventinfo.triggerTime=trgtime; + m_evtree->Fill(); + } + } //end loop over the different RCE's in the TDC block + + currentBlock = 1; + + }else if(rev->GetSubType()=="CTEL"){ + currentBlock = 0; + totalBlocks = 1; + }else if(rev->GetSubType()=="TEMP"){ + // Temperature readout + pixblock=rev->GetBlock(0); + unsigned rce=getWord(&pixblock[0],0); + unsigned short *adc=(unsigned short*)&pixblock[4]; + unsigned timenow=(unsigned)time(0); + int timediffsec=timenow-m_starttime_sec; + for(int i=0;i<8;i++){ + float res=0; + int chan=i; // remapped to outlinks. + int mod = m_linkToIndex[rce][chan]; + if(mod==-1 || m_tempsec[mod]==0)continue; + float reading=float(adc[i]&0xfff); + if(reading==0)res=0; + else res=(4095./reading-1)*10000-100; + float temperature=-273; + float b=3435; + if(res!=0)temperature=b*298.15/(b+log(res/10000)*298.15)-273.15; + if(timediffsec%60<m_lasttime_sec){ + float newval=0; + if(m_tempsec[mod]->GetEntries()>0)newval=m_tempsec[mod]->GetSumOfWeights()/m_tempsec[mod]->GetEntries(); + m_graphmutex.Lock(); + m_tempmin[mod]->SetPoint(m_tempmin[mod]->GetN(), (float)timediffsec/60, newval); + m_graphmutex.UnLock(); + m_tempsec[mod]->Reset(); + } + if(m_tempsec[mod]->GetBinContent(timediffsec%60)==0){ //sometimes 2 readings in the same bin + m_tempsec[mod]->SetBinContent(timediffsec%60, temperature); + if(m_logtemps==true)*m_tempfile<<timenow<<" "<<rce<<" "<<chan<<" "<<temperature<<std::endl; + } + } + m_lasttime_sec=timediffsec%60; + if (refresh) updateDisplay(); + return true; + }else{ + //std::cout<<"Unknown data block. Skipping."<<std::endl; + continue; + } + + while(currentBlock<totalBlocks){ + + pixblock=rev->GetBlock(currentBlock); + m_indx=0; + + while (m_indx<pixblock.size()){ + unsigned currentu=nextcurrent(&pixblock[0]); + + FormattedRecord current(currentu); + if(current.isHeader()){ + ntrg++; //really, this is the total number of triggers summed over all the modules + link=current.getLink(); + int l1id_temp=current.getL1id()&0xf; + bxid=current.getBxid()&0xff; + if(l1id==-1){ + l1id = l1id_temp; + } else{ + if(l1id_temp != l1id){ + std::cout<<"Not all data in event has same l1id!! FATAL ERROR!"<<std::endl; + assert(0); + } + } + if(firstbxid==-1){ + firstbxid = bxid; + } + + if( oldbxid[link]!=-1 ){ + int bxid_expected = oldbxid[link] + 1; + if(bxid_expected==256){ + bxid_expected=0; + } + if(bxid!=bxid_expected){ + std::cout<<"WARNING: RCE "<<rce<<" link "<<link<<" has bxid = "<<bxid; + std::cout<<" ; expected bxid = "<<bxid_expected<<std::endl; + } + } else{ + //this is the first data from this rce/link in this event. + if(bxid!=firstbxid){ + std::cout<<"ERROR: not all the modules in RCE "<<rce<<" in this event have the "; + std::cout<<"same initial bxid. FATAL ERROR."<<std::endl; + assert(0); + } + + } + oldbxid[link] = bxid; + } + else if(current.isHeaderTwo()){ + rce = current.getRCE(); + if(rce != oldrce){ + oldrce=rce; + for(int i=0;i<m_nMods;i++)oldbxid[m_outlinks[i]]=-1; + firstbxid=-1; //Modules from different rce's can have different + //bxid's, even if they have the same l1id + } + + }else if(current.isData()){ + m_nhit++; + int mod = m_linkToIndex[rce][link]; + int chip=0; + int tot=0; + int col=0; + int row=0; + int x=0; + int y=0; + int diffbx=0; + if(m_fetype[mod]==3 || m_fetype[mod]==4){ + chip=current.getFE(); + tot=current.getToT(); + if(tot>highesttot)highesttot=tot; + col=current.getCol(); + row=current.getRow(); + diffbx=bxid-firstbxid; + if (diffbx<0)diffbx+=256; + if (chip<8){ + x=18*chip+col; + y=row; + } else { + x=(15-chip)*18+17-col; + y= 319-row; + } + if(m_occ[mod]!=0){ + m_occ[mod]->Fill(x,y); + modtot[mod]+=tot; + m_bx[mod]->Fill(diffbx); + } + if(m_projx[mod]!=0){ + int nx=m_projx[mod]->GetNbinsX(); + double scale=0.25; + if(nx==144)scale=0.4; + m_projx[mod]->Fill(x*scale+scale/2); + m_projy[mod]->Fill(0.05*y+0.025); + } + }else if (m_fetype[mod]==11){ //AFP HPTDC + unsigned word=current.getWord(); + unsigned tdcid=(word>>24)&0xf; + if (tdcid>0xc || tdcid<0xa){ //TDC ids are a, b, c + std::cout<<"Bad TDC id"<<std::endl; + }else{ + unsigned chan=(word>>22)&0x3; + x=(tdcid-0xa)*4+chan; + y=(word>>28)&0x1; + tot=word&0x1fffff; //10 bits + if(m_afptdc[mod]!=0){ + m_afptdc[mod][x]->Fill(tot&0x3ff); + } + } + } + if(m_nhits[mod]<MAXHIT){ + m_pixx[mod][m_nhits[mod]]=x; + m_pixy[mod][m_nhits[mod]]=y; + m_value[mod][m_nhits[mod]]=tot; + m_timing[mod][m_nhits[mod]]=diffbx; + m_nhits[mod]++; + }else{ + std::cout<<"MORE THAN "<<MAXHIT<<" hits in module RCE "<<m_rceNums[mod]<<" outlink "<<m_outlinks[mod]<<std::endl; + } + } + + }//end loop over data in the pixel block + + currentBlock++; + } //end loop over all the pixel blocks in event + + } //end loop over all the events + + + for(int i=0;i<m_nMods;i++){ + + if(m_toth[i]!=0 && modtot[i]!=0)m_toth[i]->Fill(modtot[i]); + + //double theTimeStamp=0; + //unsigned rceNum = m_rceNums[i]; + + //for(int iRce=0; iRce<m_nRces; iRce++){ + //if(m_rces[iRce]==rceNum){ + ////std::cout<<"getting timestamp for iRce = "<<iRce<<std::endl; + //theTimeStamp = timeStamps[iRce]; + //} + //} + + //if(modtot[i]>100){ + // std::cout<<"filling stamp for mod "<<i<<" with "<<theTimeStamp<<std::endl; + //std::cout<<m_timestamp[i]<<std::endl; + //if(m_timestamp[i]!=0)m_timestamp[i]->Fill(theTimeStamp,modtot[i]); + //} + + //if(modtot[i]>100){ + //std::cout<<"Noisy hit on event "<<m_nev<<", timestamp "<<theTimeStamp<<" s, with ToT on mod "<<i<<" = "<<modtot[i]<<std::endl; + //} + + if(m_corxx[i]!=0){ + int j=m_corrindex[i]; + for(int iHit=0; iHit<m_nhits[i]; iHit++){ + for(int jHit=0; jHit<m_nhits[j]; jHit++){ + + int x1 = m_pixx[i][iHit]; + int y1 = m_pixy[i][iHit]; + int x2 = m_pixx[j][jHit]; + int y2 = m_pixy[j][jHit]; + + m_corxx[i]->Fill(x1,x2); + m_corxy[i]->Fill(x1,y2); + m_coryy[i]->Fill(y1,y2); + m_coryx[i]->Fill(y1,x2); + + } + } + } + if(m_writeRootFile==true){ + m_pltree[i]->Fill(); + } + } + + if (refresh) updateDisplay(); + + return true; + +} + +void CosmicMonitoringGuiEmbedded::addRce(unsigned int rceNum){ + + int rceSize = m_rces.size(); + bool newRce=true; + for(int iRce=0; iRce<rceSize; iRce++){ + if(m_rces[iRce]==rceNum){ + newRce=false; + break; + } + } + if(newRce){ + std::cout<<"Adding rce "<<rceNum<<std::endl; + m_rces.push_back(rceNum); + } + m_nRces=m_rces.size(); + +} + +void CosmicMonitoringGuiEmbedded::printModules(){ + + for (unsigned int i=0; i<m_config.size(); i++){ + + if(m_config[i]->isIncluded()){ + //valid=true; + unsigned outlink=m_config[i]->getOutLink(); + unsigned rce=m_config[i]->getRce(); + std::cout<<"Module "<<i<<" : rce = "<<rce<<", outlink = "<<outlink<<std::endl; + } + } + +} + +bool CosmicMonitoringGuiEmbedded::createLink(unsigned outlink, unsigned rceNum){ + bool newLink=false; + + if(m_linkmap.find(outlink + 1000*rceNum) != m_linkmap.end()){ + //std::cout<<"Already have link "<<outlink<<" rce "<<rceNum<<std::endl; + } + else{ + std::cout<<"Making link "<<outlink<<" rce "<<rceNum<<std::endl; + + m_linkmap[outlink + 1000*rceNum] = m_nMods; + if(m_linkToIndex[rceNum]==0){ + m_linkToIndex[rceNum]=new int[MAX_LINKS]; + for(int i=0;i<MAX_LINKS;i++)m_linkToIndex[rceNum][i]=-1; + } + m_linkToIndex[rceNum][outlink]=m_nMods; + m_outlinks.push_back(outlink); + m_rceNums.push_back(rceNum); + m_nMods++; + newLink=true; + } + + return newLink; + +} + +void CosmicMonitoringGuiEmbedded::saveHistos(int runnum, const char* datadir){ + + char filename[512]; + sprintf(filename, "%s/cosmic_%06d/monitoringHistograms.root", datadir, runnum); + TFile histofile(filename, "recreate"); + for (int i=0;i<m_nMods;i++){ + if (m_tempmin[i] != 0) m_tempmin[i]->Write(); + if (m_tempsec[i] != 0) m_tempsec[i]->Write(); + if (m_occ[i] != 0) m_occ[i]->Write(); + if (m_toth[i] != 0) m_toth[i]->Write(); + if (m_bx[i] != 0) m_bx[i]->Write(); + //if (m_timestamp[i]!=0) m_timestamp[i]->Write(); + if (m_corxx[i] != 0) m_corxx[i]->Write(); + if (m_corxy[i] != 0) m_corxy[i]->Write(); + if (m_coryy[i] != 0) m_coryy[i]->Write(); + if (m_coryx[i] != 0) m_coryx[i]->Write(); + if (m_projx[i] != 0) m_projx[i]->Write(); + if (m_projy[i] != 0) m_projy[i]->Write(); + if (m_afptdc[i]!=0){ + for (int j=0;j<12;j++){ + m_afptdc[i][j]->Write(); + } + } + } + for(int i=0; i<m_nRces; i++){ + if (m_tdc[i]!=0) m_tdc[i]->Write(); + for (int k=0;k<2;k++){ + for (int l=0;l<3;l++){ + if(m_hitbus[i][k][l]!=0)m_hitbus[i][k][l]->Write(); + } + } + } +} + +void CosmicMonitoringGuiEmbedded::saveScreenshot(int runnum, const char* datadir){ + + char filename[512]; + sprintf(filename, "%s/cosmic_%06d/screenshot_%d.png", datadir, runnum, m_nScreenshots++); + std::cout<<filename<<std::endl; + m_canvas->SaveAs(filename); +} + +void CosmicMonitoringGuiEmbedded::rebinTimestamps(double timeStamp){ + + while( (timeStamp + 1) > m_timeStampLimit ){ + + m_timeStampLimit = m_timeStampLimit*2; + + //std::cout<<"Timestamp limit changed to "<<m_timeStampLimit<<std::endl; + + for(int imod=0; imod<m_nMods; imod++){ + if(m_timestamp[imod]!=0){ + const int nbins = m_timestamp[imod]->GetNbinsX(); + double xmin = m_timestamp[imod]->GetBinLowEdge(1); + double xmax = m_timestamp[imod]->GetBinLowEdge(nbins+1); + double newxmax = 2*(xmax-xmin) + xmin; + + double yvals[nbins]; + + //std::cout<<"Originally:"<<std::endl; + //for(int jbin=0; jbin < nbins; jbin++){ + // std::cout<<"jbin+1: "<<jbin+1<<" = "<<m_timestamp[imod]->GetBinContent(jbin+1)<<std::endl; + // } + + + for(int jbin=0; jbin < nbins; jbin++){ + yvals[jbin] = 0; + } + for(int jbin=0; jbin < (nbins/2); jbin++){ + int bin1 = jbin*2 + 1; + yvals[jbin] = m_timestamp[imod]->GetBinContent(bin1) + m_timestamp[imod]->GetBinContent(bin1+1); + } + + m_timestamp[imod]->SetBins(nbins,xmin,newxmax); + + for(int jbin=0; jbin < nbins; jbin++){ + m_timestamp[imod]->SetBinContent(jbin+1,yvals[jbin]); + } + + //std::cout<<"Now:"<<std::endl; + // for(int jbin=0; jbin < nbins; jbin++){ + // std::cout<<"jbin+1: "<<jbin+1<<" = "<<m_timestamp[imod]->GetBinContent(jbin+1)<<std::endl; + // } + + } + } + + + } + +} + +void CosmicMonitoringGuiEmbedded::setupRootFile(const char* rootfile){ + m_evfile=new TFile(rootfile, "recreate"); + m_pltree=new TTree*[m_nMods]; + for (int i=0;i<m_nMods;i++){ + char name[128]; + sprintf(name, "Plane%d", i); + m_evfile->cd(); + m_evfile->mkdir(name); + m_evfile->cd(name); + m_pltree[i]=new TTree("Hits", "Hits"); + m_pltree[i]->Branch("NHits", &m_nhits[i], "NHits/I"); + m_pltree[i]->Branch("PixX", m_pixx[i], "HitPixX[NHits]/I"); + m_pltree[i]->Branch("PixY", m_pixy[i], "HitPixY[NHits]/I"); + m_pltree[i]->Branch("Value", m_value[i], "HitValue[NHits]/I"); + m_pltree[i]->Branch("Timing", m_timing[i], "HitTiming[NHits]/I"); + m_pltree[i]->Branch("HitInCluster", m_hitincluster[i], "HitInCluster[NHits]/I"); + m_pltree[i]->Branch("PosX", m_posx[i], "HitPosX[NHits]/D"); + m_pltree[i]->Branch("PosY", m_posy[i], "HitPosY[NHits]/D"); + m_pltree[i]->Branch("PosZ", m_posz[i], "HitPosZ[NHits]/D"); + } + m_evfile->cd(); + m_evtree=new TTree("Event", "Event information"); + m_evtree->Branch("TimeStamp", &m_eventinfo.timestamp, "TimeStamp/l"); + m_evtree->Branch("FrameNumber", &m_eventinfo.framenumber, "FrameNumber/l"); + m_evtree->Branch("TriggerOffset", &m_eventinfo.triggeroffset, "TriggerOffset/I"); + m_evtree->Branch("TriggerInfo", &m_eventinfo.triggerinfo, "TriggerInfo/I"); + m_evtree->Branch("Invalid", &m_eventinfo.invalid, "Invalid/O"); + m_evtree->Branch("TriggerTime", &m_eventinfo.triggerTime, "TriggerTime/l"); + m_evtree->Branch("TriggerPhase", &m_triggerPhase, "TriggerPhase/I"); + m_evfile->Write(); + +} +void CosmicMonitoringGuiEmbedded::closeRootFile(){ + usleep(500000); + m_evfile->Write(); + m_evfile->Close(); + m_evfile->Delete(); + delete [] m_pltree; +} +void CosmicMonitoringGuiEmbedded::closeTempFile(){ + m_tempfile->close(); + delete m_evfile; +} diff --git a/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.hh b/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.hh new file mode 100644 index 0000000000000000000000000000000000000000..c58cd5186d45e2ce7f8003b3fd99e69ddeac84b6 --- /dev/null +++ b/rce/rcecalib/server/CosmicMonitoringGuiEmbedded.hh @@ -0,0 +1,140 @@ +#ifndef COSMICMONITORINGGUIEMBDED_HH +#define COSMICMONITORINGGUIEMBDED_HH + +#include "ConfigGui.hh" +#include "TGMdiMainFrame.h" +#include <TGLabel.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include "TFile.h" +#include "TH2F.h" +#include "TGraph.h" +#include <TTree.h> +#include <string> +#include <map> +#include "TMutex.h" + +#define MAX_RCES 8 +#define MAXHIT 1000 + + +class TGListTree; +class TGListTreeItem; +class TH1; +class TRootEmbeddedCanvas; +class IPCGuiCallback; +namespace eudaq { +class DetectorEvent; +} + +struct EventInfo{ + ULong64_t timestamp; + ULong64_t framenumber; + Int_t triggeroffset; + Int_t triggerinfo; + Bool_t invalid; + ULong64_t triggerTime; +}; + +class CosmicMonitoringGuiEmbedded: public TGVerticalFrame { +public: + CosmicMonitoringGuiEmbedded(const char* filename, int nevt, const TGWindow *p,UInt_t w,UInt_t h,UInt_t options); + CosmicMonitoringGuiEmbedded(const TGWindow *p,UInt_t w,UInt_t h,UInt_t options, const std::vector<ConfigGui*> config); + virtual ~CosmicMonitoringGuiEmbedded(); + void setup(bool online, bool writeRootFile, const char* rootfile, bool writeTemps, const char* tempfile); + void clearTree(); + void updateTree(); + void updateDisplay(); + void updateHisto(); + void updateGraph(); + void saveHistos(int runnum, const char* datadir); + void saveScreenshot(int runnum, const char* datadir); + void displayHisto(TGListTreeItem* item, int b); + unsigned nextcurrent(unsigned char* p); + unsigned getWord(unsigned char *p, int word); + bool setupChannelsFromFile(const char* filename); + bool addEvent(const eudaq::DetectorEvent* dev, bool refresh = false); + bool readFile(const char* filename, int nevt); + void addRce(unsigned int rceNum); + void printModules(); + bool createLink(unsigned outlink, unsigned rceNum); + void rebinTimestamps(double timestamp); + double getHitsPerEvent(){return m_hitsperevent;} + void closeRootFile(); + void closeTempFile(); + +private: + + void fillHistoTree(); + void init(); + void setupRootFile(const char* rootfile); + + enum Filemenu {LOAD, SAVE, QUIT}; + TGTextButton* *m_quit; + TGListTree* m_tree; + TH1 *m_histo; + TGraph* m_graph; + const std::vector<ConfigGui*> m_config; + const char* m_filename; + TRootEmbeddedCanvas *m_canvas; + std::string m_dir; + bool m_delhisto; + TGCanvas *m_tgc; + + //Currently setting the limit at 4 RCE's (with 8 modules each) + TH2F* m_occ[ConfigGui::MAX_MODULES]; + TH2F* m_corxx[ConfigGui::MAX_MODULES-1]; + TH2F* m_corxy[ConfigGui::MAX_MODULES-1]; + TH2F* m_coryy[ConfigGui::MAX_MODULES-1]; + TH2F* m_coryx[ConfigGui::MAX_MODULES-1]; + TH1F* m_toth[ConfigGui::MAX_MODULES]; + TH1F* m_bx[ConfigGui::MAX_MODULES]; + TH1F* m_tdc[MAX_RCES]; + TH1F* m_hitbus[MAX_RCES][2][3]; + TH1F* m_timestamp[ConfigGui::MAX_MODULES]; + TH1F* m_projx[ConfigGui::MAX_MODULES]; + TH1F* m_projy[ConfigGui::MAX_MODULES]; + TH1F **m_afptdc[ConfigGui::MAX_MODULES]; + int m_corrindex[ConfigGui::MAX_MODULES]; + TH1F* m_tempsec[ConfigGui::MAX_MODULES]; + TGraph* m_tempmin[ConfigGui::MAX_MODULES]; + std::vector<TObject*> m_histlist; + + unsigned int m_indx; + double m_noiserate; + int m_noiseUpdateTime; + + std::map<int,int> m_linkmap; + enum constants{MAX_RCE_NUM=100, MAX_LINKS=16}; + int **m_linkToIndex; + std::vector<unsigned> m_outlinks; + std::vector<unsigned> m_rceNums; + std::vector<int> m_fetype; + std::vector<unsigned int> m_rces; + int m_nMods; + int m_nRces; + int m_nev; + int m_nhit; + int ntrg; + int highesttot; + double m_timeStampLimit; + unsigned int m_ww, m_wh, m_www, m_hhh; + int m_lastcount[ConfigGui::MAX_MODULES]; + double m_hitsperevent; + int m_nScreenshots; + TFile *m_evfile; + std::ofstream *m_tempfile; + TTree **m_pltree, *m_evtree; + Int_t *m_nhits; + Int_t **m_pixx, **m_pixy, **m_value, **m_timing, **m_hitincluster; + Int_t m_triggerPhase; + Double_t **m_posx, **m_posy, **m_posz; + EventInfo m_eventinfo; + bool m_writeRootFile, m_logtemps; + unsigned m_starttime_sec; + int m_lasttime_sec; + TMutex m_graphmutex; + +ClassDef (CosmicMonitoringGuiEmbedded,0) +}; +#endif diff --git a/rce/rcecalib/server/CosmicOfflineDataProc.cc b/rce/rcecalib/server/CosmicOfflineDataProc.cc new file mode 100644 index 0000000000000000000000000000000000000000..0aa3f6dc06f0ec0a5f8889459c1841f023f8434d --- /dev/null +++ b/rce/rcecalib/server/CosmicOfflineDataProc.cc @@ -0,0 +1,378 @@ +#include <boost/property_tree/ptree.hpp> +#include <boost/regex.hpp> +#include <boost/algorithm/string.hpp> +#include "server/CosmicOfflineDataProc.hh" +#include "config/ConfigIF.hh" +#include "config/FormattedRecord.hh" +#include "dataproc/DataProcFactory.hh" +#include "dataproc/CosmicEventReceiver.hh" +#include "dataproc/CosmicEvent.hh" +#include "dataproc/CosmicEventIterator.hh" +#include "dataproc/Channeldefs.hh" +#include "server/IPCController.hh" +#include "config/AbsFormatter.hh" +#include "config/ModuleInfo.hh" +#include "eudaq/Event.hh" +#include "eudaq/DataSender.hh" +#include "eudaq/DataSenderIF.hh" +#include "eudaq/DetectorEvent.hh" +#include "eudaq/RawDataEvent.hh" +#include "eudaq/counted_ptr.hh" +#include <iomanip> +#include <iostream> +#include <stdlib.h> +#include <time.h> + +namespace{ + const unsigned timeout=5; +} + +void printhitbus(unsigned word){ + for (int i=0;i<3;i++){ + std::cout<<"FE "<<3-i<<": "; + for (int j=0;j<10;j++){ + std::cout<<((word&(1<<(j*3+i)))!=0); + } + std::cout<<std::endl; + } +} +int CosmicOfflineDataProc::processData(unsigned short rlink, unsigned char* data, int size){ + //std::cout<<"Event size = "<<size<<std::endl; + //std::cout<<std::hex<<"First word = "<<(unsigned)data[0]<<(unsigned)data[1]<<(unsigned)data[2]<<(unsigned)data[3]<<std::dec<<std::endl; + assert(size!=0); + m_nfrag++; + int link=rlink&LINKMASK; + int rceNum = (rlink>>RCEPOS)&RCEMASK; + //std::cout<<"Data from link "<<link<<std::endl; + if (link==ADCREADOUT){ + //std::cout<<"Data from link 8"<<std::endl; + eudaq::DetectorEvent *dev=new eudaq::DetectorEvent(m_runNo,0,0); + counted_ptr<eudaq::Event> ev(dev); + eudaq::RawDataEvent* cpcp=new eudaq::RawDataEvent("TEMP",m_runNo,0); + counted_ptr<eudaq::Event> cpc(cpcp); + cpcp->AddBlock(0); + cpcp->AppendBlock(0,(char*)&rceNum,sizeof(unsigned)); + cpcp->AppendBlock(0,(char*)data,12*sizeof(unsigned)); + dev->AddEvent(cpc); + CosmicEventReceiver::receiveEvent(ev); //this function adds event to monitoring GUI + //std::cout<<"Done Data from link 8"<<std::endl; + return 0; + } + bool marker=(rlink>>MARKERPOS)&0x1; + int rceIndex = m_rceToIndex[rceNum]; + + m_hits=0; + int module = m_linkToIndex[rceNum][link]; //map link/rce onto module index + // if synching throw away fragments until we find the marker + if(m_modsynch[module]==true) { + + if (marker==false){ + if(m_print>0){ + if(link==TDCREADOUT)std::cout<<"Ignoring TDC link: "<<std::endl; + else { + std::cout<<"Ignoring Link "<<link<<std::endl; + } + m_print--; + } + m_tossed[module]++; + return 0; + } + m_modsynch[module]=false; + //if(marker)std::cout<<"Markerevent"<<std::endl; + std::cout<<"Tossed "<<m_tossed[module]<<" fragments for link "<<link<<" , RCE "<<rceNum<<std::endl; + } + if (link==TDCREADOUT){ + //std::cout<<"Data from link TDCREADOUT"<<std::endl; + // unsigned trgtime1=data[3]; + // unsigned trgtime2=data[4]; + // unsigned long long trgtime=trgtime1; + // trgtime=(trgtime<<32) | trgtime2; + + // std::cout<<"Trigger time: "<<std::hex<<trgtime<<std::dec<<std::endl; + //std::cout<<"Link TDCREADOUT L1id "<<((data[0]>>24)&0xf)<<std::endl; + unsigned udata[32]; + if(size!=32)std::cout<<"Bad TDC fragment size "<<size<<std::endl; + for(int i=0;i<32;i+=4) + udata[i/4]=data[i]<<24|data[i+1]<<16|data[i+2]<<8|data[i+3]; + bool success=m_iterator->setTdcData(udata,rceIndex); + int tluid=(udata[7]&0xffff); + //std::cout<<"TLU trigger id:"<<(udata[7]&0xffff)<<std::endl; +// std::cout<<"Trigger word:"<<((udata[7]&0xff0000)>>16)<<std::endl; + //unsigned fifothresh=(udata[7]&0xf000000)>>24; + //if(fifothresh)std::cout<<std::hex<<fifothresh<<std::dec<<std::endl; + m_event++; + //std::cout<<"Hitbus word:"<<hitbusword<<std::endl; + //unsigned backpressure=(udata[7]&0x1000000); + //unsigned fifofull=(udata[7]&0x2000000); + //if(backpressure)std::cout<<"Backpressure"<<std::endl; + //if(fifofull)std::cout<<"Fifo full"<<std::endl; +// unsigned hitbus1=udata[1]; +// unsigned hitbus2=udata[2]; +// if(hitbus1!=0){ +// std::cout<<"Hitbus TA:"<<std::endl; +// printhitbus(hitbus1); +// } +// if(hitbus2!=0){ +// std::cout<<"Hitbus TB:"<<std::endl; +// printhitbus(hitbus2); +// } + unsigned trgtime1=udata[3]; + unsigned trgtime2=udata[4]; + unsigned long long trgtime=trgtime1; + trgtime=(trgtime<<32) | trgtime2; + //std::cout<<"Trigger time stamp: "<<trgtime<<std::endl; + unsigned deadtime1=udata[5]; + unsigned deadtime2=udata[6]; + unsigned long long deadtime=deadtime1; + deadtime=(deadtime<<32) | deadtime2; + //std::cout<<"Deadtime: "<<deadtime<<std::endl; + + if(success==false){ + resynch(); + return 1; + } + }else{ + if(module>=m_nModules){ + std::cout<<"Bad link "<<link<<std::endl; + return 0; + } + unsigned parsed[16384]; + int parsedsize=0; + int nl1a; + if(m_swap[module]==true){ + unsigned swapped[16384]; + for(int i=0;i<size;i+=4){ + swapped[i/4]=data[i]<<24|data[i+1]<<16|data[i+2]<<8|data[i+3]; + } + m_formatter[module]->decode(swapped,size/sizeof(unsigned),parsed, parsedsize, nl1a); + }else{ + m_formatter[module]->decode((unsigned*)&data[0],size/sizeof(unsigned),parsed, parsedsize, nl1a); + } + unsigned int l1id=99; + int ntrg=0; + int bxfirst=-666; + int bxlast=-777; + int start=0; + //std::cout<<"New event"<<std::endl; + do{ //possibly we must split the data because it belongs to 2 triggers. + //if(start!=0)std::cout<<"Newstart "<<start<<" "<<m_iterator->nEvents()+1<<std::endl; + + int newstart=processModuleData(&parsed[start],parsedsize-start,link, module, l1id, bxfirst, bxlast, ntrg); + //if(m_hits>0) std::cout<<"Link "<<link<<" had "<<m_hits<<" hits."<<std::endl; + //std::cout<<"Data from module "<<module<<" link="<<link<<" with l1id="<<l1id<<" bxfirst="<<bxfirst<<" ntrg="<<ntrg<<" bxlast="<<bxlast<<std::endl; + //bool isdut=((link<9) || (m_file==0)); //all data is DUT when running as a producer (m_file==0) + bool isdut=true; //not using CTEL for now. + if(ntrg==0){ + std::cout<<"Inserting duplicate header for data-only frame on module RCE="<<rceNum<<" outlink="<<link<<std::endl; + FormattedRecord fr(FormattedRecord::HEADER); + fr.setL1id(l1id); + fr.setBxid(bxfirst); + unsigned hd=fr.getWord(); + m_iterator->addPixelData(module,l1id, bxfirst, bxlast, ntrg, rceIndex, isdut, &hd,1); + } + bool success=m_iterator->addPixelData(module,l1id, bxfirst, bxlast, ntrg, rceIndex, isdut, &parsed[start],newstart); + if(success==false){ + resynch(); + return 1; + } + start+=newstart; + }while(start<parsedsize); + } + return 0; +} + +int CosmicOfflineDataProc::processModuleData(unsigned* udata,int size, int link, int module, + unsigned& l1id, int& bxfirst, int& bxlast, int &ntrg){ + FormattedRecord* data=(FormattedRecord*)udata; + if(!data[0].isHeader()){ + std::cout<<"Module data not starting with 0x2xxxxxxx. Using old header info."<<std::endl; + ntrg=0; + bxfirst=m_bxfirst[module]; + bxlast=bxfirst; + l1id=m_l1id[module]; + }else{ + ntrg=1; + data[0].setLink(link); + bxfirst=data[0].getBxid()&0xff; + bxlast=bxfirst; + l1id=data[0].getL1id()&0xf; + m_l1id[module]=l1id; + m_bxfirst[module]=bxfirst; + //int bx=data[0].getBxid(); + //std::cout<<"Link "<<link<<" l1a "<<l1id<<" bx "<<bx<<std::endl; + } + //std::cout<<"Link "<<link<<" l1a "<<l1id<<" bxfirst "<<m_bxfirst[module]<<std::endl; + unsigned l1a; + for (int i=1;i<size;i++){ + if (data[i].isHeader()){ + l1a=data[i].getL1id()&0xf; + if(l1id!=l1a)return i; + data[i].setLink(link); + bxlast=data[i].getBxid()&0xff; + //std::cout<<"Link "<<link<<" l1a "<<l1a<<" bx "<<bxlast<<std::endl; + ntrg++; + } + //}else if(data[i]&0x80000000){ + // //m_hits++; + // int chip=(data[i]>>24)&0xf; + // int tot=(data[i]>>16)&0xff; + // int col=(data[i]>>8)&0x1f; + // int row=data[i]&0xff; + // int tr=bx-bxfirst; + // if (tr<0)tr+=256; + //if(row<156 && tot > 6) + // std::cout<<"Link "<<link<<" Trigger "<<tr<<" Chip "<<chip<<" row "<<row<<" col "<<col<<" tot "<<tot<<std::endl; + // } + } + return size; +} + + +void CosmicOfflineDataProc::resynch(){ + std::cout<<"Resynchronizing"<<std::endl; + // set synch flags for everybody + for (int i=0;i<64;i++)m_modsynch[i]=true; + for (int i=0;i<64;i++)m_tossed[i]=0; + m_print=0; + m_iterator->resynch(); + m_controller->resynch();//pause run, reset counters, post markers +} + +CosmicOfflineDataProc::CosmicOfflineDataProc(IPCController* controller, + std::vector<ModuleInfo*> modinfo, + std::vector<int> rcesAll, + unsigned runnum, + const std::string& outputFile, + bool writeEudet, bool writeRaw) + : m_runNo(runnum), m_event(0), m_hitbus(0), m_controller(controller), m_sec(0xffffffff), m_chunk(0) +{ + + m_nModules=modinfo.size(); + m_l1id=new int[m_nModules]; + m_bxfirst=new int[m_nModules]; + m_swap=new int[m_nModules]; + m_rceToIndex=new int[MAX_RCES]; + m_linkToIndex=new int*[MAX_RCES]; + for(int i=0;i<MAX_RCES;i++)m_linkToIndex[i]=0; + for(int i=0;i<m_nModules;i++){ + m_l1id[i]=0; + m_bxfirst[i]=0; + } + + //make a vector only of the *unique* rce numbers + std::vector<int> rces; + for(unsigned imod=0; imod<rcesAll.size(); imod++){ + int rceNum=rcesAll[imod]; + bool newRCE=true; + + for(unsigned jrce=0; jrce<rces.size(); jrce++){ + if(rces[jrce] == rceNum){ + newRCE=false; + break; + } + } + if(newRCE){ + rces.push_back(rceNum); + } + + } + + unsigned nRces=rces.size(); + for(unsigned i=0; i<nRces; i++){ + m_rceToIndex[rces[i]] = i; + m_linkToIndex[rces[i]]=new int[MAX_LINKS]; + m_linkToIndex[rces[i]][TDCREADOUT]=m_nModules+i; + } + for (int i=0;i<m_nModules;i++){ + m_linkToIndex[rcesAll[i]][modinfo[i]->getOutLink()]=i; + } + + for (int i=0;i<m_nModules;i++){ + m_formatter[i]=modinfo[i]->getFormatter(); + if(std::string(m_formatter[i]->getName())=="JJ" || + std::string(m_formatter[i]->getName())=="AFPHPTDC"){ // need to byte-swap + m_swap[i]=true; + }else{ + m_swap[i]=false; + } + } + for(int i=0;i<64;i++){ + m_modsynch[i] = false; + m_tossed[i] = 0; + } + m_nfrag=0; + m_print=0; + bool monitor=false; + m_pfile=0; + m_file=0; + if(outputFile!=""){ + monitor=true; + if(writeEudet==true){ + m_file=new eudaq::FileSerializer(outputFile.c_str()); + eudaq::DetectorEvent dev(m_runNo,0,0); + dev.SetFlags(eudaq::Event::FLAG_BORE); + dev.SetTag("CONFIG", "Name = Test"); + eudaq::RawDataEvent *revc=new eudaq::RawDataEvent(eudaq::RawDataEvent::BORE("CTEL",m_runNo)); + counted_ptr<eudaq::Event> cpc(revc); + dev.AddEvent(cpc); + eudaq::RawDataEvent *revd=new eudaq::RawDataEvent(eudaq::RawDataEvent::BORE("APIX-CT",m_runNo)); + counted_ptr<eudaq::Event> cpd(revd); + dev.AddEvent(cpd); + dev.Serialize(*m_file); + } + if(writeRaw==true){ + std::cout<<"Run number "<<m_runNo<<std::endl; + std::string pfname=outputFile.substr(0,outputFile.size()-4)+"_000000.dat"; + m_filename=outputFile.substr(0,outputFile.size()-4); + m_pfile=new std::ofstream(pfname.c_str(), std::ios::binary); + unsigned utime=(unsigned)time(0); + m_pfile->write((char*)&utime, 4); + m_pfile->write((char*)&nRces, 4); + } + } + // create the event iterator class which does all the work + m_iterator=new CosmicEventIterator(monitor, m_file, m_pfile, m_runNo,m_nModules,rces); + + +} + +CosmicOfflineDataProc::~CosmicOfflineDataProc(){ + m_iterator->flushEvents(); + std::cout<<"Number of fragments processed: "<<m_nfrag<<std::endl; + //if(m_event>0)std::cout<<"Hitbus efficiency in the previous run: "<<(float)m_hitbus/(float)m_event<<std::endl; + if(m_pfile!=0){ + m_pfile->close(); + delete m_pfile; + } + if(m_file!=0){ + int eventnumber=m_iterator->nEvents()+1; + eudaq::DetectorEvent dev(m_runNo,eventnumber,0); + dev.SetFlags(eudaq::Event::FLAG_EORE); + eudaq::RawDataEvent *revc=new eudaq::RawDataEvent(eudaq::RawDataEvent::EORE("CTEL",m_runNo,eventnumber)); + counted_ptr<eudaq::Event> cpc(revc); + dev.AddEvent(cpc); + eudaq::RawDataEvent *revd=new eudaq::RawDataEvent(eudaq::RawDataEvent::EORE("APIX-CT",m_runNo,eventnumber)); + counted_ptr<eudaq::Event> cpd(revd); + dev.AddEvent(cpd); + dev.Serialize(*m_file); + delete m_file; + } + std::cout<<"close file called"<<std::endl; + delete m_iterator; + delete [] m_l1id; + delete [] m_bxfirst; + delete [] m_swap; + delete [] m_rceToIndex; + for(int i=0;i<MAX_RCES;i++)delete [] m_linkToIndex[i]; + delete [] m_linkToIndex; +} + +inline void CosmicOfflineDataProc::switchfile(){ + m_chunk++; + m_pfile->close(); + char chunknum[16]; + sprintf(chunknum, "_%06d.dat", m_chunk); + m_pfile->open((m_filename+chunknum).c_str(),std::ios::binary); + unsigned utime=(unsigned)time(0); + m_pfile->write((char*)&utime, 4); +} diff --git a/rce/rcecalib/server/CosmicOfflineDataProc.hh b/rce/rcecalib/server/CosmicOfflineDataProc.hh new file mode 100644 index 0000000000000000000000000000000000000000..54d70e13012f0ed5ef33f85fdeac3d1e8fdc6341 --- /dev/null +++ b/rce/rcecalib/server/CosmicOfflineDataProc.hh @@ -0,0 +1,57 @@ +#ifndef COSMICOFFLINEDATAPROC_HH +#define COSMICOFFLINEDATAPROC_HH + +#include <boost/property_tree/ptree_fwd.hpp> +#include "rcecalib/eudaq/FileSerializer.hh" +#include <list> +#include <string> +#include <vector> +#include <fstream> +#include <map> + +class CosmicEvent; +class CosmicEventIterator; +class AbsFormatter; +class IPCController; +class ModuleInfo; + +class CosmicOfflineDataProc{ +public: + CosmicOfflineDataProc(IPCController* controller, + std::vector<ModuleInfo*> modinfo, + std::vector<int> rceAll, + unsigned runnum, const std::string& outputFile, bool writeEudet, bool writeRaw); + virtual ~CosmicOfflineDataProc(); + int processData(unsigned short link, unsigned char* data, int size); +protected: + void resynch(); + inline int processModuleData(unsigned* data,int size, int link, int module, unsigned& l1id, int& bxfirst, int &bxlast, int &ntrg); + void switchfile(); + enum constants{MAX_RCES=100, MAX_LINKS=32}; + + int m_nModules; + bool m_modsynch[64]; + int* m_l1id; + int* m_bxfirst; + int* m_swap; + int **m_linkToIndex; + int *m_rceToIndex; + int m_tossed[64]; + unsigned m_runNo; + eudaq::FileSerializer *m_file; + std::ofstream* m_pfile; + //std::ofstream m_file; + int m_nfrag; + CosmicEventIterator* m_iterator; + int m_print; + int m_hits; + int m_event; + int m_hitbus; + AbsFormatter* m_formatter[64]; + IPCController* m_controller; + unsigned m_sec; + unsigned m_chunk; + std::string m_filename; +}; + +#endif diff --git a/rce/rcecalib/server/DataExporter.cc b/rce/rcecalib/server/DataExporter.cc new file mode 100644 index 0000000000000000000000000000000000000000..cee067ef1f84bbef8280ccd449bd75027f2625d9 --- /dev/null +++ b/rce/rcecalib/server/DataExporter.cc @@ -0,0 +1,117 @@ +#include "rcecalib/server/DataExporter.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "stdlib.h" +#include "TFile.h" +#include "TKey.h" +#include "TROOT.h" +#include "TClass.h" +#include <iostream> +#include <sys/stat.h> +#include <boost/regex.hpp> + +const std::string DataExporter::basedir=getExportBaseDir(); + +const std::string DataExporter::getExportBaseDir(){ + char * var = getenv( "EXPORT_DIR" ); + if(var) return var; + char *home=getenv("HOME"); + return std::string(home)+"/export"; +} + +void DataExporter::exportData(std::string &runname, std::string &topconfigname, std::string &rcdir, TFile* file, TFile* anfile){ + struct stat stFileInfo; + int intStat; + intStat = stat(basedir.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Export directory "<<basedir<<" does not exist. Not exporting data."<<std::endl; + return; + } + std::map<std::string, std::map<int, int> > ids; + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(!m_cfg[i]->isIncluded())continue; + std::string modname="M"; + modname+=m_cfg[i]->getModuleId(); + std::string moddir=basedir+"/"+modname; + intStat = stat(moddir.c_str(),&stFileInfo); + if(intStat != 0) mkdir (moddir.c_str(),0777); + std::string configdir=moddir+"/configs"; + intStat = stat(configdir.c_str(),&stFileInfo); + if(intStat != 0) mkdir (configdir.c_str(),0777); + std::string datadir=moddir+"/data"; + intStat = stat(datadir.c_str(),&stFileInfo); + if(intStat != 0) mkdir (datadir.c_str(),0777); + // Copy config + char cmd[512]; + sprintf(cmd,"cp %s/globalconfig.txt %s/globalconfig_%s.txt", rcdir.c_str(), configdir.c_str(), runname.c_str()); + system (cmd); + sprintf(cmd,"cp %s/%s %s/%s", rcdir.c_str(), topconfigname.c_str(), configdir.c_str(), topconfigname.c_str()); + system (cmd); + sprintf(cmd,"cp %s/scanconfig_%s.txt %s/scanconfig_%s.txt", rcdir.c_str(), runname.c_str(), configdir.c_str(), runname.c_str()); + system (cmd); + m_cfg[i]->copyConfig(configdir.c_str()); + int feid=m_cfg[i]->getId(); + ids[modname][feid]=1; + } + for (std::map <std::string, std::map<int, int> >::const_iterator it = ids.begin(); it != ids.end(); ++it){ + std::string modname=it->first; + std::string datadir=basedir+"/"+modname+"/data/"; + std::string hfilename=modname+"_"+runname+".root"; + TFile hfile((datadir+"/"+hfilename).c_str(), "recreate", file->GetTitle()); + CopyFile(file->GetName(), it->second, "histos"); + if(anfile!=0)CopyFile(anfile->GetName(), it->second, "analysis"); + } +} + +void DataExporter::CopyDir(TDirectory *source, const std::map<int, int> &ids, const char* dirname) { + //copy all objects and subdirs of directory source as a subdir of the current directory + TDirectory *savdir = gDirectory; + TDirectory *adir = savdir->mkdir(dirname); + adir->cd(); + //loop on all entries of this directory + TKey *key; + TIter nextkey(source->GetListOfKeys()); + while ((key = (TKey*)nextkey())) { + const char *classname = key->GetClassName(); + TClass *cl = gROOT->GetClass(classname); + if (!cl) continue; + if (cl->InheritsFrom(TDirectory::Class())) { + source->cd(key->GetName()); + TDirectory *subdir = gDirectory; + adir->cd(); + CopyDir(subdir, ids, subdir->GetName()); + adir->cd(); + } else { + source->cd(); + boost::regex re("Mod_(\\d+)"); + std::string name(key->GetName()); + boost::cmatch matches; + if(boost::regex_search(name.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + int id=strtol(match.c_str(),0,10); + if( ids.find(id)!=ids.end()){ + TObject *obj = key->ReadObj(); + adir->cd(); + obj->Write(); + delete obj; + } + } + } + } + adir->SaveSelf(kTRUE); + savdir->cd(); +} +void DataExporter::CopyFile(const char *fname, const std::map<int, int> &ids, const char* topdir) { + //Copy all objects and subdirs of file fname as a subdir of the current directory + TDirectory *target = gDirectory; + TFile *f = TFile::Open(fname); + if (!f || f->IsZombie()) { + printf("Cannot copy file: %s\n",fname); + target->cd(); + return; + } + target->cd(); + CopyDir(f, ids, topdir); + delete f; + target->cd(); +} diff --git a/rce/rcecalib/server/DataExporter.hh b/rce/rcecalib/server/DataExporter.hh new file mode 100644 index 0000000000000000000000000000000000000000..00514577ecaac22fbce774c6ab7ba5d213fee612 --- /dev/null +++ b/rce/rcecalib/server/DataExporter.hh @@ -0,0 +1,23 @@ +#ifndef DATAEXPORTER_HH +#define DATAEXPORTER_HH + +class TFile; +class ConfigGui; +class TDirectory; +#include <string> +#include <map> + +class DataExporter{ +public: + DataExporter(ConfigGui** cfg): m_cfg(cfg){} + ~DataExporter(){} + void exportData(std::string &runname, std::string &topconfigname, std::string &rcdir, TFile* file, TFile* anfile); +private: + void CopyDir(TDirectory *source, const std::map<int, int> &ids, const char* topdir); + void CopyFile(const char *fname, const std::map<int, int> &ids, const char* dirname); + static const std::string getExportBaseDir(); + ConfigGui** m_cfg; + static const std::string basedir; +}; + +#endif diff --git a/rce/rcecalib/server/EthPrimitive.cc b/rce/rcecalib/server/EthPrimitive.cc new file mode 100644 index 0000000000000000000000000000000000000000..74a7f16c7e82425b0f18d03af0a95c87b2e8c9fa --- /dev/null +++ b/rce/rcecalib/server/EthPrimitive.cc @@ -0,0 +1,65 @@ +#include "rcecalib/server/EthPrimitive.hh" +#include <unistd.h> +#include <stdio.h> +#include <assert.h> +#include <sys/uio.h> +#include <iostream> +#include <string.h> +#include <new> + + +EthPrimitive::EthPrimitive(unsigned short port){ + RceNet::IpAddress src(port); +#ifdef RCE_V2 + m_socket.bind(src); + m_socket.listen(); +#else + m_socket.listen(src); +#endif + RceNet::IpAddress name; + m_socket.getname(name); + printf("TCP upload socket %d bound to port %d\n", m_socket.socket(), name.port()); +} + + +const char* EthPrimitive::receiveCommand() { + const unsigned buflen=1024; + static char buffer[buflen]; + int connfd = m_socket.accept(); + m_connection=new RceNet::Socket(connfd); + int bytes = m_connection->recv(buffer, buflen); + assert(bytes<(int)buflen); + buffer[bytes]=0; + while(buffer[bytes-1]==' ' && bytes>0)buffer[--bytes]=0; + std::cout<<"COMMAND: "<<buffer<<std::endl; + return buffer; +} +void EthPrimitive::reply(const char* msg){ + assert(m_connection!=0); + m_connection->send((void*)msg, strlen(msg) ); + delete m_connection; + m_connection=0; +} +void EthPrimitive::reply(char* buffer, int len){ + assert(m_connection!=0); + m_connection->send((void*)buffer, len ); + delete m_connection; + m_connection=0; +} + +const char* EthPrimitive::receiveModule(unsigned char *buffer, int size) { + assert(m_connection==0); + int connfd = m_socket.accept(); + m_connection=new RceNet::Socket(connfd); + int remaining = size; + int offset = 0; + while( remaining > 0 ) { + int bytes = m_connection->recv(buffer + offset, remaining); + if(bytes<0)break; + offset += bytes; + remaining -= bytes; + } + if(remaining!=0)return "Download failed."; + return "OK"; +} + diff --git a/rce/rcecalib/server/EthPrimitive.hh b/rce/rcecalib/server/EthPrimitive.hh new file mode 100644 index 0000000000000000000000000000000000000000..1bd6617b730afa72796393b6b11dff8e3c67ca4a --- /dev/null +++ b/rce/rcecalib/server/EthPrimitive.hh @@ -0,0 +1,33 @@ +#ifndef ETH_PRIMITIVE_H +#define ETH_PRIMITIVE_H + +#define PACKETSIZE 300 +#include <sys/types.h> +#include "sys/socket.h" +#include <netinet/in.h> +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, net, SocketTcp.hh) +#include DAT_PUBLIC( oldPpi, net, IpAddress.hh) +#include DAT_PUBLIC( oldPpi, net, IpAddress.hh) +#else +#include "rce/net/SocketTcp.hh" +#include "rce/net/IpAddress.hh" +#include "rce/service/Procedure.hh" +#endif +#include "namespace_aliases.hh" +class CmdDecoder; + +class EthPrimitive { + public: + EthPrimitive(unsigned short port); + const char* receiveCommand(); + const char* receiveModule(unsigned char* buffer, int size); + void reply(const char* msg); + void reply(char* buffer, int len); + private: + RceNet::Socket *m_connection; + RceNet::SocketTcp m_socket; +}; + +#endif diff --git a/rce/rcecalib/server/FEI4AConfigFile.cc b/rce/rcecalib/server/FEI4AConfigFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..ff41846098a59911fde557183b1f46782ee306d6 --- /dev/null +++ b/rce/rcecalib/server/FEI4AConfigFile.cc @@ -0,0 +1,737 @@ +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/util/exceptions.hh" +#include <boost/algorithm/string.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <sys/stat.h> + +std::string FEI4AConfigFile::getFullPath(std::string relPath){ + std::string newPath = relPath, basePath=m_moduleCfgFilePath, testName; + unsigned int pos; + // skip config file-name part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // skip "config" part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // now skip module part of base path, but keep last "/" + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos+1,basePath.length()-pos); + else basePath=""; + // then add relative path of DAC or mask file + newPath = basePath + newPath; + return newPath; +} + +FEI4AConfigFile::~FEI4AConfigFile(){} + +unsigned short FEI4AConfigFile::lookupToUShort(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + unsigned short val; + int success=convertToUShort(vals, val); + if(success==false){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} +float FEI4AConfigFile::lookupToFloat(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + float val; + char* end; + val=strtof(vals.c_str(), &end); + if(end-vals.c_str()!=(int)vals.size()){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} + +int FEI4AConfigFile::convertToUShort(std::string par, unsigned short& val){ + char* end; + val=strtoul(par.c_str(), &end, 0); + if(end-par.c_str()!=(int)par.size()){ + return 0; + } + if((val&0xffff0000)!=0){ + std::cout<<"Value "<<val<<" too large."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return 1; +} + + +void FEI4AConfigFile::setupMaskBit(const long int bit, ipc::PixelFEI4AConfig* cfg, std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + unsigned short val; + int success=convertToUShort(m_params[par], val); + //file + if(success==false){ + std::string fullpath=getFullPath(m_params[par]); + std::ifstream* maskfile=new std::ifstream(fullpath.c_str()); + if(!maskfile->good()){ + std::cout<<"Cannot open file with name "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string inpline; + unsigned short row=0; + while(true){ + getline(*maskfile, inpline); + if(maskfile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" -"), boost::token_compress_on ); + if(splitVec.size()!=17){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + int success=convertToUShort(splitVec[0], val); + if(success!=true || val!=++row){//check and increment row number + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string oneline; + for(int i=1;i<17;i++)oneline+=splitVec[i]; //concatenate everyting. + if(oneline.size()!=(unsigned)ipc::IPC_N_I4_PIXEL_COLUMNS) throw rcecalib::Config_File_Error(ERS_HERE); + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + if(oneline[i]=='1')cfg->FEMasks[i][row-1]|=1<<bit; + } + } + } + if(row!=ipc::IPC_N_I4_PIXEL_ROWS) throw rcecalib::Config_File_Error(ERS_HERE); + delete maskfile; + }else{ + // left are the cases all 0 and all 1 + if(val!=0 && val!=1) throw rcecalib::Config_File_Error(ERS_HERE); + for (int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + cfg->FEMasks[i][j]|=val<<bit; + } + } + } +} + + +void FEI4AConfigFile::setupDAC(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + unsigned short val; + int success=convertToUShort(m_params[par], val); + //file + if(success==false){ + std::string fullpath=getFullPath(m_params[par]); + std::ifstream* dacfile=new std::ifstream(fullpath.c_str()); + if(!dacfile->good()){ + std::cout<<"Cannot open file with name "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string inpline; + unsigned short hrow=1; + while(true){ + getline(*dacfile, inpline); + if(dacfile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" "), boost::token_compress_on ); + if(splitVec.size()!=41){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + success=convertToUShort(splitVec[0].substr(0,splitVec[0].size()-1),val); + if(success!=true || val!=++hrow/2){//check and increment row number + throw rcecalib::Config_File_Error(ERS_HERE); + } + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS/2;i++){ + success=convertToUShort(splitVec[i+1], val); + if(!success) throw rcecalib::Config_File_Error(ERS_HERE); + trim[i+(hrow%2)*ipc::IPC_N_I4_PIXEL_COLUMNS/2][hrow/2-1]=val; + } + } + } + if(hrow/2!=ipc::IPC_N_I4_PIXEL_ROWS) throw rcecalib::Config_File_Error(ERS_HERE); + delete dacfile; + }else{ + // left are the cases where all settings are identical. + for (int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + trim[i][j]=val; + } + } + } +} + +void FEI4AConfigFile::writeModuleConfig(ipc::PixelFEI4AConfig* config, const std::string &base, const std::string &confdir, + const std::string &configname, const std::string &key){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(base.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<" does not exist. Not writing config file"<<std::endl; + return; + } + intStat = stat((base+"/"+confdir).c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + //std::cout<<"Directory "<<base<<"/"<<confdir<<" does not exist. Creating."<<std::endl; + mkdir ((base+"/"+confdir).c_str(),0777); + mkdir ((base+"/"+confdir+"/configs").c_str(),0777); + mkdir ((base+"/"+confdir+"/masks").c_str(),0777); + mkdir ((base+"/"+confdir+"/tdacs").c_str(),0777); + mkdir ((base+"/"+confdir+"/fdacs").c_str(),0777); + } + std::string cfgname=configname; + if(key.size()!=0)cfgname+="__"+key; + std::string fullpath=base+"/"+confdir+"/configs/"+cfgname+".cfg"; + std::ofstream cfgfile(fullpath.c_str()); + cfgfile<<"# FEI4A Configuration"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Module name"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"ModuleID\t\t"<<config->idStr<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Geographical address"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"Address\t\t\t"<<(unsigned)config->FECommand.address<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Global register"<<std::endl; + cfgfile<<std::endl; + //Global register + ipc::PixelFEI4AGlobal* cfg=&config->FEGlobal; + cfgfile<<"TrigCnt\t\t\t"<<cfg->TrigCnt<<std::endl; + cfgfile<<"Conf_AddrEnable\t\t"<<cfg->Conf_AddrEnable <<std::endl; + cfgfile<<"Reg2Spare\t\t"<<cfg->Reg2Spare <<std::endl; + cfgfile<<"ErrMask0\t\t"<<"0x"<<std::hex<<cfg->ErrMask0 <<std::dec<<std::endl; + cfgfile<<"ErrMask1\t\t"<<"0x"<<std::hex<<cfg->ErrMask1 <<std::dec<<std::endl; + cfgfile<<"PrmpVbpRight\t\t"<< cfg->PrmpVbpRight <<std::endl; + cfgfile<<"Vthin\t\t\t"<<cfg->Vthin <<std::endl; + cfgfile<<"DisVbn_CPPM\t\t"<<cfg->DisVbn_CPPM <<std::endl; + cfgfile<<"PrmpVbp\t\t\t"<<cfg->PrmpVbp <<std::endl; + cfgfile<<"TdacVbp\t\t\t"<< cfg->TdacVbp <<std::endl; + cfgfile<<"DisVbn\t\t\t"<<cfg->DisVbn <<std::endl; + cfgfile<<"Amp2Vbn\t\t\t"<<cfg->Amp2Vbn <<std::endl; + cfgfile<<"Amp2VbpFol\t\t"<<cfg->Amp2VbpFol <<std::endl; + cfgfile<<"PrmpVbpTop\t\t"<<cfg->PrmpVbpTop <<std::endl; + cfgfile<<"Amp2Vbp\t\t\t"<<cfg->Amp2Vbp <<std::endl; + cfgfile<<"FdacVbn\t\t\t"<<cfg->FdacVbn <<std::endl; + cfgfile<<"Amp2Vbpf\t\t"<<cfg->Amp2Vbpf <<std::endl; + cfgfile<<"PrmpVbnFol\t\t"<<cfg->PrmpVbnFol <<std::endl; + cfgfile<<"PrmpVbpLeft\t\t"<<cfg->PrmpVbpLeft <<std::endl; + cfgfile<<"PrmpVbpf\t\t"<<cfg->PrmpVbpf <<std::endl; + cfgfile<<"PrmpVbnLcc\t\t"<<cfg->PrmpVbnLcc <<std::endl; + cfgfile<<"Reg13Spare\t\t"<<cfg->Reg13Spare <<std::endl; + cfgfile<<"PxStrobes\t\t"<<cfg->PxStrobes <<std::endl; + cfgfile<<"S0\t\t\t"<<cfg->S0 <<std::endl; + cfgfile<<"S1\t\t\t"<<cfg->S1 <<std::endl; + cfgfile<<"LVDSDrvIref\t\t"<<cfg->LVDSDrvIref <<std::endl; + cfgfile<<"BonnDac\t\t\t"<<cfg->BonnDac <<std::endl; + cfgfile<<"PllIbias\t\t"<<cfg->PllIbias <<std::endl; + cfgfile<<"LVDSDrvVos\t\t"<<cfg->LVDSDrvVos <<std::endl; + cfgfile<<"TempSensBias\t\t"<<cfg->TempSensBias <<std::endl; + cfgfile<<"PllIcp\t\t\t"<<cfg->PllIcp <<std::endl; + cfgfile<<"Reg17Spare\t\t"<<cfg->Reg17Spare <<std::endl; + cfgfile<<"PlsrIdacRamp\t\t"<<cfg->PlsrIdacRamp <<std::endl; + cfgfile<<"Reg18Spare\t\t"<<cfg->Reg18Spare <<std::endl; + cfgfile<<"PlsrVgOPamp\t\t"<<cfg->PlsrVgOPamp <<std::endl; + cfgfile<<"PlsrDacBias\t\t"<<cfg->PlsrDacBias <<std::endl; + cfgfile<<"Reg19Spare\t\t"<<cfg->Reg19Spare <<std::endl; + cfgfile<<"Vthin_AltCoarse\t\t"<<cfg->Vthin_AltCoarse <<std::endl; + cfgfile<<"Vthin_AltFine\t\t"<<cfg->Vthin_AltFine <<std::endl; + cfgfile<<"PlsrDAC\t\t\t"<<cfg->PlsrDAC <<std::endl; + cfgfile<<"DIGHITIN_Sel\t\t"<<cfg->DIGHITIN_Sel <<std::endl; + cfgfile<<"DINJ_Override\t\t"<<cfg->DINJ_Override <<std::endl; + cfgfile<<"HITLD_In\t\t"<<cfg->HITLD_In <<std::endl; + cfgfile<<"Reg21Spare\t\t"<<cfg->Reg21Spare <<std::endl; + cfgfile<<"Reg22Spare2\t\t"<<cfg->Reg22Spare2 <<std::endl; + cfgfile<<"Colpr_Addr\t\t"<<cfg->Colpr_Addr <<std::endl; + cfgfile<<"Colpr_Mode\t\t"<<cfg->Colpr_Mode <<std::endl; + cfgfile<<"Reg22Spare1\t\t"<<cfg->Reg22Spare1 <<std::endl; + cfgfile<<"DisableColumnCnfg0\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg0 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg1\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg1 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg2\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg2 <<std::dec<<std::endl; + cfgfile<<"TrigLat\t\t\t"<< cfg->TrigLat <<std::endl; + cfgfile<<"CMDcnt\t\t\t"<<cfg->CMDcnt <<std::endl; + cfgfile<<"StopModeCnfg\t\t"<<cfg->StopModeCnfg <<std::endl; + cfgfile<<"HitDiscCnfg\t\t"<<cfg->HitDiscCnfg <<std::endl; + cfgfile<<"EN_PLL\t\t\t"<<cfg->EN_PLL <<std::endl; + cfgfile<<"Efuse_sense\t\t"<<cfg->Efuse_sense <<std::endl; + cfgfile<<"Stop_Clk\t\t"<<cfg->Stop_Clk <<std::endl; + cfgfile<<"ReadErrorReq\t\t"<<cfg->ReadErrorReq <<std::endl; + cfgfile<<"ReadSkipped\t\t"<<cfg->ReadSkipped <<std::endl; + cfgfile<<"Reg27Spare\t\t"<<cfg->Reg27Spare <<std::endl; + cfgfile<<"GateHitOr\t\t"<<cfg->GateHitOr <<std::endl; + cfgfile<<"CalEn\t\t\t"<<cfg->CalEn <<std::endl; + cfgfile<<"SR_clr\t\t\t"<<cfg->SR_clr <<std::endl; + cfgfile<<"Latch_en\t\t"<<cfg->Latch_en <<std::endl; + cfgfile<<"SR_Clock\t\t"<<cfg->SR_Clock <<std::endl; + cfgfile<<"LVDSDrvSet06\t\t"<<cfg->LVDSDrvSet06 <<std::endl; + cfgfile<<"Reg28Spare\t\t"<<cfg->Reg28Spare <<std::endl; + cfgfile<<"EN40M\t\t\t"<<cfg->EN40M <<std::endl; + cfgfile<<"EN80M\t\t\t"<<cfg->EN80M <<std::endl; + cfgfile<<"CLK0_S2\t\t\t"<<(cfg->CLK0 &0x1)<<std::endl; + cfgfile<<"CLK0_S1\t\t\t"<<((cfg->CLK0>>1)&0x1 )<<std::endl; + cfgfile<<"CLK0_S0\t\t\t"<<((cfg->CLK0>>2)&0x1 )<<std::endl; + cfgfile<<"CLK1_S2\t\t\t"<<(cfg->CLK1&0x1 )<<std::endl; + cfgfile<<"CLK1_S1\t\t\t"<<((cfg->CLK1>>1)&0x1 )<<std::endl; + cfgfile<<"CLK1_S0\t\t\t"<<((cfg->CLK1>>2)&0x1 )<<std::endl; + cfgfile<<"EN160M\t\t\t"<<cfg->EN160M <<std::endl; + cfgfile<<"EN320M\t\t\t"<<cfg->EN320M <<std::endl; + cfgfile<<"Reg29Spare1\t\t"<<cfg->Reg29Spare1 <<std::endl; + cfgfile<<"no8b10b\t\t\t"<<cfg->no8b10b <<std::endl; + cfgfile<<"Clk2OutCnfg\t\t"<<cfg->Clk2OutCnfg <<std::endl; + cfgfile<<"EmptyRecord\t\t"<<cfg->EmptyRecord <<std::endl; + cfgfile<<"Reg29Spare2\t\t"<<cfg->Reg29Spare2 <<std::endl; + cfgfile<<"LVDSDrvEn\t\t"<<cfg->LVDSDrvEn <<std::endl; + cfgfile<<"LVDSDrvSet30\t\t"<<cfg->LVDSDrvSet30 <<std::endl; + cfgfile<<"LVDSDrvSet12\t\t"<<cfg->LVDSDrvSet12 <<std::endl; + cfgfile<<"PlsrRiseUpTau\t\t"<<cfg->PlsrRiseUpTau <<std::endl; + cfgfile<<"PlsrPwr\t\t\t"<<cfg->PlsrPwr <<std::endl; + cfgfile<<"PlsrDelay\t\t"<<cfg->PlsrDelay <<std::endl; + cfgfile<<"ExtDigCalSW\t\t"<<cfg->ExtDigCalSW <<std::endl; + cfgfile<<"ExtAnaCalSW\t\t"<<cfg->ExtAnaCalSW <<std::endl; + cfgfile<<"Reg31Spare\t\t"<<cfg->Reg31Spare <<std::endl; + cfgfile<<"SELB0\t\t\t"<<cfg->SELB0 <<std::endl; + cfgfile<<"SELB1\t\t\t"<<cfg->SELB1 <<std::endl; + cfgfile<<"SELB2\t\t\t"<<cfg->SELB2 <<std::endl; + cfgfile<<"EfuseCref\t\t"<<cfg->EfuseCref <<std::endl; + cfgfile<<"EfuseVref\t\t"<<cfg->EfuseVref <<std::endl; + cfgfile<<"Chip_SN\t\t\t"<<cfg->Chip_SN <<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Pixel register"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"enable\t\t\t"<<confdir<<"/masks/enable_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"largeCap\t\t"<<confdir<<"/masks/largeCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"smallCap\t\t"<<confdir<<"/masks/smallCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"hitbus\t\t\t"<<confdir<<"/masks/hitbus_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"tdac\t\t\t"<<confdir<<"/tdacs/tdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"fdac\t\t\t"<<confdir<<"/fdacs/fdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Charge injection parameters"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"cinjLo\t\t\t"<<config->FECalib.cinjLo <<std::endl; + cfgfile<<"cinjHi\t\t\t"<<config->FECalib.cinjHi <<std::endl; + cfgfile<<"vcalCoeff[0]\t\t"<<config->FECalib.vcalCoeff[0] <<std::endl; + cfgfile<<"vcalCoeff[1]\t\t"<<config->FECalib.vcalCoeff[1] <<std::endl; + cfgfile<<"vcalCoeff[2]\t\t"<<config->FECalib.vcalCoeff[2] <<std::endl; + cfgfile<<"vcalCoeff[3]\t\t"<<config->FECalib.vcalCoeff[3] <<std::endl; + cfgfile<<"chargeCoeffClo\t\t"<<config->FECalib.chargeCoeffClo<<std::endl; + cfgfile<<"chargeCoeffChi\t\t"<<config->FECalib.chargeCoeffChi<<std::endl; + cfgfile<<"chargeOffsetClo\t\t"<<config->FECalib.chargeOffsetClo<<std::endl; + cfgfile<<"chargeOffsetChi\t\t"<<config->FECalib.chargeOffsetChi<<std::endl; + cfgfile<<"monleakCoeff\t\t"<<config->FECalib.monleakCoeff<<std::endl; + writeMaskFile(ipc::enable, config, base+"/"+confdir+"/masks/enable_"+cfgname+".dat"); + writeMaskFile(ipc::largeCap, config, base+"/"+confdir+"/masks/largeCap_"+cfgname+".dat"); + writeMaskFile(ipc::smallCap, config, base+"/"+confdir+"/masks/smallCap_"+cfgname+".dat"); + writeMaskFile(ipc::hitbus, config, base+"/"+confdir+"/masks/hitbus_"+cfgname+".dat"); + + writeDacFile(config->FETrims.dacThresholdTrim, base+"/"+confdir+"/tdacs/tdac_"+cfgname+".dat"); + writeDacFile(config->FETrims.dacFeedbackTrim, base+"/"+confdir+"/fdacs/fdac_"+cfgname+".dat"); + + + +} +void FEI4AConfigFile::writeMaskFile(const long int bit, ipc::PixelFEI4AConfig* config, const std::string &filename){ + std::ofstream maskfile(filename.c_str()); + maskfile<<"### 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76"<<std::endl; + char linenr[128]; + for(int i=1;i<=336;i++){ + sprintf(linenr,"%3d ", i); + maskfile<<linenr; + for (int j=1;j<=80;j++){ + maskfile<<((config->FEMasks[j-1][i-1]>>bit)&0x1); + if(j%10==0)maskfile<<" "; + else if(j%5==0)maskfile<<"-"; + } + maskfile<<std::endl; + } +} + +void FEI4AConfigFile::writeDacFile(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , const std::string filename){ + std::ofstream maskfile(filename.c_str()); + char line[512]; + for (int i=0;i<674;i++){ + if(i>1){ + sprintf(line, "%3d",i/2); + maskfile<<line; + if(i%2==0)maskfile<<"a "; + else maskfile<<"b "; + }else{ + maskfile<<"### "; + } + for (int j=1;j<=40;j++){ + if(i==0)sprintf(line, "%2d ",j); + else if(i==1)sprintf(line, "%2d ",j+40); + else { + int val = trim[j-1+(i%2)*ipc::IPC_N_I4_PIXEL_COLUMNS/2][i/2-1]; + sprintf(line, "%2d ",val); + } + maskfile<<line; + if(j%10==0)maskfile<<" "; + } + maskfile<<std::endl; + } +} + +void FEI4AConfigFile::readModuleConfig(ipc::PixelFEI4AConfig* config, std::string filename){ + //clear structure + char* ccfg=(char*)config; + for (unsigned int i=0;i<sizeof(ipc::PixelFEI4AConfig);i++)ccfg[i]=0; + //open file + m_moduleCfgFile=new std::ifstream(filename.c_str()); + if(!m_moduleCfgFile->good()){ + std::cout<<"Cannot open file with name "<<filename<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + m_moduleCfgFilePath = filename; + // parse config file + std::string inpline; + m_params.clear(); + while(true){ + getline(*m_moduleCfgFile, inpline); + if(m_moduleCfgFile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" \t"), boost::token_compress_on ); + if(splitVec.size()<2){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + m_params[splitVec[0]]=splitVec[1]; + } + } + // Module name + std::string modname=""; + if( m_params.find("ModuleID")==m_params.end()){ + std::cout<<"No Module ID defined."<<std::endl; + }else{ + modname=m_params["ModuleID"]; + } + sprintf((char*)config->idStr, "%s", modname.c_str()); + //Geographical address + config->FECommand.address=lookupToUShort("Address"); + //Global register + ipc::PixelFEI4AGlobal* cfg=&config->FEGlobal; + cfg->TrigCnt = lookupToUShort("TrigCnt"); + cfg->Conf_AddrEnable = lookupToUShort("Conf_AddrEnable"); + cfg->Reg2Spare = lookupToUShort("Reg2Spare"); + cfg->ErrMask0 = lookupToUShort("ErrMask0"); + cfg->ErrMask1 = lookupToUShort("ErrMask1"); + cfg->PrmpVbpRight = lookupToUShort("PrmpVbpRight"); + cfg->Vthin = lookupToUShort("Vthin"); + cfg->DisVbn_CPPM = lookupToUShort("DisVbn_CPPM"); + cfg->PrmpVbp = lookupToUShort("PrmpVbp"); + cfg->TdacVbp = lookupToUShort("TdacVbp"); + cfg->DisVbn = lookupToUShort("DisVbn"); + cfg->Amp2Vbn = lookupToUShort("Amp2Vbn"); + cfg->Amp2VbpFol = lookupToUShort("Amp2VbpFol"); + cfg->PrmpVbpTop = lookupToUShort("PrmpVbpTop"); + cfg->Amp2Vbp = lookupToUShort("Amp2Vbp"); + cfg->FdacVbn = lookupToUShort("FdacVbn"); + cfg->Amp2Vbpf = lookupToUShort("Amp2Vbpf"); + cfg->PrmpVbnFol = lookupToUShort("PrmpVbnFol"); + cfg->PrmpVbpLeft = lookupToUShort("PrmpVbpLeft"); + cfg->PrmpVbpf = lookupToUShort("PrmpVbpf"); + cfg->PrmpVbnLcc = lookupToUShort("PrmpVbnLcc"); + cfg->Reg13Spare = lookupToUShort("Reg13Spare"); + cfg->PxStrobes = lookupToUShort("PxStrobes"); + cfg->S0 = lookupToUShort("S0"); + cfg->S1 = lookupToUShort("S1"); + cfg->LVDSDrvIref = lookupToUShort("LVDSDrvIref"); + cfg->BonnDac = lookupToUShort("BonnDac"); + cfg->PllIbias = lookupToUShort("PllIbias"); + cfg->LVDSDrvVos = lookupToUShort("LVDSDrvVos"); + cfg->TempSensBias = lookupToUShort("TempSensBias"); + cfg->PllIcp = lookupToUShort("PllIcp"); + cfg->Reg17Spare = lookupToUShort("Reg17Spare"); + cfg->PlsrIdacRamp = lookupToUShort("PlsrIdacRamp"); + cfg->Reg18Spare = lookupToUShort("Reg18Spare"); + cfg->PlsrVgOPamp = lookupToUShort("PlsrVgOPamp"); + cfg->PlsrDacBias = lookupToUShort("PlsrDacBias"); + cfg->Reg19Spare = lookupToUShort("Reg19Spare"); + cfg->Vthin_AltCoarse = lookupToUShort("Vthin_AltCoarse"); + cfg->Vthin_AltFine = lookupToUShort("Vthin_AltFine"); + cfg->PlsrDAC = lookupToUShort("PlsrDAC"); + cfg->DIGHITIN_Sel = lookupToUShort("DIGHITIN_Sel"); + cfg->DINJ_Override = lookupToUShort("DINJ_Override"); + cfg->HITLD_In = lookupToUShort("HITLD_In"); + cfg->Reg21Spare = lookupToUShort("Reg21Spare"); + cfg->Reg22Spare2 = lookupToUShort("Reg22Spare2"); + cfg->Colpr_Addr = lookupToUShort("Colpr_Addr"); + cfg->Colpr_Mode = lookupToUShort("Colpr_Mode"); + cfg->Reg22Spare1 = lookupToUShort("Reg22Spare1"); + cfg->DisableColumnCnfg0 = lookupToUShort("DisableColumnCnfg0"); + cfg->DisableColumnCnfg1 = lookupToUShort("DisableColumnCnfg1"); + cfg->DisableColumnCnfg2 = lookupToUShort("DisableColumnCnfg2"); + cfg->TrigLat = lookupToUShort("TrigLat"); + cfg->CMDcnt = lookupToUShort("CMDcnt"); + cfg->StopModeCnfg = lookupToUShort("StopModeCnfg"); + cfg->HitDiscCnfg = lookupToUShort("HitDiscCnfg"); + cfg->EN_PLL = lookupToUShort("EN_PLL"); + cfg->Efuse_sense = lookupToUShort("Efuse_sense"); + cfg->Stop_Clk = lookupToUShort("Stop_Clk"); + cfg->ReadErrorReq = lookupToUShort("ReadErrorReq"); + cfg->ReadSkipped = lookupToUShort("ReadSkipped"); + cfg->Reg27Spare = lookupToUShort("Reg27Spare"); + cfg->GateHitOr = lookupToUShort("GateHitOr"); + cfg->CalEn = lookupToUShort("CalEn"); + cfg->SR_clr = lookupToUShort("SR_clr"); + cfg->Latch_en = lookupToUShort("Latch_en"); + cfg->SR_Clock = lookupToUShort("SR_Clock"); + cfg->LVDSDrvSet06 = lookupToUShort("LVDSDrvSet06"); + cfg->Reg28Spare = lookupToUShort("Reg28Spare"); + cfg->EN40M = lookupToUShort("EN40M"); + cfg->EN80M = lookupToUShort("EN80M"); + //special case + cfg->CLK0 = lookupToUShort("CLK0_S2"); + cfg->CLK0 |= lookupToUShort("CLK0_S1")<<1; + cfg->CLK0 |= lookupToUShort("CLK0_S0")<<2; + cfg->CLK1 = lookupToUShort("CLK1_S2"); + cfg->CLK1 |= lookupToUShort("CLK1_S1")<<1; + cfg->CLK1 |= lookupToUShort("CLK1_S0")<<2; + + cfg->EN160M = lookupToUShort("EN160M"); + cfg->EN320M = lookupToUShort("EN320M"); + cfg->Reg29Spare1 = lookupToUShort("Reg29Spare1"); + cfg->no8b10b = lookupToUShort("no8b10b"); + cfg->Clk2OutCnfg = lookupToUShort("Clk2OutCnfg"); + cfg->EmptyRecord = lookupToUShort("EmptyRecord"); + cfg->Reg29Spare2 = lookupToUShort("Reg29Spare2"); + cfg->LVDSDrvEn = lookupToUShort("LVDSDrvEn"); + cfg->LVDSDrvSet30 = lookupToUShort("LVDSDrvSet30"); + cfg->LVDSDrvSet12 = lookupToUShort("LVDSDrvSet12"); + cfg->PlsrRiseUpTau = lookupToUShort("PlsrRiseUpTau"); + cfg->PlsrPwr = lookupToUShort("PlsrPwr"); + cfg->PlsrDelay = lookupToUShort("PlsrDelay"); + cfg->ExtDigCalSW = lookupToUShort("ExtDigCalSW"); + cfg->ExtAnaCalSW = lookupToUShort("ExtAnaCalSW"); + cfg->Reg31Spare = lookupToUShort("Reg31Spare"); + cfg->SELB0 = lookupToUShort("SELB0"); + cfg->SELB1 = lookupToUShort("SELB1"); + cfg->SELB2 = lookupToUShort("SELB2"); + cfg->EfuseCref = lookupToUShort("EfuseCref"); + cfg->EfuseVref = lookupToUShort("EfuseVref"); + cfg->Chip_SN = lookupToUShort("Chip_SN"); + + // charge injection + config->FECalib.cinjLo=lookupToFloat("cinjLo"); + config->FECalib.cinjHi=lookupToFloat("cinjHi"); + config->FECalib.vcalCoeff[0]=lookupToFloat("vcalCoeff[0]"); + config->FECalib.vcalCoeff[1]=lookupToFloat("vcalCoeff[1]"); + config->FECalib.vcalCoeff[2]=lookupToFloat("vcalCoeff[2]"); + config->FECalib.vcalCoeff[3]=lookupToFloat("vcalCoeff[3]"); + config->FECalib.chargeCoeffClo=lookupToFloat("chargeCoeffClo"); + config->FECalib.chargeCoeffChi=lookupToFloat("chargeCoeffChi"); + config->FECalib.chargeOffsetClo=lookupToFloat("chargeOffsetClo"); + config->FECalib.chargeOffsetChi=lookupToFloat("chargeOffsetChi"); + config->FECalib.monleakCoeff=lookupToFloat("monleakCoeff"); + + //Pixel register + //Masks + setupMaskBit(ipc::enable, config, "enable"); + setupMaskBit(ipc::largeCap, config, "largeCap"); + setupMaskBit(ipc::smallCap, config, "smallCap"); + setupMaskBit(ipc::hitbus, config, "hitbus"); + + setupDAC(config->FETrims.dacThresholdTrim, "tdac"); + setupDAC(config->FETrims.dacFeedbackTrim, "fdac"); + delete m_moduleCfgFile; +} + +void FEI4AConfigFile::dump(const ipc::PixelFEI4AConfig &config){ + const ipc::PixelFEI4AGlobal* cfg=&config.FEGlobal; + std::cout<<"Global Register Fields:"<<std::endl; + std::cout<<"======================="<<std::endl; + std::cout<<"TrigCnt = "<<cfg->TrigCnt<<std::endl; + std::cout<<"Conf_AddrEnable = "<<cfg->Conf_AddrEnable<<std::endl; + std::cout<<"Reg2Spare = "<<cfg->Reg2Spare<<std::endl; + std::cout<<"ErrMask0 = "<<cfg->ErrMask0<<std::endl; + std::cout<<"ErrMask1 = "<<cfg->ErrMask1<<std::endl; + std::cout<<"PrmpVbpRight = "<<cfg->PrmpVbpRight<<std::endl; + std::cout<<"Vthin = "<<cfg->Vthin<<std::endl; + std::cout<<"DisVbn_CPPM = "<<cfg->DisVbn_CPPM<<std::endl; + std::cout<<"PrmpVbp = "<<cfg->PrmpVbp<<std::endl; + std::cout<<"TdacVbp = "<<cfg->TdacVbp<<std::endl; + std::cout<<"DisVbn = "<<cfg->DisVbn<<std::endl; + std::cout<<"Amp2Vbn = "<<cfg->Amp2Vbn<<std::endl; + std::cout<<"Amp2VbpFol = "<<cfg->Amp2VbpFol<<std::endl; + std::cout<<"PrmpVbpTop = "<<cfg->PrmpVbpTop<<std::endl; + std::cout<<"Amp2Vbp = "<<cfg->Amp2Vbp<<std::endl; + std::cout<<"FdacVbn = "<<cfg->FdacVbn<<std::endl; + std::cout<<"Amp2Vbpf = "<<cfg->Amp2Vbpf<<std::endl; + std::cout<<"PrmpVbnFol = "<<cfg->PrmpVbnFol<<std::endl; + std::cout<<"PrmpVbpLeft = "<<cfg->PrmpVbpLeft<<std::endl; + std::cout<<"PrmpVbpf = "<<cfg->PrmpVbpf<<std::endl; + std::cout<<"PrmpVbnLcc = "<<cfg->PrmpVbnLcc<<std::endl; + std::cout<<"Reg13Spare = "<<cfg->Reg13Spare<<std::endl; + std::cout<<"PxStrobes = "<<cfg->PxStrobes<<std::endl; + std::cout<<"S0 = "<<cfg->S0<<std::endl; + std::cout<<"S1 = "<<cfg->S1<<std::endl; + std::cout<<"LVDSDrvIref = "<<cfg->LVDSDrvIref<<std::endl; + std::cout<<"BonnDac = "<<cfg->BonnDac<<std::endl; + std::cout<<"PllIbias = "<<cfg->PllIbias<<std::endl; + std::cout<<"LVDSDrvVos = "<<cfg->LVDSDrvVos<<std::endl; + std::cout<<"TempSensBias = "<<cfg->TempSensBias<<std::endl; + std::cout<<"PllIcp = "<<cfg->PllIcp<<std::endl; + std::cout<<"Reg17Spare = "<<cfg->Reg17Spare<<std::endl; + std::cout<<"PlsrIdacRamp = "<<cfg->PlsrIdacRamp<<std::endl; + std::cout<<"Reg18Spare = "<<cfg->Reg18Spare<<std::endl; + std::cout<<"PlsrVgOPamp = "<<cfg->PlsrVgOPamp<<std::endl; + std::cout<<"PlsrDacBias = "<<cfg->PlsrDacBias<<std::endl; + std::cout<<"Reg19Spare = "<<cfg->Reg19Spare<<std::endl; + std::cout<<"Vthin_AltCoarse = "<<cfg->Vthin_AltCoarse<<std::endl; + std::cout<<"Vthin_AltFine = "<<cfg->Vthin_AltFine<<std::endl; + std::cout<<"PlsrDAC = "<<cfg->PlsrDAC<<std::endl; + std::cout<<"DIGHITIN_Sel = "<<cfg->DIGHITIN_Sel<<std::endl; + std::cout<<"DINJ_Override = "<<cfg->DINJ_Override<<std::endl; + std::cout<<"HITLD_In = "<<cfg->HITLD_In<<std::endl; + std::cout<<"Reg21Spare = "<<cfg->Reg21Spare<<std::endl; + std::cout<<"Reg22Spare2 = "<<cfg->Reg22Spare2<<std::endl; + std::cout<<"Colpr_Addr = "<<cfg->Colpr_Addr<<std::endl; + std::cout<<"Colpr_Mode = "<<cfg->Colpr_Mode<<std::endl; + std::cout<<"Reg22Spare1 = "<<cfg->Reg22Spare2<<std::endl; + std::cout<<"DisableColumnCnfg0 = "<<cfg->DisableColumnCnfg0<<std::endl; + std::cout<<"DisableColumnCnfg1 = "<<cfg->DisableColumnCnfg1<<std::endl; + std::cout<<"DisableColumnCnfg2 = "<<cfg->DisableColumnCnfg2<<std::endl; + std::cout<<"TrigLat = "<<cfg->TrigLat<<std::endl; + std::cout<<"CMDcnt = "<<cfg->CMDcnt<<std::endl; + std::cout<<"StopModeCnfg = "<<cfg->StopModeCnfg<<std::endl; + std::cout<<"HitDiscCnfg = "<<cfg->HitDiscCnfg<<std::endl; + std::cout<<"EN_PLL = "<<cfg->EN_PLL<<std::endl; + std::cout<<"Efuse_sense = "<<cfg->Efuse_sense<<std::endl; + std::cout<<"Stop_Clk = "<<cfg->Stop_Clk<<std::endl; + std::cout<<"ReadErrorReq = "<<cfg->ReadErrorReq<<std::endl; + std::cout<<"ReadSkipped = "<<cfg->ReadSkipped<<std::endl; + std::cout<<"Reg27Spare = "<<cfg->Reg27Spare<<std::endl; + std::cout<<"GateHitOr = "<<cfg->GateHitOr<<std::endl; + std::cout<<"CalEn = "<<cfg->CalEn<<std::endl; + std::cout<<"SR_clr = "<<cfg->SR_clr<<std::endl; + std::cout<<"Latch_en = "<<cfg->Latch_en<<std::endl; + std::cout<<"SR_Clock = "<<cfg->SR_Clock<<std::endl; + std::cout<<"LVDSDrvSet06 = "<<cfg->LVDSDrvSet06<<std::endl; + std::cout<<"Reg28Spare = "<<cfg->Reg28Spare<<std::endl; + std::cout<<"EN40M = "<<cfg->EN40M<<std::endl; + std::cout<<"EN80M = "<<cfg->EN80M<<std::endl; + std::cout<<"CLK1 = "<<cfg->CLK1<<std::endl; + std::cout<<"CLK0 = "<<cfg->CLK0<<std::endl; + std::cout<<"EN160M = "<<cfg->EN160M<<std::endl; + std::cout<<"EN320M = "<<cfg->EN320M<<std::endl; + std::cout<<"Reg29Spare1 = "<<cfg->Reg29Spare1<<std::endl; + std::cout<<"no8b10b = "<<cfg->no8b10b<<std::endl; + std::cout<<"Clk2OutCnfg = "<<cfg->Clk2OutCnfg<<std::endl; + std::cout<<"EmptyRecord = "<<cfg->EmptyRecord<<std::endl; + std::cout<<"Reg29Spare2 = "<<cfg->Reg29Spare2<<std::endl; + std::cout<<"LVDSDrvEn = "<<cfg->LVDSDrvEn<<std::endl; + std::cout<<"LVDSDrvSet30 = "<<cfg->LVDSDrvSet30<<std::endl; + std::cout<<"LVDSDrvSet12 = "<<cfg->LVDSDrvSet12<<std::endl; + std::cout<<"PlsrRiseUpTau = "<<cfg->PlsrRiseUpTau<<std::endl; + std::cout<<"PlsrPwr = "<<cfg->PlsrPwr<<std::endl; + std::cout<<"PlsrDelay = "<<cfg->PlsrDelay<<std::endl; + std::cout<<"ExtDigCalSW = "<<cfg->ExtDigCalSW<<std::endl; + std::cout<<"ExtAnaCalSW = "<<cfg->ExtAnaCalSW<<std::endl; + std::cout<<"Reg31Spare = "<<cfg->Reg31Spare<<std::endl; + std::cout<<"SELB0 = "<<cfg->SELB0<<std::endl; + std::cout<<"SELB1 = "<<cfg->SELB1<<std::endl; + std::cout<<"SELB2 = "<<cfg->SELB2<<std::endl; + std::cout<<"EfuseCref = "<<cfg->EfuseCref<<std::endl; + std::cout<<"EfuseVref = "<<cfg->EfuseVref<<std::endl; + std::cout<<"Chip_SN = "<<cfg->Chip_SN<<std::endl; + // charge injection + std::cout<<std::endl; + std::cout<<"Charge injection parameters:"<<std::endl; + std::cout<<"============================"<<std::endl; + std::cout<<"cinjLo = "<<config.FECalib.cinjLo<<std::endl; + std::cout<<"cinjHi = "<<config.FECalib.cinjHi<<std::endl; + std::cout<<"vcalCoeff[0] = "<<config.FECalib.vcalCoeff[0]<<std::endl; + std::cout<<"vcalCoeff[1] = "<<config.FECalib.vcalCoeff[1]<<std::endl; + std::cout<<"vcalCoeff[2] = "<<config.FECalib.vcalCoeff[2]<<std::endl; + std::cout<<"vcalCoeff[3] = "<<config.FECalib.vcalCoeff[3]<<std::endl; + std::cout<<"chargeCoeffClo = "<<config.FECalib.chargeCoeffClo<<std::endl; + std::cout<<"chargeCoeffChi = "<<config.FECalib.chargeCoeffChi<<std::endl; + std::cout<<"chargeOffsetClo = "<<config.FECalib.chargeOffsetClo<<std::endl; + std::cout<<"chargeOffsetChi = "<<config.FECalib.chargeOffsetChi<<std::endl; + std::cout<<"monleakCoeff = "<<config.FECalib.monleakCoeff<<std::endl; + + //DACs + std::cout<<"Threshold DAC:"<<std::endl; + std::cout<<"--------------"<<std::endl; + dumpDac(config.FETrims.dacThresholdTrim); + std::cout<<"Feedback DAC:"<<std::endl; + std::cout<<"-------------"<<std::endl; + dumpDac(config.FETrims.dacFeedbackTrim); + + //Masks + std::cout<<"Enable Mask:"<<std::endl; + std::cout<<"------------"<<std::endl; + dumpMask(ipc::enable, config); + std::cout<<"Large Cap Mask:"<<std::endl; + std::cout<<"---------------"<<std::endl; + dumpMask(ipc::largeCap, config); + std::cout<<"Small Cap Mask:"<<std::endl; + std::cout<<"---------------"<<std::endl; + dumpMask(ipc::smallCap, config); + std::cout<<"Hitbus Mask:"<<std::endl; + std::cout<<"------------"<<std::endl; + dumpMask(ipc::hitbus, config); + +} + +void FEI4AConfigFile::dumpDac(const unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS]){ + std::cout<<(unsigned)trim[0][0]<<" "<<(unsigned)trim[79][335]<<std::endl; + for (int i=0;i<674;i++){ + if(i>1){ + printf("%3d",i/2); + if(i%2==0)std::cout<<"a "; + else std::cout<<"b "; + }else{ + std::cout<<"### "; + } + for (int j=1;j<=40;j++){ + if(i<2){ + if(i==0)printf("%2d ",j); + else printf("%2d ",j+40); + }else{ + if(i%2==0)printf("%2d ",trim[j-1][i/2-1]); + else printf("%2d ",trim[j+39][i/2-1]); + } + if(j%10==0)std::cout<<" "; + } + std::cout<<std::endl; + } + std::cout<<std::endl; + } + + void FEI4AConfigFile::dumpMask(const long int bit, const ipc::PixelFEI4AConfig& cfg){ + + for (int i=0;i<=336;i++){ + if(i==0){ + std::cout<<"### 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76"<<std::endl; + } + else{ + printf("%3d ",i); + for (int j=1;j<=80;j++){ + printf("%1d",(cfg.FEMasks[j-1][i-1]>>bit)&0x1); + if(j%10==0)std::cout<<" "; + else if(j%5==0)std::cout<<"-"; + } + std::cout<<std::endl; + } + } + std::cout<<std::endl; + } diff --git a/rce/rcecalib/server/FEI4AConfigFile.hh b/rce/rcecalib/server/FEI4AConfigFile.hh new file mode 100644 index 0000000000000000000000000000000000000000..9fef2674cd0b01e8055519d98d66dff4d64eccc3 --- /dev/null +++ b/rce/rcecalib/server/FEI4AConfigFile.hh @@ -0,0 +1,32 @@ +#ifndef FEI4ACONFIGFILE_HH +#define FEI4ACONFIGFILE_HH + +#include "PixelFEI4AConfig.hh" +#include <string> +#include <map> + +class FEI4AConfigFile { +public: + FEI4AConfigFile(){} + ~FEI4AConfigFile(); + void readModuleConfig(ipc::PixelFEI4AConfig* cfg, std::string filename); + void writeModuleConfig(ipc::PixelFEI4AConfig* cfg, const std::string &base, const std::string &confdir, const std::string &configname, const std::string &key); + void writeMaskFile(const long int bit, ipc::PixelFEI4AConfig* config, const std::string &filename); + void writeDacFile(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , const std::string filename); + void dump(const ipc::PixelFEI4AConfig& cfg); +private: + std::string getFullPath(std::string relPath); + void setupDAC(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , std::string par); + void setupMaskBit(const long int bit, ipc::PixelFEI4AConfig *cfg, std::string par); + void dumpMask(const long int bit, const ipc::PixelFEI4AConfig& cfg); + unsigned short lookupToUShort(std::string par); + int convertToUShort(std::string par, unsigned short& val); + float lookupToFloat(std::string par); + void dumpDac(const unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS]); + + std::string m_moduleCfgFilePath; + std::ifstream *m_moduleCfgFile; + std::map<std::string, std::string> m_params; +}; + +#endif diff --git a/rce/rcecalib/server/FEI4BConfigFile.cc b/rce/rcecalib/server/FEI4BConfigFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..e0b650782696f70c60c703e7b9e175f4af9a6b2d --- /dev/null +++ b/rce/rcecalib/server/FEI4BConfigFile.cc @@ -0,0 +1,772 @@ +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/util/exceptions.hh" +#include <boost/algorithm/string.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <sys/stat.h> + +std::string FEI4BConfigFile::getFullPath(std::string relPath){ + std::string newPath = relPath, basePath=m_moduleCfgFilePath, testName; + unsigned int pos; + // skip config file-name part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // skip "config" part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // now skip module part of base path, but keep last "/" + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos+1,basePath.length()-pos); + else basePath=""; + // then add relative path of DAC or mask file + newPath = basePath + newPath; + return newPath; +} + +FEI4BConfigFile::~FEI4BConfigFile(){} + +unsigned short FEI4BConfigFile::lookupToUShort(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + unsigned short val; + int success=convertToUShort(vals, val); + if(success==false){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} +float FEI4BConfigFile::lookupToFloat(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + float val; + char* end; + val=strtof(vals.c_str(), &end); + if(end-vals.c_str()!=(int)vals.size()){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} + +int FEI4BConfigFile::convertToUShort(std::string par, unsigned short& val){ + char* end; + val=strtoul(par.c_str(), &end, 0); + if(end-par.c_str()!=(int)par.size()){ + return 0; + } + if((val&0xffff0000)!=0){ + std::cout<<"Value "<<val<<" too large."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return 1; +} + + +void FEI4BConfigFile::setupMaskBit(const long int bit, ipc::PixelFEI4BConfig* cfg, std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + unsigned short val; + int success=convertToUShort(m_params[par], val); + //file + if(success==false){ + std::string fullpath=getFullPath(m_params[par]); + std::ifstream* maskfile=new std::ifstream(fullpath.c_str()); + if(!maskfile->good()){ + std::cout<<"Cannot open file with name "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string inpline; + unsigned short row=0; + while(true){ + getline(*maskfile, inpline); + if(maskfile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" -"), boost::token_compress_on ); + if(splitVec.size()!=17){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + int success=convertToUShort(splitVec[0], val); + if(success!=true || val!=++row){//check and increment row number + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string oneline; + for(int i=1;i<17;i++)oneline+=splitVec[i]; //concatenate everyting. + if(oneline.size()!=(unsigned)ipc::IPC_N_I4_PIXEL_COLUMNS) throw rcecalib::Config_File_Error(ERS_HERE); + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + if(oneline[i]=='1')cfg->FEMasks[i][row-1]|=1<<bit; + } + } + } + if(row!=ipc::IPC_N_I4_PIXEL_ROWS) throw rcecalib::Config_File_Error(ERS_HERE); + delete maskfile; + }else{ + // left are the cases all 0 and all 1 + if(val!=0 && val!=1) throw rcecalib::Config_File_Error(ERS_HERE); + for (int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + cfg->FEMasks[i][j]|=val<<bit; + } + } + } +} + + +void FEI4BConfigFile::setupDAC(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + unsigned short val; + int success=convertToUShort(m_params[par], val); + //file + if(success==false){ + std::string fullpath=getFullPath(m_params[par]); + std::ifstream* dacfile=new std::ifstream(fullpath.c_str()); + if(!dacfile->good()){ + std::cout<<"Cannot open file with name "<<fullpath<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string inpline; + unsigned short hrow=1; + while(true){ + getline(*dacfile, inpline); + if(dacfile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" "), boost::token_compress_on ); + if(splitVec.size()!=41){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + success=convertToUShort(splitVec[0].substr(0,splitVec[0].size()-1),val); + if(success!=true || val!=++hrow/2){//check and increment row number + throw rcecalib::Config_File_Error(ERS_HERE); + } + for(int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS/2;i++){ + success=convertToUShort(splitVec[i+1], val); + if(!success) throw rcecalib::Config_File_Error(ERS_HERE); + trim[i+(hrow%2)*ipc::IPC_N_I4_PIXEL_COLUMNS/2][hrow/2-1]=val; + } + } + } + if(hrow/2!=ipc::IPC_N_I4_PIXEL_ROWS) throw rcecalib::Config_File_Error(ERS_HERE); + delete dacfile; + }else{ + // left are the cases where all settings are identical. + for (int i=0;i<ipc::IPC_N_I4_PIXEL_COLUMNS;i++){ + for(int j=0;j<ipc::IPC_N_I4_PIXEL_ROWS;j++){ + trim[i][j]=val; + } + } + } +} + +void FEI4BConfigFile::writeModuleConfig(ipc::PixelFEI4BConfig* config, const std::string &base, const std::string &confdir, + const std::string &configname, const std::string &key){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(base.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<" does not exist. Not writing config file"<<std::endl; + return; + } + intStat = stat((base+"/"+confdir).c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + //std::cout<<"Directory "<<base<<"/"<<confdir<<" does not exist. Creating."<<std::endl; + mkdir ((base+"/"+confdir).c_str(),0777); + mkdir ((base+"/"+confdir+"/configs").c_str(),0777); + mkdir ((base+"/"+confdir+"/masks").c_str(),0777); + mkdir ((base+"/"+confdir+"/tdacs").c_str(),0777); + mkdir ((base+"/"+confdir+"/fdacs").c_str(),0777); + } + std::string cfgname=configname; + if(key.size()!=0)cfgname+="__"+key; + std::string fullpath=base+"/"+confdir+"/configs/"+cfgname+".cfg"; + std::ofstream cfgfile(fullpath.c_str()); + cfgfile<<"# FEI4B Configuration"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Module name"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"ModuleID\t\t"<<config->idStr<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Geographical address"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"Address\t\t\t"<<(unsigned)config->FECommand.address<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Global register"<<std::endl; + cfgfile<<std::endl; + //Global register + ipc::PixelFEI4BGlobal* cfg=&config->FEGlobal; + cfgfile<<"TrigCnt\t\t\t"<<cfg->TrigCnt<<std::endl; + cfgfile<<"Conf_AddrEnable\t\t"<<cfg->Conf_AddrEnable <<std::endl; + cfgfile<<"Reg2Spare\t\t"<<cfg->Reg2Spare <<std::endl; + cfgfile<<"ErrMask0\t\t"<<"0x"<<std::hex<<cfg->ErrMask0 <<std::dec<<std::endl; + cfgfile<<"ErrMask1\t\t"<<"0x"<<std::hex<<cfg->ErrMask1 <<std::dec<<std::endl; + cfgfile<<"PrmpVbpRight\t\t"<< cfg->PrmpVbpRight <<std::endl; + cfgfile<<"BufVgOpAmp\t\t"<<cfg->BufVgOpAmp <<std::endl; + cfgfile<<"Reg6Spare\t\t"<<cfg->Reg6Spare <<std::endl; + cfgfile<<"PrmpVbp\t\t\t"<<cfg->PrmpVbp <<std::endl; + cfgfile<<"TdacVbp\t\t\t"<< cfg->TdacVbp <<std::endl; + cfgfile<<"DisVbn\t\t\t"<<cfg->DisVbn <<std::endl; + cfgfile<<"Amp2Vbn\t\t\t"<<cfg->Amp2Vbn <<std::endl; + cfgfile<<"Amp2VbpFol\t\t"<<cfg->Amp2VbpFol <<std::endl; + cfgfile<<"Reg9Spare\t\t"<<cfg->Reg9Spare <<std::endl; + cfgfile<<"Amp2Vbp\t\t\t"<<cfg->Amp2Vbp <<std::endl; + cfgfile<<"FdacVbn\t\t\t"<<cfg->FdacVbn <<std::endl; + cfgfile<<"Amp2Vbpf\t\t"<<cfg->Amp2Vbpf <<std::endl; + cfgfile<<"PrmpVbnFol\t\t"<<cfg->PrmpVbnFol <<std::endl; + cfgfile<<"PrmpVbpLeft\t\t"<<cfg->PrmpVbpLeft <<std::endl; + cfgfile<<"PrmpVbpf\t\t"<<cfg->PrmpVbpf <<std::endl; + cfgfile<<"PrmpVbnLcc\t\t"<<cfg->PrmpVbnLcc <<std::endl; + cfgfile<<"Reg13Spare\t\t"<<cfg->Reg13Spare <<std::endl; + cfgfile<<"PxStrobes\t\t"<<cfg->PxStrobes <<std::endl; + cfgfile<<"S0\t\t\t"<<cfg->S0 <<std::endl; + cfgfile<<"S1\t\t\t"<<cfg->S1 <<std::endl; + cfgfile<<"LVDSDrvIref\t\t"<<cfg->LVDSDrvIref <<std::endl; + cfgfile<<"GADCOpAmp\t\t"<<cfg->GADCOpAmp <<std::endl; + cfgfile<<"PllIbias\t\t"<<cfg->PllIbias <<std::endl; + cfgfile<<"LVDSDrvVos\t\t"<<cfg->LVDSDrvVos <<std::endl; + cfgfile<<"TempSensBias\t\t"<<cfg->TempSensBias <<std::endl; + cfgfile<<"PllIcp\t\t\t"<<cfg->PllIcp <<std::endl; + cfgfile<<"Reg17Spare\t\t"<<cfg->Reg17Spare <<std::endl; + cfgfile<<"PlsrIdacRamp\t\t"<<cfg->PlsrIdacRamp <<std::endl; + cfgfile<<"VrefDigTune\t\t"<<cfg->VrefDigTune <<std::endl; + cfgfile<<"PlsrVgOPamp\t\t"<<cfg->PlsrVgOPamp <<std::endl; + cfgfile<<"PlsrDacBias\t\t"<<cfg->PlsrDacBias <<std::endl; + cfgfile<<"VrefAnTune\t\t"<<cfg->VrefAnTune <<std::endl; + cfgfile<<"Vthin_AltCoarse\t\t"<<cfg->Vthin_AltCoarse <<std::endl; + cfgfile<<"Vthin_AltFine\t\t"<<cfg->Vthin_AltFine <<std::endl; + cfgfile<<"PlsrDAC\t\t\t"<<cfg->PlsrDAC <<std::endl; + cfgfile<<"DIGHITIN_Sel\t\t"<<cfg->DIGHITIN_Sel <<std::endl; + cfgfile<<"DINJ_Override\t\t"<<cfg->DINJ_Override <<std::endl; + cfgfile<<"HITLD_In\t\t"<<cfg->HITLD_In <<std::endl; + cfgfile<<"Reg21Spare\t\t"<<cfg->Reg21Spare <<std::endl; + cfgfile<<"Reg22Spare2\t\t"<<cfg->Reg22Spare2 <<std::endl; + cfgfile<<"Colpr_Addr\t\t"<<cfg->Colpr_Addr <<std::endl; + cfgfile<<"Colpr_Mode\t\t"<<cfg->Colpr_Mode <<std::endl; + cfgfile<<"Reg22Spare1\t\t"<<cfg->Reg22Spare1 <<std::endl; + cfgfile<<"DisableColumnCnfg0\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg0 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg1\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg1 <<std::dec<<std::endl; + cfgfile<<"DisableColumnCnfg2\t"<<"0x"<<std::hex<<cfg->DisableColumnCnfg2 <<std::dec<<std::endl; + cfgfile<<"TrigLat\t\t\t"<< cfg->TrigLat <<std::endl; + cfgfile<<"CMDcnt\t\t\t"<<cfg->CMDcnt <<std::endl; + cfgfile<<"StopModeCnfg\t\t"<<cfg->StopModeCnfg <<std::endl; + cfgfile<<"HitDiscCnfg\t\t"<<cfg->HitDiscCnfg <<std::endl; + cfgfile<<"EN_PLL\t\t\t"<<cfg->EN_PLL <<std::endl; + cfgfile<<"Efuse_sense\t\t"<<cfg->Efuse_sense <<std::endl; + cfgfile<<"Stop_Clk\t\t"<<cfg->Stop_Clk <<std::endl; + cfgfile<<"ReadErrorReq\t\t"<<cfg->ReadErrorReq <<std::endl; + cfgfile<<"Reg27Spare1\t\t"<<cfg->Reg27Spare1 <<std::endl; + cfgfile<<"GADC_Enable\t\t"<<cfg->GADC_Enable <<std::endl; + cfgfile<<"ShiftReadBack\t\t"<<cfg->ShiftReadBack <<std::endl; + cfgfile<<"Reg27Spare2\t\t"<<cfg->Reg27Spare2 <<std::endl; + cfgfile<<"GateHitOr\t\t"<<cfg->GateHitOr <<std::endl; + cfgfile<<"CalEn\t\t\t"<<cfg->CalEn <<std::endl; + cfgfile<<"SR_clr\t\t\t"<<cfg->SR_clr <<std::endl; + cfgfile<<"Latch_en\t\t"<<cfg->Latch_en <<std::endl; + cfgfile<<"SR_Clock\t\t"<<cfg->SR_Clock <<std::endl; + cfgfile<<"LVDSDrvSet06\t\t"<<cfg->LVDSDrvSet06 <<std::endl; + cfgfile<<"Reg28Spare\t\t"<<cfg->Reg28Spare <<std::endl; + cfgfile<<"EN40M\t\t\t"<<cfg->EN40M <<std::endl; + cfgfile<<"EN80M\t\t\t"<<cfg->EN80M <<std::endl; + cfgfile<<"CLK0_S2\t\t\t"<<(cfg->CLK0 &0x1)<<std::endl; + cfgfile<<"CLK0_S1\t\t\t"<<((cfg->CLK0>>1)&0x1 )<<std::endl; + cfgfile<<"CLK0_S0\t\t\t"<<((cfg->CLK0>>2)&0x1 )<<std::endl; + cfgfile<<"CLK1_S2\t\t\t"<<(cfg->CLK1&0x1 )<<std::endl; + cfgfile<<"CLK1_S1\t\t\t"<<((cfg->CLK1>>1)&0x1 )<<std::endl; + cfgfile<<"CLK1_S0\t\t\t"<<((cfg->CLK1>>2)&0x1 )<<std::endl; + cfgfile<<"EN160M\t\t\t"<<cfg->EN160M <<std::endl; + cfgfile<<"EN320M\t\t\t"<<cfg->EN320M <<std::endl; + cfgfile<<"Reg29Spare1\t\t"<<cfg->Reg29Spare1 <<std::endl; + cfgfile<<"no8b10b\t\t\t"<<cfg->no8b10b <<std::endl; + cfgfile<<"Clk2OutCnfg\t\t"<<cfg->Clk2OutCnfg <<std::endl; + cfgfile<<"EmptyRecord\t\t"<<cfg->EmptyRecord <<std::endl; + cfgfile<<"Reg29Spare2\t\t"<<cfg->Reg29Spare2 <<std::endl; + cfgfile<<"LVDSDrvEn\t\t"<<cfg->LVDSDrvEn <<std::endl; + cfgfile<<"LVDSDrvSet30\t\t"<<cfg->LVDSDrvSet30 <<std::endl; + cfgfile<<"LVDSDrvSet12\t\t"<<cfg->LVDSDrvSet12 <<std::endl; + cfgfile<<"TempSensDiodeSel\t"<<cfg->TempSensDiodeSel <<std::endl; + cfgfile<<"TempSensDisable\t\t"<<cfg->TempSensDisable <<std::endl; + cfgfile<<"IleakRange\t\t"<<cfg->IleakRange <<std::endl; + cfgfile<<"Reg30Spare\t\t"<<cfg->Reg30Spare <<std::endl; + cfgfile<<"PlsrRiseUpTau\t\t"<<cfg->PlsrRiseUpTau <<std::endl; + cfgfile<<"PlsrPwr\t\t\t"<<cfg->PlsrPwr <<std::endl; + cfgfile<<"PlsrDelay\t\t"<<cfg->PlsrDelay <<std::endl; + cfgfile<<"ExtDigCalSW\t\t"<<cfg->ExtDigCalSW <<std::endl; + cfgfile<<"ExtAnaCalSW\t\t"<<cfg->ExtAnaCalSW <<std::endl; + cfgfile<<"Reg31Spare\t\t"<<cfg->Reg31Spare <<std::endl; + cfgfile<<"GADCSel\t\t\t"<<cfg->GADCSel <<std::endl; + cfgfile<<"SELB0\t\t\t"<<cfg->SELB0 <<std::endl; + cfgfile<<"SELB1\t\t\t"<<cfg->SELB1 <<std::endl; + cfgfile<<"SELB2\t\t\t"<<cfg->SELB2 <<std::endl; + cfgfile<<"Reg34Spare1\t\t"<<cfg->Reg34Spare1 <<std::endl; + cfgfile<<"PrmpVbpMsnEn\t\t"<<cfg->PrmpVbpMsnEn <<std::endl; + cfgfile<<"Reg34Spare2\t\t"<<cfg->Reg34Spare2 <<std::endl; + cfgfile<<"Chip_SN\t\t\t"<<cfg->Chip_SN <<std::endl; + cfgfile<<"Reg1Spare\t\t"<<cfg->Reg1Spare <<std::endl; + cfgfile<<"SmallHitErase\t\t"<<cfg->SmallHitErase <<std::endl; + cfgfile<<"Eventlimit\t\t"<<cfg->Eventlimit <<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Pixel register"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"enable\t\t\t"<<confdir<<"/masks/enable_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"largeCap\t\t"<<confdir<<"/masks/largeCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"smallCap\t\t"<<confdir<<"/masks/smallCap_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"hitbus\t\t\t"<<confdir<<"/masks/hitbus_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"tdac\t\t\t"<<confdir<<"/tdacs/tdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<"fdac\t\t\t"<<confdir<<"/fdacs/fdac_"<<cfgname<<".dat"<<std::endl; + cfgfile<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Charge injection parameters"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"cinjLo\t\t\t"<<config->FECalib.cinjLo <<std::endl; + cfgfile<<"cinjHi\t\t\t"<<config->FECalib.cinjHi <<std::endl; + cfgfile<<"vcalCoeff[0]\t\t"<<config->FECalib.vcalCoeff[0] <<std::endl; + cfgfile<<"vcalCoeff[1]\t\t"<<config->FECalib.vcalCoeff[1] <<std::endl; + cfgfile<<"vcalCoeff[2]\t\t"<<config->FECalib.vcalCoeff[2] <<std::endl; + cfgfile<<"vcalCoeff[3]\t\t"<<config->FECalib.vcalCoeff[3] <<std::endl; + cfgfile<<"chargeCoeffClo\t\t"<<config->FECalib.chargeCoeffClo<<std::endl; + cfgfile<<"chargeCoeffChi\t\t"<<config->FECalib.chargeCoeffChi<<std::endl; + cfgfile<<"chargeOffsetClo\t\t"<<config->FECalib.chargeOffsetClo<<std::endl; + cfgfile<<"chargeOffsetChi\t\t"<<config->FECalib.chargeOffsetChi<<std::endl; + cfgfile<<"monleakCoeff\t\t"<<config->FECalib.monleakCoeff<<std::endl; + writeMaskFile(ipc::enable, config, base+"/"+confdir+"/masks/enable_"+cfgname+".dat"); + writeMaskFile(ipc::largeCap, config, base+"/"+confdir+"/masks/largeCap_"+cfgname+".dat"); + writeMaskFile(ipc::smallCap, config, base+"/"+confdir+"/masks/smallCap_"+cfgname+".dat"); + writeMaskFile(ipc::hitbus, config, base+"/"+confdir+"/masks/hitbus_"+cfgname+".dat"); + + writeDacFile(config->FETrims.dacThresholdTrim, base+"/"+confdir+"/tdacs/tdac_"+cfgname+".dat"); + writeDacFile(config->FETrims.dacFeedbackTrim, base+"/"+confdir+"/fdacs/fdac_"+cfgname+".dat"); + + + +} +void FEI4BConfigFile::writeMaskFile(const long int bit, ipc::PixelFEI4BConfig* config, const std::string &filename){ + std::ofstream maskfile(filename.c_str()); + maskfile<<"### 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76"<<std::endl; + char linenr[128]; + for(int i=1;i<=336;i++){ + sprintf(linenr,"%3d ", i); + maskfile<<linenr; + for (int j=1;j<=80;j++){ + maskfile<<((config->FEMasks[j-1][i-1]>>bit)&0x1); + if(j%10==0)maskfile<<" "; + else if(j%5==0)maskfile<<"-"; + } + maskfile<<std::endl; + } +} + +void FEI4BConfigFile::writeDacFile(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , const std::string filename){ + std::ofstream maskfile(filename.c_str()); + char line[512]; + for (int i=0;i<674;i++){ + if(i>1){ + sprintf(line, "%3d",i/2); + maskfile<<line; + if(i%2==0)maskfile<<"a "; + else maskfile<<"b "; + }else{ + maskfile<<"### "; + } + for (int j=1;j<=40;j++){ + if(i==0)sprintf(line, "%2d ",j); + else if(i==1)sprintf(line, "%2d ",j+40); + else { + int val = trim[j-1+(i%2)*ipc::IPC_N_I4_PIXEL_COLUMNS/2][i/2-1]; + sprintf(line, "%2d ",val); + } + maskfile<<line; + if(j%10==0)maskfile<<" "; + } + maskfile<<std::endl; + } +} + +void FEI4BConfigFile::readModuleConfig(ipc::PixelFEI4BConfig* config, std::string filename){ + //clear structure + char* ccfg=(char*)config; + for (unsigned int i=0;i<sizeof(ipc::PixelFEI4BConfig);i++)ccfg[i]=0; + //open file + m_moduleCfgFile=new std::ifstream(filename.c_str()); + if(!m_moduleCfgFile->good()){ + std::cout<<"Cannot open file with name "<<filename<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + m_moduleCfgFilePath = filename; + // parse config file + std::string inpline; + m_params.clear(); + while(true){ + getline(*m_moduleCfgFile, inpline); + if(m_moduleCfgFile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" \t"), boost::token_compress_on ); + if(splitVec.size()<2){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + m_params[splitVec[0]]=splitVec[1]; + } + } + // Module name + std::string modname=""; + if( m_params.find("ModuleID")==m_params.end()){ + std::cout<<"No Module ID defined."<<std::endl; + }else{ + modname=m_params["ModuleID"]; + } + sprintf((char*)config->idStr, "%s", modname.c_str()); + //Geographical address + config->FECommand.address=lookupToUShort("Address"); + //Global register + ipc::PixelFEI4BGlobal* cfg=&config->FEGlobal; + cfg->TrigCnt = lookupToUShort("TrigCnt"); + cfg->Conf_AddrEnable = lookupToUShort("Conf_AddrEnable"); + cfg->Reg2Spare = lookupToUShort("Reg2Spare"); + cfg->ErrMask0 = lookupToUShort("ErrMask0"); + cfg->ErrMask1 = lookupToUShort("ErrMask1"); + cfg->PrmpVbpRight = lookupToUShort("PrmpVbpRight"); + cfg->BufVgOpAmp = lookupToUShort("BufVgOpAmp"); + cfg->Reg6Spare = lookupToUShort("Reg6Spare"); + cfg->PrmpVbp = lookupToUShort("PrmpVbp"); + cfg->TdacVbp = lookupToUShort("TdacVbp"); + cfg->DisVbn = lookupToUShort("DisVbn"); + cfg->Amp2Vbn = lookupToUShort("Amp2Vbn"); + cfg->Amp2VbpFol = lookupToUShort("Amp2VbpFol"); + cfg->Reg9Spare = lookupToUShort("Reg9Spare"); + cfg->Amp2Vbp = lookupToUShort("Amp2Vbp"); + cfg->FdacVbn = lookupToUShort("FdacVbn"); + cfg->Amp2Vbpf = lookupToUShort("Amp2Vbpf"); + cfg->PrmpVbnFol = lookupToUShort("PrmpVbnFol"); + cfg->PrmpVbpLeft = lookupToUShort("PrmpVbpLeft"); + cfg->PrmpVbpf = lookupToUShort("PrmpVbpf"); + cfg->PrmpVbnLcc = lookupToUShort("PrmpVbnLcc"); + cfg->Reg13Spare = lookupToUShort("Reg13Spare"); + cfg->PxStrobes = lookupToUShort("PxStrobes"); + cfg->S0 = lookupToUShort("S0"); + cfg->S1 = lookupToUShort("S1"); + cfg->LVDSDrvIref = lookupToUShort("LVDSDrvIref"); + cfg->GADCOpAmp = lookupToUShort("GADCOpAmp"); + cfg->PllIbias = lookupToUShort("PllIbias"); + cfg->LVDSDrvVos = lookupToUShort("LVDSDrvVos"); + cfg->TempSensBias = lookupToUShort("TempSensBias"); + cfg->PllIcp = lookupToUShort("PllIcp"); + cfg->Reg17Spare = lookupToUShort("Reg17Spare"); + cfg->PlsrIdacRamp = lookupToUShort("PlsrIdacRamp"); + cfg->VrefDigTune = lookupToUShort("VrefDigTune"); + cfg->PlsrVgOPamp = lookupToUShort("PlsrVgOPamp"); + cfg->PlsrDacBias = lookupToUShort("PlsrDacBias"); + cfg->VrefAnTune = lookupToUShort("VrefAnTune"); + cfg->Vthin_AltCoarse = lookupToUShort("Vthin_AltCoarse"); + cfg->Vthin_AltFine = lookupToUShort("Vthin_AltFine"); + cfg->PlsrDAC = lookupToUShort("PlsrDAC"); + cfg->DIGHITIN_Sel = lookupToUShort("DIGHITIN_Sel"); + cfg->DINJ_Override = lookupToUShort("DINJ_Override"); + cfg->HITLD_In = lookupToUShort("HITLD_In"); + cfg->Reg21Spare = lookupToUShort("Reg21Spare"); + cfg->Reg22Spare2 = lookupToUShort("Reg22Spare2"); + cfg->Colpr_Addr = lookupToUShort("Colpr_Addr"); + cfg->Colpr_Mode = lookupToUShort("Colpr_Mode"); + cfg->Reg22Spare1 = lookupToUShort("Reg22Spare1"); + cfg->DisableColumnCnfg0 = lookupToUShort("DisableColumnCnfg0"); + cfg->DisableColumnCnfg1 = lookupToUShort("DisableColumnCnfg1"); + cfg->DisableColumnCnfg2 = lookupToUShort("DisableColumnCnfg2"); + cfg->TrigLat = lookupToUShort("TrigLat"); + cfg->CMDcnt = lookupToUShort("CMDcnt"); + cfg->StopModeCnfg = lookupToUShort("StopModeCnfg"); + cfg->HitDiscCnfg = lookupToUShort("HitDiscCnfg"); + cfg->EN_PLL = lookupToUShort("EN_PLL"); + cfg->Efuse_sense = lookupToUShort("Efuse_sense"); + cfg->Stop_Clk = lookupToUShort("Stop_Clk"); + cfg->ReadErrorReq = lookupToUShort("ReadErrorReq"); + cfg->Reg27Spare1 = lookupToUShort("Reg27Spare1"); + cfg->GADC_Enable = lookupToUShort("GADC_Enable"); + cfg->ShiftReadBack = lookupToUShort("ShiftReadBack"); + cfg->Reg27Spare2 = lookupToUShort("Reg27Spare2"); + cfg->GateHitOr = lookupToUShort("GateHitOr"); + cfg->CalEn = lookupToUShort("CalEn"); + cfg->SR_clr = lookupToUShort("SR_clr"); + cfg->Latch_en = lookupToUShort("Latch_en"); + cfg->SR_Clock = lookupToUShort("SR_Clock"); + cfg->LVDSDrvSet06 = lookupToUShort("LVDSDrvSet06"); + cfg->Reg28Spare = lookupToUShort("Reg28Spare"); + cfg->EN40M = lookupToUShort("EN40M"); + cfg->EN80M = lookupToUShort("EN80M"); + //special case + cfg->CLK0 = lookupToUShort("CLK0_S2"); + cfg->CLK0 |= lookupToUShort("CLK0_S1")<<1; + cfg->CLK0 |= lookupToUShort("CLK0_S0")<<2; + cfg->CLK1 = lookupToUShort("CLK1_S2"); + cfg->CLK1 |= lookupToUShort("CLK1_S1")<<1; + cfg->CLK1 |= lookupToUShort("CLK1_S0")<<2; + + cfg->EN160M = lookupToUShort("EN160M"); + cfg->EN320M = lookupToUShort("EN320M"); + cfg->Reg29Spare1 = lookupToUShort("Reg29Spare1"); + cfg->no8b10b = lookupToUShort("no8b10b"); + cfg->Clk2OutCnfg = lookupToUShort("Clk2OutCnfg"); + cfg->EmptyRecord = lookupToUShort("EmptyRecord"); + cfg->Reg29Spare2 = lookupToUShort("Reg29Spare2"); + cfg->LVDSDrvEn = lookupToUShort("LVDSDrvEn"); + cfg->LVDSDrvSet30 = lookupToUShort("LVDSDrvSet30"); + cfg->LVDSDrvSet12 = lookupToUShort("LVDSDrvSet12"); + cfg->TempSensDiodeSel = lookupToUShort("TempSensDiodeSel"); + cfg->TempSensDisable = lookupToUShort("TempSensDisable"); + cfg->IleakRange = lookupToUShort("IleakRange"); + cfg->Reg30Spare = lookupToUShort("Reg30Spare"); + cfg->PlsrRiseUpTau = lookupToUShort("PlsrRiseUpTau"); + cfg->PlsrPwr = lookupToUShort("PlsrPwr"); + cfg->PlsrDelay = lookupToUShort("PlsrDelay"); + cfg->ExtDigCalSW = lookupToUShort("ExtDigCalSW"); + cfg->ExtAnaCalSW = lookupToUShort("ExtAnaCalSW"); + cfg->Reg31Spare = lookupToUShort("Reg31Spare"); + cfg->GADCSel = lookupToUShort("GADCSel"); + cfg->SELB0 = lookupToUShort("SELB0"); + cfg->SELB1 = lookupToUShort("SELB1"); + cfg->SELB2 = lookupToUShort("SELB2"); + cfg->Reg34Spare1 = lookupToUShort("Reg34Spare1"); + cfg->PrmpVbpMsnEn = lookupToUShort("PrmpVbpMsnEn"); + cfg->Reg34Spare2 = lookupToUShort("Reg34Spare2"); + cfg->Chip_SN = lookupToUShort("Chip_SN"); + cfg->Reg1Spare = lookupToUShort("Reg1Spare"); + cfg->SmallHitErase = lookupToUShort("SmallHitErase"); + cfg->Eventlimit = lookupToUShort("Eventlimit"); + + if((cfg->HitDiscCnfg==0 && cfg->SmallHitErase==0) + ||(cfg->HitDiscCnfg!=0 && cfg->SmallHitErase!=0)){ + std::cout<<"***WARNING: HitDiscCnfig="<<cfg->HitDiscCnfg<<" and SmallHitErase="<<cfg->SmallHitErase<<" on Chip with SN="<<cfg->Chip_SN<<"."<<std::endl; + } + // charge injection + config->FECalib.cinjLo=lookupToFloat("cinjLo"); + config->FECalib.cinjHi=lookupToFloat("cinjHi"); + config->FECalib.vcalCoeff[0]=lookupToFloat("vcalCoeff[0]"); + config->FECalib.vcalCoeff[1]=lookupToFloat("vcalCoeff[1]"); + config->FECalib.vcalCoeff[2]=lookupToFloat("vcalCoeff[2]"); + config->FECalib.vcalCoeff[3]=lookupToFloat("vcalCoeff[3]"); + config->FECalib.chargeCoeffClo=lookupToFloat("chargeCoeffClo"); + config->FECalib.chargeCoeffChi=lookupToFloat("chargeCoeffChi"); + config->FECalib.chargeOffsetClo=lookupToFloat("chargeOffsetClo"); + config->FECalib.chargeOffsetChi=lookupToFloat("chargeOffsetChi"); + config->FECalib.monleakCoeff=lookupToFloat("monleakCoeff"); + + //Pixel register + //Masks + setupMaskBit(ipc::enable, config, "enable"); + setupMaskBit(ipc::largeCap, config, "largeCap"); + setupMaskBit(ipc::smallCap, config, "smallCap"); + setupMaskBit(ipc::hitbus, config, "hitbus"); + + setupDAC(config->FETrims.dacThresholdTrim, "tdac"); + setupDAC(config->FETrims.dacFeedbackTrim, "fdac"); + delete m_moduleCfgFile; +} + +void FEI4BConfigFile::dump(const ipc::PixelFEI4BConfig &config){ + const ipc::PixelFEI4BGlobal* cfg=&config.FEGlobal; + std::cout<<"Global Register Fields:"<<std::endl; + std::cout<<"======================="<<std::endl; + std::cout<<"TrigCnt = "<<cfg->TrigCnt<<std::endl; + std::cout<<"Conf_AddrEnable = "<<cfg->Conf_AddrEnable<<std::endl; + std::cout<<"Reg2Spare = "<<cfg->Reg2Spare<<std::endl; + std::cout<<"ErrMask0 = "<<cfg->ErrMask0<<std::endl; + std::cout<<"ErrMask1 = "<<cfg->ErrMask1<<std::endl; + std::cout<<"PrmpVbpRight = "<<cfg->PrmpVbpRight<<std::endl; + std::cout<<"BufVgOpAmp = "<<cfg->BufVgOpAmp<<std::endl; + std::cout<<"Reg6Spare = "<<cfg->Reg6Spare<<std::endl; + std::cout<<"PrmpVbp = "<<cfg->PrmpVbp<<std::endl; + std::cout<<"TdacVbp = "<<cfg->TdacVbp<<std::endl; + std::cout<<"DisVbn = "<<cfg->DisVbn<<std::endl; + std::cout<<"Amp2Vbn = "<<cfg->Amp2Vbn<<std::endl; + std::cout<<"Amp2VbpFol = "<<cfg->Amp2VbpFol<<std::endl; + std::cout<<"Reg9Spare = "<<cfg->Reg9Spare<<std::endl; + std::cout<<"Amp2Vbp = "<<cfg->Amp2Vbp<<std::endl; + std::cout<<"FdacVbn = "<<cfg->FdacVbn<<std::endl; + std::cout<<"Amp2Vbpf = "<<cfg->Amp2Vbpf<<std::endl; + std::cout<<"PrmpVbnFol = "<<cfg->PrmpVbnFol<<std::endl; + std::cout<<"PrmpVbpLeft = "<<cfg->PrmpVbpLeft<<std::endl; + std::cout<<"PrmpVbpf = "<<cfg->PrmpVbpf<<std::endl; + std::cout<<"PrmpVbnLcc = "<<cfg->PrmpVbnLcc<<std::endl; + std::cout<<"Reg13Spare = "<<cfg->Reg13Spare<<std::endl; + std::cout<<"PxStrobes = "<<cfg->PxStrobes<<std::endl; + std::cout<<"S0 = "<<cfg->S0<<std::endl; + std::cout<<"S1 = "<<cfg->S1<<std::endl; + std::cout<<"LVDSDrvIref = "<<cfg->LVDSDrvIref<<std::endl; + std::cout<<"GADCOpAmp = "<<cfg->GADCOpAmp<<std::endl; + std::cout<<"PllIbias = "<<cfg->PllIbias<<std::endl; + std::cout<<"LVDSDrvVos = "<<cfg->LVDSDrvVos<<std::endl; + std::cout<<"TempSensBias = "<<cfg->TempSensBias<<std::endl; + std::cout<<"PllIcp = "<<cfg->PllIcp<<std::endl; + std::cout<<"Reg17Spare = "<<cfg->Reg17Spare<<std::endl; + std::cout<<"PlsrIdacRamp = "<<cfg->PlsrIdacRamp<<std::endl; + std::cout<<"VrefDigTune = "<<cfg->VrefDigTune<<std::endl; + std::cout<<"PlsrVgOPamp = "<<cfg->PlsrVgOPamp<<std::endl; + std::cout<<"PlsrDacBias = "<<cfg->PlsrDacBias<<std::endl; + std::cout<<"VrefAnTune = "<<cfg->VrefAnTune<<std::endl; + std::cout<<"Vthin_AltCoarse = "<<cfg->Vthin_AltCoarse<<std::endl; + std::cout<<"Vthin_AltFine = "<<cfg->Vthin_AltFine<<std::endl; + std::cout<<"PlsrDAC = "<<cfg->PlsrDAC<<std::endl; + std::cout<<"DIGHITIN_Sel = "<<cfg->DIGHITIN_Sel<<std::endl; + std::cout<<"DINJ_Override = "<<cfg->DINJ_Override<<std::endl; + std::cout<<"HITLD_In = "<<cfg->HITLD_In<<std::endl; + std::cout<<"Reg21Spare = "<<cfg->Reg21Spare<<std::endl; + std::cout<<"Reg22Spare2 = "<<cfg->Reg22Spare2<<std::endl; + std::cout<<"Colpr_Addr = "<<cfg->Colpr_Addr<<std::endl; + std::cout<<"Colpr_Mode = "<<cfg->Colpr_Mode<<std::endl; + std::cout<<"Reg22Spare1 = "<<cfg->Reg22Spare2<<std::endl; + std::cout<<"DisableColumnCnfg0 = "<<cfg->DisableColumnCnfg0<<std::endl; + std::cout<<"DisableColumnCnfg1 = "<<cfg->DisableColumnCnfg1<<std::endl; + std::cout<<"DisableColumnCnfg2 = "<<cfg->DisableColumnCnfg2<<std::endl; + std::cout<<"TrigLat = "<<cfg->TrigLat<<std::endl; + std::cout<<"CMDcnt = "<<cfg->CMDcnt<<std::endl; + std::cout<<"StopModeCnfg = "<<cfg->StopModeCnfg<<std::endl; + std::cout<<"HitDiscCnfg = "<<cfg->HitDiscCnfg<<std::endl; + std::cout<<"EN_PLL = "<<cfg->EN_PLL<<std::endl; + std::cout<<"Efuse_sense = "<<cfg->Efuse_sense<<std::endl; + std::cout<<"Stop_Clk = "<<cfg->Stop_Clk<<std::endl; + std::cout<<"ReadErrorReq = "<<cfg->ReadErrorReq<<std::endl; + std::cout<<"Reg27Spare1 = "<<cfg->Reg27Spare1<<std::endl; + std::cout<<"GADC_Enable = "<<cfg->GADC_Enable<<std::endl; + std::cout<<"ShiftReadBack = "<<cfg->ShiftReadBack<<std::endl; + std::cout<<"Reg27Spare2 = "<<cfg->Reg27Spare2<<std::endl; + std::cout<<"GateHitOr = "<<cfg->GateHitOr<<std::endl; + std::cout<<"CalEn = "<<cfg->CalEn<<std::endl; + std::cout<<"SR_clr = "<<cfg->SR_clr<<std::endl; + std::cout<<"Latch_en = "<<cfg->Latch_en<<std::endl; + std::cout<<"SR_Clock = "<<cfg->SR_Clock<<std::endl; + std::cout<<"LVDSDrvSet06 = "<<cfg->LVDSDrvSet06<<std::endl; + std::cout<<"Reg28Spare = "<<cfg->Reg28Spare<<std::endl; + std::cout<<"EN40M = "<<cfg->EN40M<<std::endl; + std::cout<<"EN80M = "<<cfg->EN80M<<std::endl; + std::cout<<"CLK1 = "<<cfg->CLK1<<std::endl; + std::cout<<"CLK0 = "<<cfg->CLK0<<std::endl; + std::cout<<"EN160M = "<<cfg->EN160M<<std::endl; + std::cout<<"EN320M = "<<cfg->EN320M<<std::endl; + std::cout<<"Reg29Spare1 = "<<cfg->Reg29Spare1<<std::endl; + std::cout<<"no8b10b = "<<cfg->no8b10b<<std::endl; + std::cout<<"Clk2OutCnfg = "<<cfg->Clk2OutCnfg<<std::endl; + std::cout<<"EmptyRecord = "<<cfg->EmptyRecord<<std::endl; + std::cout<<"Reg29Spare2 = "<<cfg->Reg29Spare2<<std::endl; + std::cout<<"LVDSDrvEn = "<<cfg->LVDSDrvEn<<std::endl; + std::cout<<"LVDSDrvSet30 = "<<cfg->LVDSDrvSet30<<std::endl; + std::cout<<"LVDSDrvSet12 = "<<cfg->LVDSDrvSet12<<std::endl; + std::cout<<"TempSensDiodeSel = "<<cfg->TempSensDiodeSel<<std::endl; + std::cout<<"TempSensDisable = "<<cfg->TempSensDisable<<std::endl; + std::cout<<"IleakRange = "<<cfg->IleakRange<<std::endl; + std::cout<<"PlsrRiseUpTau = "<<cfg->PlsrRiseUpTau<<std::endl; + std::cout<<"PlsrPwr = "<<cfg->PlsrPwr<<std::endl; + std::cout<<"PlsrDelay = "<<cfg->PlsrDelay<<std::endl; + std::cout<<"ExtDigCalSW = "<<cfg->ExtDigCalSW<<std::endl; + std::cout<<"ExtAnaCalSW = "<<cfg->ExtAnaCalSW<<std::endl; + std::cout<<"Reg31Spare = "<<cfg->Reg31Spare<<std::endl; + std::cout<<"SELB0 = "<<cfg->SELB0<<std::endl; + std::cout<<"SELB1 = "<<cfg->SELB1<<std::endl; + std::cout<<"SELB2 = "<<cfg->SELB2<<std::endl; + std::cout<<"Reg34Spare1 = "<<cfg->Reg34Spare1<<std::endl; + std::cout<<"PrmpVbpMsnEn = "<<cfg->PrmpVbpMsnEn<<std::endl; + std::cout<<"Reg34Spare2 = "<<cfg->Reg34Spare2<<std::endl; + std::cout<<"Chip_SN = "<<cfg->Chip_SN<<std::endl; + std::cout<<"Reg1Spare = "<<cfg->Reg1Spare<<std::endl; + std::cout<<"SmallHitErase = "<<cfg->SmallHitErase<<std::endl; + std::cout<<"Eventlimit = "<<cfg->Eventlimit<<std::endl; + // charge injection + std::cout<<std::endl; + std::cout<<"Charge injection parameters:"<<std::endl; + std::cout<<"============================"<<std::endl; + std::cout<<"cinjLo = "<<config.FECalib.cinjLo<<std::endl; + std::cout<<"cinjHi = "<<config.FECalib.cinjHi<<std::endl; + std::cout<<"vcalCoeff[0] = "<<config.FECalib.vcalCoeff[0]<<std::endl; + std::cout<<"vcalCoeff[1] = "<<config.FECalib.vcalCoeff[1]<<std::endl; + std::cout<<"vcalCoeff[2] = "<<config.FECalib.vcalCoeff[2]<<std::endl; + std::cout<<"vcalCoeff[3] = "<<config.FECalib.vcalCoeff[3]<<std::endl; + std::cout<<"chargeCoeffClo = "<<config.FECalib.chargeCoeffClo<<std::endl; + std::cout<<"chargeCoeffChi = "<<config.FECalib.chargeCoeffChi<<std::endl; + std::cout<<"chargeOffsetClo = "<<config.FECalib.chargeOffsetClo<<std::endl; + std::cout<<"chargeOffsetChi = "<<config.FECalib.chargeOffsetChi<<std::endl; + std::cout<<"monleakCoeff = "<<config.FECalib.monleakCoeff<<std::endl; + + //DACs + std::cout<<"Threshold DAC:"<<std::endl; + std::cout<<"--------------"<<std::endl; + dumpDac(config.FETrims.dacThresholdTrim); + std::cout<<"Feedback DAC:"<<std::endl; + std::cout<<"-------------"<<std::endl; + dumpDac(config.FETrims.dacFeedbackTrim); + + //Masks + std::cout<<"Enable Mask:"<<std::endl; + std::cout<<"------------"<<std::endl; + dumpMask(ipc::enable, config); + std::cout<<"Large Cap Mask:"<<std::endl; + std::cout<<"---------------"<<std::endl; + dumpMask(ipc::largeCap, config); + std::cout<<"Small Cap Mask:"<<std::endl; + std::cout<<"---------------"<<std::endl; + dumpMask(ipc::smallCap, config); + std::cout<<"Hitbus Mask:"<<std::endl; + std::cout<<"------------"<<std::endl; + dumpMask(ipc::hitbus, config); + +} + +void FEI4BConfigFile::dumpDac(const unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS]){ + std::cout<<(unsigned)trim[0][0]<<" "<<(unsigned)trim[79][335]<<std::endl; + for (int i=0;i<674;i++){ + if(i>1){ + printf("%3d",i/2); + if(i%2==0)std::cout<<"a "; + else std::cout<<"b "; + }else{ + std::cout<<"### "; + } + for (int j=1;j<=40;j++){ + if(i<2){ + if(i==0)printf("%2d ",j); + else printf("%2d ",j+40); + }else{ + if(i%2==0)printf("%2d ",trim[j-1][i/2-1]); + else printf("%2d ",trim[j+39][i/2-1]); + } + if(j%10==0)std::cout<<" "; + } + std::cout<<std::endl; + } + std::cout<<std::endl; + } + + void FEI4BConfigFile::dumpMask(const long int bit, const ipc::PixelFEI4BConfig& cfg){ + + for (int i=0;i<=336;i++){ + if(i==0){ + std::cout<<"### 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76"<<std::endl; + } + else{ + printf("%3d ",i); + for (int j=1;j<=80;j++){ + printf("%1d",(cfg.FEMasks[j-1][i-1]>>bit)&0x1); + if(j%10==0)std::cout<<" "; + else if(j%5==0)std::cout<<"-"; + } + std::cout<<std::endl; + } + } + std::cout<<std::endl; + } diff --git a/rce/rcecalib/server/FEI4BConfigFile.hh b/rce/rcecalib/server/FEI4BConfigFile.hh new file mode 100644 index 0000000000000000000000000000000000000000..ad1b4c6c4cec9634c8347174cd60aa0c7c8b7af9 --- /dev/null +++ b/rce/rcecalib/server/FEI4BConfigFile.hh @@ -0,0 +1,32 @@ +#ifndef FEI4BCONFIGFILE_HH +#define FEI4BCONFIGFILE_HH + +#include "PixelFEI4BConfig.hh" +#include <string> +#include <map> + +class FEI4BConfigFile { +public: + FEI4BConfigFile(){} + ~FEI4BConfigFile(); + void readModuleConfig(ipc::PixelFEI4BConfig* cfg, std::string filename); + void writeModuleConfig(ipc::PixelFEI4BConfig* cfg, const std::string &base, const std::string &confdir, const std::string &configname, const std::string &key); + void writeMaskFile(const long int bit, ipc::PixelFEI4BConfig* config, const std::string &filename); + void writeDacFile(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , const std::string filename); + void dump(const ipc::PixelFEI4BConfig& cfg); +private: + std::string getFullPath(std::string relPath); + void setupDAC(unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS] , std::string par); + void setupMaskBit(const long int bit, ipc::PixelFEI4BConfig *cfg, std::string par); + void dumpMask(const long int bit, const ipc::PixelFEI4BConfig& cfg); + unsigned short lookupToUShort(std::string par); + int convertToUShort(std::string par, unsigned short& val); + float lookupToFloat(std::string par); + void dumpDac(const unsigned char trim[][ipc::IPC_N_I4_PIXEL_ROWS]); + + std::string m_moduleCfgFilePath; + std::ifstream *m_moduleCfgFile; + std::map<std::string, std::string> m_params; +}; + +#endif diff --git a/rce/rcecalib/server/GlobalConfigGui.cc b/rce/rcecalib/server/GlobalConfigGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..e37c100c8782b8fb221c404988a80ad70b365c2f --- /dev/null +++ b/rce/rcecalib/server/GlobalConfigGui.cc @@ -0,0 +1,560 @@ +#include "rcecalib/server/GlobalConfigGui.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/HitbusConfigFile.hh" +#include "PixelFEI4AConfig.hh" +#include "PixelFEI4BConfig.hh" +#include "PixelModuleConfig.hh" +#include "rcecalib/server/ConfigGui.hh" +#include <TGFileDialog.h> +#include <iostream> +#include <boost/regex.hpp> +#include <sys/stat.h> +#include <sstream> +#ifdef SQLDB +#include <mysql.h> +#endif + +GlobalConfigGui::GlobalConfigGui(ConfigGui* cg[], const char* dffile, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options): + TGVerticalFrame(p,w,h,options), m_config(cg), m_defaultfile(dffile){ + + m_name=new TGLabel(this,"Global Module Configuration"); + AddFrame(m_name,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 10, 0)); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_name->SetTextFont(labelfont); + + TGHorizontalFrame *conf0 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf0,new TGLayoutHints(kLHintsExpandX )); + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-14-*-*-*-*-*-iso8859-1"); + m_update=new TGTextButton(conf0,"Update"); + m_update->SetFont(labelfont); + m_update->SetMargins(5,10,5,5); + m_update->Connect("Clicked()", "GlobalConfigGui", this,"update()"); + conf0->AddFrame(m_update,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + TGTextButton *sd=new TGTextButton(conf0,"Save"); + sd->Connect("Clicked()", "GlobalConfigGui", this,"saveDefault()"); + sd->SetFont(labelfont); + sd->SetMargins(5,10,5,5); + conf0->AddFrame(sd,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_save=new TGTextButton(conf0,"Save As"); + m_save->Connect("Clicked()", "GlobalConfigGui", this,"save()"); + m_save->SetFont(labelfont); + m_save->SetMargins(5,10,5,5); + conf0->AddFrame(m_save,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_load=new TGTextButton(conf0,"Load"); + m_load->Connect("Clicked()", "GlobalConfigGui", this,"load()"); + m_load->SetFont(labelfont); + m_load->SetMargins(5,10,5,5); + conf0->AddFrame(m_load,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + TGLabel *masklabel=new TGLabel(conf0,"Config Name:"); + FontStruct_t maskfont= gClient->GetFontByName("-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1"); + masklabel->SetTextFont(maskfont); + conf0->AddFrame(masklabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_name=new TGLabel(conf0," "); + conf0->AddFrame(m_name,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + masklabel=new TGLabel(conf0,"Key:"); + masklabel->SetTextFont(maskfont); + conf0->AddFrame(masklabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_key=new TGLabel(conf0," "); + conf0->AddFrame(m_key,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + + // Config directory + + FontStruct_t clabelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + FontStruct_t cmaskfont= gClient->GetFontByName("-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1"); + m_conf1 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(m_conf1,new TGLayoutHints(kLHintsExpandX )); + TGLabel *ddlabel=new TGLabel(m_conf1,"Config Root Dir:"); + m_conf1->AddFrame(ddlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 10, 0)); + ddlabel->SetTextFont(clabelfont); + m_rootdirl=new TGLabel(m_conf1, " "); + m_rootdirl->SetTextFont(cmaskfont); + m_conf1->AddFrame(m_rootdirl,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 10, 0)); + TGTextButton *lddd=new TGTextButton(m_conf1,"Browse"); + lddd->Connect("Clicked()", "GlobalConfigGui", this,"guiSetRootDir()"); + lddd->SetFont(clabelfont); + lddd->SetMargins(10,15,3,3); + m_conf1->AddFrame(lddd,new TGLayoutHints(kLHintsCenterY | kLHintsRight ,2,2,5,5)); + TGTextButton *absp=new TGTextButton(m_conf1,"Abs Path"); + absp->Connect("Clicked()", "GlobalConfigGui", this,"setAbsPath()"); + absp->SetFont(clabelfont); + absp->SetMargins(10,15,3,3); + m_conf1->AddFrame(absp,new TGLayoutHints(kLHintsCenterY | kLHintsRight ,2,2,5,5)); + + // Data directory + + m_conf2 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(m_conf2,new TGLayoutHints(kLHintsExpandX )); + ddlabel=new TGLabel(m_conf2,"Data Dir:"); + m_conf2->AddFrame(ddlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 10, 0)); + ddlabel->SetTextFont(clabelfont); + m_datadir=new TGLabel(m_conf2, " "); + m_datadir->SetTextFont(cmaskfont); + m_conf2->AddFrame(m_datadir,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 10, 0)); + lddd=new TGTextButton(m_conf2,"Browse"); + lddd->Connect("Clicked()", "GlobalConfigGui", this,"guiSetDataDir()"); + lddd->SetFont(clabelfont); + lddd->SetMargins(10,15,3, 3); + m_conf2->AddFrame(lddd,new TGLayoutHints(kLHintsCenterY | kLHintsRight ,2,2,5,5)); + + // Run Number + TGHorizontalFrame *datapanel2 = new TGHorizontalFrame(this, 2, 2, kSunkenFrame); + AddFrame(datapanel2,new TGLayoutHints(kLHintsExpandX )); + TGLabel *runlabel=new TGLabel(datapanel2,"Run Number:"); + runlabel->SetTextFont(clabelfont); + datapanel2->AddFrame(runlabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 10, 0)); + FontStruct_t labelfont2; + labelfont2 = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-24-*-*-*-*-*-iso8859-1"); + m_runno=new TGNumberEntry(datapanel2,0,5,-1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative); + m_runno->GetNumberEntry()->SetFont(labelfont2); + m_runno->SetHeight(30); + m_runno->SetWidth(140); + //reset RunNum if SQLDB +#ifdef SQLDB + m_runno->SetIntNumber(maxRunNum()); + m_runno->SetState(false); +#endif + // m_name->Connect("TextChanged(const char*)", "CalibGui", this,"setName(const char*)"); + datapanel2->AddFrame(m_runno,new TGLayoutHints(kLHintsCenterY |kLHintsCenterX, 5, 5, 5, 5)); + + gClient->GetColorByName("red", m_red); + m_homedir=std::string(getenv("HOME")); + +} + + +GlobalConfigGui::~GlobalConfigGui(){ + Cleanup(); +} + +void GlobalConfigGui::guiSetDataDir(){ + std::string dirs=setDir(); + if(dirs!="")setDataDir(dirs.c_str()); +} + +void GlobalConfigGui::setDataDir(const char* dd){ + m_datadir->SetText(dd); + m_conf2->Layout(); + m_ddir=dd; +} + +void GlobalConfigGui::updateText(TGLabel* label, const char* newtext){ + //unsigned len=strlen(label->GetText()->GetString()); + label->SetText(newtext); + //if (strlen(newtext)>len)Layout(); + Layout(); +} + +void GlobalConfigGui::enableControls(bool on){ + #ifndef SQLDB + m_runno->SetState(on); + #endif + m_save->SetEnabled(on); + m_load->SetEnabled(on); + m_update->SetEnabled(on); +} + +void GlobalConfigGui::print(std::ostream &os){ +} + +void GlobalConfigGui::updateAvailable(bool on){ + if(on)m_update->SetTextColor(m_red); + else m_update->SetTextColor(0); + m_upd=on; + Layout(); +} + +void GlobalConfigGui::save(){ + const char *filetypes[] = { "Config files", "*.cfg", + "All files", "*", + 0, 0 }; + bool sth=false; + for(int i=0;i<ConfigGui::MAX_MODULES;i++)if(m_config[i]->isIncluded())sth=true; + if(sth==false){ + std::cout<<"Nothing to save."<<std::endl; + return; + } + TGFileInfo fileinfo; + if(m_path!="") + fileinfo.fIniDir=StrDup(m_path.c_str()); + else + fileinfo.fIniDir=StrDup(m_rootdir.c_str()); + fileinfo.fFileTypes = filetypes; + fileinfo.fFilename=0; + char newconfigname[512]; + std::string oldname=m_name->GetText()->Data(); + if(oldname!=" " && oldname!="Unknown"){ + sprintf(newconfigname, "%s__%d.cfg", oldname.c_str(),getRunNumber()); + fileinfo.fFilename=StrDup(newconfigname); + } + new TGFileDialog(gClient->GetRoot(), 0, kFDSave, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + m_filename=fileinfo.fFilename; + if(m_filename.size()<4 || m_filename.substr(m_filename.size()-4,4)!=".cfg")m_filename+=".cfg"; + setupDisplay(); + saveConfig(); +} +void GlobalConfigGui::saveConfig(){ + copyConfig(m_filename.c_str()); +} +void GlobalConfigGui::copyConfig(const char *filename){ + std::ofstream of(filename); + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + m_config[i]->writeConfig(of); + } +} + + + +void GlobalConfigGui::load(){ + const char *filetypes[] = { "Config files", "*.cfg", + "All files", "*", + 0, 0 }; + TGFileInfo fileinfo; + if(std::string(m_name->GetText()->Data())!="Default" && m_path!="") + fileinfo.fIniDir=StrDup(m_path.c_str()); + else + fileinfo.fIniDir=StrDup(m_rootdir.c_str()); + fileinfo.fFileTypes = filetypes; + fileinfo.fFilename=StrDup(m_cfgpluskey.c_str()); + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + m_filename=fileinfo.fFilename; + setupDisplay(); + loadConfig(); +} + +void GlobalConfigGui::load(const char* filename){ + m_filename=filename; + setupDisplay(); + loadConfig(); +} + +void GlobalConfigGui::loadConfig(){ + // Attempt to get the file attributes + struct stat stFileInfo; + int intStat; + intStat = stat(m_filename.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist} + m_filename="None"; + setupDisplay(); + return; + } + std::ifstream cfgFile(m_filename.c_str()); + std::string filename; + for(int i=0;i<ConfigGui::MAX_MODULES;i++){ + m_config[i]->readConfig(cfgFile); + } +} + +void GlobalConfigGui::update(){ + if(m_upd==false)return; + // Attempt to get the file attributes + struct stat stFileInfo; + int intStat; + char fname[512]; + sprintf(fname, "%stop/config__%d.cfg", m_configdir.c_str(), getRunNumber()); + intStat = stat(fname,&stFileInfo); + if(intStat != 0) { //File does not exist} + std::cout<<"There is no top level config file for this run."<<std::endl; + return; + } + const char *filetypes[] = { "Config files", "*.cfg", + "All files", "*", + 0, 0 }; + std::string oldname=m_name->GetText()->Data(); + if(oldname!=" " && oldname!="Unknown") + { + m_filename=m_path+oldname+Form("__%d.cfg",getRunNumber()); + } + else{ + TGFileInfo fileinfo; + fileinfo.fIniDir=StrDup(m_rootdir.c_str()); + fileinfo.fFileTypes = filetypes; + fileinfo.fFilename=0; + new TGFileDialog(gClient->GetRoot(), 0, kFDSave, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + m_filename=fileinfo.fFilename; + if(m_filename.size()<4 || m_filename.substr(m_filename.size()-4,4)!=".cfg")m_filename+=".cfg"; + } + updateAvailable(false); + setupDisplay(); + std::ifstream oldfile(fname); + std::ofstream newfile(m_filename.c_str()); + int chan; + std::string filename, oldfilename, oldfilenamenopath; + int ind=0; + while (oldfile.good()){ + oldfile>>oldfilenamenopath; + if(oldfilenamenopath[0]!='/')oldfilename=m_rootdir+oldfilenamenopath; //relative path + else oldfilename=oldfilenamenopath; + filename=oldfilename; + if(oldfile.eof())break; + boost::regex re("configUpdate"); + bool docopy=false; + std::string path=m_config[ind]->getPath(); + if(path.substr(0,m_rootdir.size())==m_rootdir)path=path.substr(m_rootdir.size()); + if(boost::regex_search(filename.c_str(), re)){ + filename.replace(0,m_configdir.size(), path); + docopy=true; + newfile<<filename<<std::endl; + }else{ + newfile<<oldfilenamenopath<<std::endl; + } + for(int i=0;i<5;i++){ + oldfile>>chan; + newfile<<chan<<std::endl; + } + if(docopy==true){ + if(m_config[ind]->getType()=="FEI3"){ + ipc::PixelModuleConfig* cf=new ipc::PixelModuleConfig; + TurboDaqFile turbodaqfile; + turbodaqfile.readModuleConfig(cf, oldfilename); + char key[32]; + sprintf(key, "%d", getRunNumber()); + turbodaqfile.writeModuleConfig(cf, m_config[ind]->getPath(), + m_config[ind]->getConfdir(), + m_config[ind]->getConfigName(), + key); + delete cf; + }else if(m_config[ind]->getType()=="FEI4A"){ + ipc::PixelFEI4AConfig* cf=new ipc::PixelFEI4AConfig; + FEI4AConfigFile fei4afile; + fei4afile.readModuleConfig(cf, oldfilename); + char key[32]; + sprintf(key, "%d", getRunNumber()); + fei4afile.writeModuleConfig(cf, m_config[ind]->getPath(), + m_config[ind]->getConfdir(), + m_config[ind]->getConfigName(), + key); + delete cf; + }else if(m_config[ind]->getType()=="FEI4B"){ + ipc::PixelFEI4BConfig* cf=new ipc::PixelFEI4BConfig; + FEI4BConfigFile fei4bfile; + fei4bfile.readModuleConfig(cf, oldfilename); + char key[32]; + sprintf(key, "%d", getRunNumber()); + fei4bfile.writeModuleConfig(cf, m_config[ind]->getPath(), + m_config[ind]->getConfdir(), + m_config[ind]->getConfigName(), + key); + delete cf; + }else if(m_config[ind]->getType()=="Hitbus"){ + ipc::HitbusModuleConfig* cf=new ipc::HitbusModuleConfig; + HitbusConfigFile hitbusfile; + hitbusfile.readModuleConfig(cf, oldfilename); + char key[32]; + sprintf(key, "%d", getRunNumber()); + hitbusfile.writeModuleConfig(cf, m_config[ind]->getPath(), + m_config[ind]->getConfdir(), + m_config[ind]->getConfigName(), + key); + delete cf; + } + + + } + ind++; + } + newfile.close(); + loadConfig(); +} + +void GlobalConfigGui::setConfigDir(const char* name){ + m_configdir=name; + mkdir((m_configdir+"top").c_str(), 0777); +} + +void GlobalConfigGui::saveDefault(){ + std::ofstream of((m_homedir+m_defaultfile).c_str()); + writeGuiConfig(of); + of.close(); +} + +void GlobalConfigGui::writeGuiConfig(std::ofstream &ofile){ + if(m_filename=="None") + m_filename=std::string(getenv("HOME"))+"/"+"Default.cfg"; + ofile<<getRunNumber()<<std::endl; + ofile<<m_filename<<std::endl; + ofile<<m_ddir<<std::endl; + ofile<<m_rootdir<<std::endl; + saveConfig(); +} + +void GlobalConfigGui::readGuiConfig(std::ifstream &ifile){ + int runno; + ifile>>runno; + setRunNumber(runno); + std::string filename; + ifile>>m_filename; + std::string datadir; + ifile>>datadir; + if(datadir=="")datadir=m_homedir+"/calibData"; + setDataDir(datadir.c_str()); + std::string configdir; + ifile>>configdir; + setRootDir(configdir.c_str()); + setupDisplay(); + loadConfig(); +} + +void GlobalConfigGui::setupDisplay(){ + boost::cmatch matches; + //std::string res="/([^/]*)\\.cfg$"; // parse what's hopefully the config file name + boost::regex re; + std::string res("(^.*\\/)(.+)\\.cfg$"); + re=res; + if(boost::regex_search(m_filename.c_str(), matches, re)){ + if(matches.size()>2){ + m_path=std::string(matches[1].first, matches[1].second); + m_cfgpluskey=std::string(matches[2].first, matches[2].second); + res="(.*)__([0-9]+)$"; // parse what's hopefully the key + re=res; + if(boost::regex_search(m_cfgpluskey.c_str(), matches, re)){ + if(matches.size()>2){ + std::string match1(matches[1].first, matches[1].second); + std::string match2(matches[2].first, matches[2].second); + updateText(m_name,match1.c_str()); + updateText(m_key,match2.c_str()); + }else{ + updateText(m_name,m_cfgpluskey.c_str()); + updateText(m_key,""); + } + }else{ + updateText(m_name,m_cfgpluskey.c_str()); + updateText(m_key,""); + } + }else{ + updateText(m_name,"Unknown"); + updateText(m_key,"Unknown"); + m_path=""; + } + }else{ + updateText(m_name,"Unknown"); + updateText(m_key,"Unknown"); + m_path=""; + } +} +void GlobalConfigGui::filePrompt()//Prompt for name of config file +{ + const char *filetypes[] = { "Config files", "*.cfg", + "All files", "*", + 0, 0 }; + TGFileInfo fileinfo; + fileinfo.fIniDir=0; + fileinfo.fFileTypes = filetypes; + fileinfo.fFilename=0; + new TGFileDialog(gClient->GetRoot(), 0, kFDSave, &fileinfo); + m_filename=fileinfo.fFilename; + if(m_filename.size()<4 || m_filename.substr(m_filename.size()-4,4)!=".cfg")m_filename+=".cfg"; + setupDisplay(); + std::cout << "File name " << m_filename << std::endl; +} +bool GlobalConfigGui::oldFileLoaded() +{ + std::string oldname=m_name->GetText()->Data(); + + return oldname!=" " && oldname!="Unknown"; +} + +std::string GlobalConfigGui::setDir(){ + const char *filetypes[] = { "Directory", "*/", 0, 0 }; + TGFileInfo fileinfo; + fileinfo.fIniDir=0; + //fileinfo.fIniDir=StrDup(m_path.c_str()); + fileinfo.fFileTypes = filetypes; + //fileinfo.fFilename=StrDup(m_cfgpluskey.c_str()); + fileinfo.fFilename=0; + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return ""; + } + std::string datadir; + struct stat stFileInfo; + int intStat; + // Root TGFileinfo is a mess, have to try multiple options + intStat = stat(fileinfo.fFilename,&stFileInfo); + if(intStat != 0) { //File does not exist + intStat = stat(fileinfo.fIniDir,&stFileInfo); + if(intStat !=0) { // File does not exist + std::cout<<"Directory does not exist"<<std::endl; + }else{ + datadir=fileinfo.fIniDir; + } + }else{ + datadir=fileinfo.fFilename; + } + return datadir; +} + +void GlobalConfigGui::guiSetRootDir(){ + std::string dirs=setDir(); + if(dirs!="") setRootDir(dirs.c_str()); +} + + +void GlobalConfigGui::setRootDir(const char* dd){ + m_rootdirl->SetText(dd); + m_conf1->Layout(); + m_rootdir=dd; + if(m_rootdir.size()>0 && m_rootdir[m_rootdir.size()-1]!='/')m_rootdir+="/"; + m_config[0]->setRootDir(m_rootdir); //static function +} +void GlobalConfigGui::setAbsPath(){ + m_rootdirl->SetText(""); + m_conf1->Layout(); + m_rootdir=""; + m_config[0]->setRootDir(m_rootdir); //static function +} + +// Does not increment anymore, increment is happening in maxRunNum +// just being lazy +int GlobalConfigGui::incrementRunNumber(){ + int newrunno=maxRunNum(); + m_runno->SetIntNumber(newrunno); + return newrunno; +} + +int GlobalConfigGui::maxRunNum() +{ + #ifdef SQLDB + MYSQL *conn; + MYSQL_RES *result; + MYSQL_ROW row; + conn = mysql_init(NULL); + std::string dbName="RCECalibRuns"; + #ifdef SQLDEBUG + dbName="RCECalibRunsDev"; + #endif + if(mysql_real_connect(conn, "pixiblsr1daq1", "DBWriter", "W#1ter", dbName.c_str(), 0, NULL, 0)==NULL) + { + + std::cout << "SQL connection to " << dbName << " failed!! Nothing will be inserted!" <<std::endl; + //m_primList->updateStatus("Failed to connect to SQL database!"); + return m_runno->GetIntNumber(); + } + //mysql_query(conn, "SELECT max(RunNum) FROM CalibRunLog"); + mysql_query(conn, "INSERT INTO CalibRunLog (RunNum) VALUES(NULL);"); + mysql_query(conn, "SELECT LAST_INSERT_ID();"); + result = mysql_store_result(conn); + row= mysql_fetch_row(result); + int maxNum; + std::stringstream(row[0]) >> maxNum; + mysql_free_result(result); + mysql_close(conn); + return maxNum; + #endif + return m_runno->GetIntNumber()+1; +} diff --git a/rce/rcecalib/server/GlobalConfigGui.hh b/rce/rcecalib/server/GlobalConfigGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..03e85d792b5e1fa316ea038649832f17e4c75403 --- /dev/null +++ b/rce/rcecalib/server/GlobalConfigGui.hh @@ -0,0 +1,71 @@ +#ifndef GLOBALCONFIGGUI_HH +#define GLOBALCONFIGGUI_HH + +#include <TGButton.h> +#include <TGTextEntry.h> +#include <TGLabel.h> +#include <TGComboBox.h> +#include <fstream> +#include <string> +#include <map> +#include "TGNumberEntry.h" + +class ConfigGui; + +class GlobalConfigGui: public TGVerticalFrame{ +public: + GlobalConfigGui(ConfigGui* cfg[], const char* filename, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options); + virtual ~GlobalConfigGui(); + void print(std::ostream &os); + void enableControls(bool on); + void updateAvailable(bool on); + void save(); + void saveConfig(); + void copyConfig(const char* filename); + void saveDefault(); + void load(); + void load(const char* filename); + void loadConfig(); + void update(); + void setupDisplay(); + void readGuiConfig(std::ifstream &in); + void writeGuiConfig(std::ofstream &out); + void setConfigDir(const char* name); + void filePrompt(); + bool oldFileLoaded(); + std::string setDir(); + void setRootDir(const char* dd); + void guiSetRootDir(); + void setAbsPath(); + std::string getConfigName(){ return m_cfgpluskey; } + const char* getDataDir(){return m_ddir.c_str();} + void setDataDir(const char* dd); + void guiSetDataDir(); + int getRunNumber(){return m_runno->GetIntNumber();} + void setRunNumber(int runno){m_runno->SetIntNumber(runno);} + int incrementRunNumber(); +private: + int maxRunNum(); + TGLabel *m_name; + TGLabel *m_key; + TGLabel *m_rootdirl; + TGLabel *m_datadir; + TGNumberEntry *m_runno; + TGTextButton *m_update, *m_save, *m_load; + TGHorizontalFrame *m_conf1, *m_conf2; + ConfigGui **m_config; + bool m_upd; + std::string m_filename; + std::string m_configdir; + std::string m_path; + std::string m_cfgpluskey; + std::string m_homedir; + std::string m_rootdir; + std::string m_ddir; + std::string m_defaultfile; + Pixel_t m_red; + void updateText(TGLabel* label, const char* newtext); + ClassDef(GlobalConfigGui,0); +}; + +#endif diff --git a/rce/rcecalib/server/HitbusConfigFile.cc b/rce/rcecalib/server/HitbusConfigFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..b5f6df0a1afabc5568a78c3b347243aae6b737a3 --- /dev/null +++ b/rce/rcecalib/server/HitbusConfigFile.cc @@ -0,0 +1,146 @@ +#include "rcecalib/server/HitbusConfigFile.hh" +#include "rcecalib/util/exceptions.hh" +#include <boost/algorithm/string.hpp> +#include <iostream> +#include <fstream> +#include <vector> +#include <sys/stat.h> + +HitbusConfigFile::~HitbusConfigFile(){} + +unsigned short HitbusConfigFile::lookupToUShort(std::string par){ + if( m_params.find(par)==m_params.end()){ + std::cout<<"Parameter "<<par<<" does not exist."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::string vals=m_params[par]; + unsigned short val; + int success=convertToUShort(vals, val); + if(success==false){ + std::cout<<"Bad value "<<vals<< " for parameter "<<par<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return val; +} + +int HitbusConfigFile::convertToUShort(std::string par, unsigned short& val){ + char* end; + val=strtoul(par.c_str(), &end, 0); + if(end-par.c_str()!=(int)par.size()){ + return 0; + } + if((val&0xffff0000)!=0){ + std::cout<<"Value "<<val<<" too large."<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return 1; +} + +void HitbusConfigFile::writeModuleConfig(ipc::HitbusModuleConfig* config, const std::string &base, const std::string &confdir, + const std::string &configname, const std::string &key){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(base.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<" does not exist. Not writing config file"<<std::endl; + return; + } + intStat = stat((base+"/"+confdir).c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + //std::cout<<"Directory "<<base<<"/"<<confdir<<" does not exist. Creating."<<std::endl; + mkdir ((base+"/"+confdir).c_str(),0777); + } + std::string cfgname=configname; + if(key.size()!=0)cfgname+="__"+key; + std::string fullpath=base+"/"+confdir+"/"+cfgname+".cfg"; + std::ofstream cfgfile(fullpath.c_str()); + cfgfile<<"# Hitbus Chip Configuration"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Module name"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"ModuleID\t\t"<<config->idStr<<std::endl; + cfgfile<<std::endl; + cfgfile<<"# Registers"<<std::endl; + cfgfile<<std::endl; + //Register + cfgfile<<"bpm\t\t\t"<<(unsigned)config->bpm<<std::endl; + cfgfile<<"delay_tam1\t\t"<<(unsigned)config->delay_tam1<<std::endl; + cfgfile<<"delay_tam2\t\t"<<(unsigned)config->delay_tam2<<std::endl; + cfgfile<<"delay_tam3\t\t"<<(unsigned)config->delay_tam3<<std::endl; + cfgfile<<"delay_tbm1\t\t"<<(unsigned)config->delay_tbm1<<std::endl; + cfgfile<<"delay_tbm2\t\t"<<(unsigned)config->delay_tbm2<<std::endl; + cfgfile<<"delay_tbm3\t\t"<<(unsigned)config->delay_tbm3<<std::endl; + cfgfile<<"bypass_delay\t\t"<<(unsigned)config->bypass_delay<<std::endl; + cfgfile<<"clock\t\t\t"<<"0x"<<std::hex<<(unsigned)config->clock<<std::dec<<std::endl; + cfgfile<<"function_A\t\t"<<"0x"<<std::hex<<(unsigned)config->function_A<<std::dec<<std::endl; + cfgfile<<"function_B\t\t"<<"0x"<<std::hex<<(unsigned)config->function_B<<std::dec<<std::endl; +} + +void HitbusConfigFile::readModuleConfig(ipc::HitbusModuleConfig* config, std::string filename){ + //clear structure + char* ccfg=(char*)config; + for (unsigned int i=0;i<sizeof(ipc::HitbusModuleConfig);i++)ccfg[i]=0; + //open file + m_moduleCfgFile=new std::ifstream(filename.c_str()); + if(!m_moduleCfgFile->good()){ + std::cout<<"Cannot open file with name "<<filename<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + m_moduleCfgFilePath = filename; + // parse config file + std::string inpline; + m_params.clear(); + while(true){ + getline(*m_moduleCfgFile, inpline); + if(m_moduleCfgFile->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ //remove comment lines and empty lines + std::vector<std::string> splitVec; + split( splitVec, inpline, boost::is_any_of(" \t"), boost::token_compress_on ); + if(splitVec.size()<2){ + std::cout<<"Bad input line "<<inpline<<std::endl; + continue; + } + m_params[splitVec[0]]=splitVec[1]; + } + } + // Module name + std::string modname=""; + if( m_params.find("ModuleID")==m_params.end()){ + std::cout<<"No Module ID defined."<<std::endl; + }else{ + modname=m_params["ModuleID"]; + } + sprintf((char*)config->idStr, "%s", modname.c_str()); + //Registers + config->bpm = lookupToUShort("bpm"); + config->delay_tam1 = lookupToUShort("delay_tam1"); + config->delay_tam2 = lookupToUShort("delay_tam2"); + config->delay_tam3 = lookupToUShort("delay_tam3"); + config->delay_tbm1 = lookupToUShort("delay_tbm1"); + config->delay_tbm2 = lookupToUShort("delay_tbm2"); + config->delay_tbm3 = lookupToUShort("delay_tbm3"); + config->bypass_delay = lookupToUShort("bypass_delay"); + config->clock = lookupToUShort("clock"); + config->function_A = lookupToUShort("function_A"); + config->function_B = lookupToUShort("function_B"); + + delete m_moduleCfgFile; +} + +void HitbusConfigFile::dump(const ipc::HitbusModuleConfig &config){ + std::cout<<"Registers:"<<std::endl; + std::cout<<"=========="<<std::endl; + std::cout<<"bpm = "<<config.bpm<<std::endl; + std::cout<<"delay_tam1 = "<<config.delay_tam1<<std::endl; + std::cout<<"delay_tam2 = "<<config.delay_tam2<<std::endl; + std::cout<<"delay_tam3 = "<<config.delay_tam3<<std::endl; + std::cout<<"delay_tbm1 = "<<config.delay_tbm1<<std::endl; + std::cout<<"delay_tbm2 = "<<config.delay_tbm2<<std::endl; + std::cout<<"delay_tbm3 = "<<config.delay_tbm3<<std::endl; + std::cout<<"bypass_delay = "<<config.bypass_delay<<std::endl; + std::cout<<"clock = "<<config.clock<<std::endl; + std::cout<<"function_A = "<<config.function_A<<std::endl; + std::cout<<"function_B = "<<config.function_B<<std::endl; +} diff --git a/rce/rcecalib/server/HitbusConfigFile.hh b/rce/rcecalib/server/HitbusConfigFile.hh new file mode 100644 index 0000000000000000000000000000000000000000..dbde1be68f195227bf553bc5437a7066726d5c70 --- /dev/null +++ b/rce/rcecalib/server/HitbusConfigFile.hh @@ -0,0 +1,25 @@ +#ifndef HITBUSCONFIGFILE_HH +#define HITBUSCONFIGFILE_HH + +#include "HitbusModuleConfig.hh" +#include <string> +#include <map> + +class HitbusConfigFile { +public: + HitbusConfigFile(){} + ~HitbusConfigFile(); + void readModuleConfig(ipc::HitbusModuleConfig* cfg, std::string filename); + void writeModuleConfig(ipc::HitbusModuleConfig* config, const std::string &base, const std::string &confdir, + const std::string &configname, const std::string &key); + void dump(const ipc::HitbusModuleConfig& cfg); +private: + unsigned short lookupToUShort(std::string par); + int convertToUShort(std::string par, unsigned short& val); + + std::string m_moduleCfgFilePath; + std::ifstream *m_moduleCfgFile; + std::map<std::string, std::string> m_params; +}; + +#endif diff --git a/rce/rcecalib/server/IPCCallback.hh b/rce/rcecalib/server/IPCCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..7ee36d3abd3868c795579f49a80c2864afc09d5b --- /dev/null +++ b/rce/rcecalib/server/IPCCallback.hh @@ -0,0 +1,20 @@ +#ifndef IPCCALLBACK_HH +#define IPCCALLBACK_HH + +#include "ipc/object.h" +#include "Callback.hh" +#include <ipc/server.h> + +class IPCCallback : public IPCServer, + public IPCObject<POA_ipc::Callback> +{ +public: + IPCCallback(): m_rce(0){} + void notify( const ipc::CallbackParams &msg )=0; + void stopServer()=0; + void addRce(){m_rce++;} +protected: + int m_rce; +}; + +#endif diff --git a/rce/rcecalib/server/IPCController.cc b/rce/rcecalib/server/IPCController.cc new file mode 100644 index 0000000000000000000000000000000000000000..ac3999bdbddaeb20372f452dd1d2f59f6df2bce6 --- /dev/null +++ b/rce/rcecalib/server/IPCController.cc @@ -0,0 +1,975 @@ + +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/IPCRegularCallback.hh" +#include "rcecalib/server/PixScan.hh" +#include "IPCFEI3Adapter.hh" +#include "IPCFEI4AAdapter.hh" +#include "IPCFEI4BAdapter.hh" +#include "IPCHitbusAdapter.hh" +#include "IPCAFPHPTDCAdapter.hh" +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCScanRootAdapter.hh" +#include "ScanOptions.hh" +#include "ers/ers.h" +#include <stdio.h> +#include <boost/lexical_cast.hpp> +#include <string> + +IPCController::IPCController(IPCPartition &p):m_partition(p){} + +void IPCController::addRce(int rce){ + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)return; //RCE has already been added. + m_rces.push_back(rce); +} +void IPCController::removeAllRces(){ + m_rces.clear(); +} +void IPCController::downloadModuleConfig(int rce, int id, PixelModuleConfig& config){ + ipc::IPCFEI3Adapter_var modhandle; + std::string names=boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(rce); + const char* name=names.c_str(); + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI3Adapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI3Adapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + modhandle -> IPCdownloadConfig( config ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +void IPCController::downloadModuleConfig(int rce, int id, PixelFEI4AConfig& config){ + ipc::IPCFEI4AAdapter_var modhandle; + std::string names=boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(rce); + const char* name=names.c_str(); + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<name<<" not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + modhandle -> IPCdownloadConfig( config ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +void IPCController::downloadModuleConfig(int rce, int id, PixelFEI4BConfig& config){ + ipc::IPCFEI4BAdapter_var modhandle; + std::string names=boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(rce); + const char* name=names.c_str(); + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4BAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4BAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + modhandle -> IPCdownloadConfig( config ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +void IPCController::downloadModuleConfig(int rce, int id, HitbusModuleConfig& config){ + ipc::IPCHitbusAdapter_var modhandle; + std::string names=boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(rce); + const char* name=names.c_str(); + try { + bool v=m_partition.isObjectValid<ipc::IPCHitbusAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCHitbusAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + modhandle -> IPCdownloadConfig( config ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} +void IPCController::downloadModuleConfig(int rce, int id, AFPHPTDCModuleConfig& config){ + ipc::IPCAFPHPTDCAdapter_var modhandle; + std::string names=boost::lexical_cast<std::string>(id)+"_RCE"+boost::lexical_cast<std::string>(rce); + const char* name=names.c_str(); + try { + bool v=m_partition.isObjectValid<ipc::IPCAFPHPTDCAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCAFPHPTDCAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + modhandle -> IPCdownloadConfig( config ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +void IPCController::addModule(const char* name, const char* type, int id, int inLink, int outLink, int rce, const char* formatter){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + sprintf(cfa, "configIF_RCE%d",rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::ModSetup s; + s.id=id; + s.inLink=inLink; + s.outLink=outLink; + std::string typestring; + if(std::string(type)=="FEI3")typestring="IPC_FEI3_multiThread"; + else if(std::string(type)=="FEI4A")typestring="IPC_FEI4A_multiThread"; + else if(std::string(type)=="FEI4B")typestring="IPC_FEI4B_multiThread"; + else if(std::string(type)=="Hitbus")typestring="IPC_Hitbus_multiThread"; + else if(std::string(type)=="HPTDC")typestring="IPC_AFPHPTDC_multiThread"; + else(assert(0)); + handle -> IPCsetupModule( name,typestring.c_str(),s , formatter); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} + +int IPCController::setupTrigger(const char* type){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + return m_rces[i]+1000; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCsetupTriggerIF(type); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + return 0; +} + +void IPCController::removeAllModules(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCdeleteModules(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} +void IPCController::startScan(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCstartScan( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::abortScan(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCabort( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::stopWaitingForData(){ + ipc::IPCScanAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCstopWaiting( ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::getEventInfo(unsigned* nevent) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + sprintf(cfa, "configIF_RCE%d", m_rces[0]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + *nevent= handle -> IPCnTrigger(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } +} +int IPCController::verifyModuleConfigHW(int rce, int id) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + int retval=0; + sprintf(cfa, "configIF_RCE%d",rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + retval|=handle -> IPCverifyModuleConfigHW(id); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return retval; +} + +void IPCController::setupParameter(const char* par, int val) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCsetupParameter(par, val); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::setupMaskStage(int stage) { + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCsetupMaskStage(stage); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + + +void IPCController::downloadScanConfig(ipc::ScanOptions& options){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCconfigureScan(options); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::waitForScanCompletion(ipc::Priority pr, IPCCallback* callb){ + IPCCallback *cb; + if(callb==0) cb=new IPCRegularCallback; + else cb=callb; + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCconfigureCallback(cb->_this(), pr ); + cb->addRce(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + cb->run(); + cb->_destroy(); +} +void IPCController::runScan(ipc::Priority pr, IPCCallback* callb){ + IPCCallback *cb; + if(callb==0) cb=new IPCRegularCallback; + else cb=callb; + ipc::IPCScanRootAdapter_var rhandle; + ipc::IPCScanAdapter_var shandle; + char cfa[128]; + char cfb[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + sprintf(cfb, "scanCtrl_RCE%d", m_rces[i]); + try { + shandle = m_partition.lookup<ipc::IPCScanAdapter>( cfb ); + rhandle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + rhandle -> IPCconfigureCallback(cb->_this(), pr ); + cb->addRce(); + shandle->IPCstartScan(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + cb->run(); + cb->_destroy(); +} + +unsigned IPCController::getNEventsProcessed(){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + //maybe have to change if have multiple RCE's? + sprintf(cfa, "scanRoot_RCE%d", m_rces[0]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle -> IPCnEvents( ); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 0; +} + +void IPCController::resynch(){ + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + assert(m_rces.size()>0); + + for(size_t i=0;i<m_rces.size();i++){ + std::cout<<"IPCController sending resynch command to RCE "<<m_rces[i]<<std::endl; + + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle -> IPCresynch( ); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + } + +} + +void IPCController::resetFE(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCresetFE(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +void IPCController::configureModulesHW(){ + ipc::IPCConfigIFAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "configIF_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + handle->IPCconfigureModulesHW(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } +} + +unsigned IPCController::writeHWglobalRegister(const char* name, int reg, unsigned short val){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return modhandle->IPCwriteHWglobalRegister(reg,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWglobalRegister(const char* name, int reg, unsigned short &val){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return modhandle->IPCreadHWglobalRegister(reg,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::writeHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> data, std::vector<unsigned> &retvec){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::uvec ipcdata; + ipc::uvec_var retv; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + unsigned stat= modhandle->IPCwriteDoubleColumnHW(bit, dcol, ipcdata, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::readHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> &retvec){ + ipc::IPCFEI4AAdapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI4AAdapter>(name); + if(!v) { + std::cout<<"Not valid"<<std::endl; + assert(0); + } + modhandle = m_partition.lookup<ipc::IPCFEI4AAdapter>( name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::uvec_var retv; + unsigned stat= modhandle->IPCreadDoubleColumnHW(bit, dcol, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::sendHWcommand(int rce, unsigned char opcode){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCsendHWcommand(opcode); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::writeHWregister(int rce, unsigned addr, unsigned val){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCwriteHWregister(addr,val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWregister(int rce, unsigned addr, unsigned &val){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + return handle->IPCreadHWregister((CORBA::ULong)addr,(CORBA::ULong&) val); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::writeHWblockData(int rce, std::vector<unsigned>& data){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::blockdata ipcdata; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + return handle->IPCwriteHWblockData(ipcdata); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} +unsigned IPCController::readHWblockData(int rce, std::vector<unsigned>& data,std::vector<unsigned>& retvec ){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::blockdata ipcdata; + ipc::blockdata_var retv; + ipcdata.length(data.size()); + for(size_t i=0;i<data.size();i++)ipcdata[i]=data[i]; + unsigned stat= handle->IPCreadHWblockData(ipcdata, retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return stat; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return 1000; +} + +unsigned IPCController::readHWbuffers(int rce, std::vector<unsigned char>& retvec ){ + ipc::IPCConfigIFAdapter_var handle; + bool foundRce=false; + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)foundRce=true; + assert(foundRce); + char cfa[128]; + sprintf(cfa, "configIF_RCE%d", rce); + try { + handle = m_partition.lookup<ipc::IPCConfigIFAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::chardata_var retv; + unsigned nbuf= handle->IPCreadHWbuffers(retv); + for(unsigned i=0;i<retv->length();i++)retvec.push_back(retv[i]); + return nbuf; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + return (unsigned)-1; +} + +int IPCController::getScanStatus(){ + ipc::IPCScanAdapter_var handle; + int status=0; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanCtrl_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + status|= handle->IPCgetStatus(); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + } + return status; +} diff --git a/rce/rcecalib/server/IPCController.hh b/rce/rcecalib/server/IPCController.hh new file mode 100644 index 0000000000000000000000000000000000000000..9c930df27ee109afc7e99d1eae4d12714435b0b6 --- /dev/null +++ b/rce/rcecalib/server/IPCController.hh @@ -0,0 +1,70 @@ +#ifndef IPCCONTROLLER_HH +#define IPCCONTROLLER_HH + +#include "ipc/partition.h" +#include "PixelModuleConfig.hh" +#include "PixelFEI4AConfig.hh" +#include "PixelFEI4BConfig.hh" +#include "HitbusModuleConfig.hh" +#include "AFPHPTDCModuleConfig.hh" +#include "IPCScanRootAdapter.hh" +#include "IPCScanAdapter.hh" +#include <vector> +#include <map> + +class IPCCallback; +namespace ipc{ + class ScanOptions; +} + +class IPCController{ +public: + IPCController() {}; + IPCController(IPCPartition &p); + void addRce(int rce); + void removeAllRces(); + + void downloadModuleConfig(int rce, int id, ipc::PixelModuleConfig& config); + void downloadModuleConfig(int rce, int id, ipc::PixelFEI4AConfig& config); + void downloadModuleConfig(int rce, int id, ipc::PixelFEI4BConfig& config); + void downloadModuleConfig(int rce, int id, ipc::HitbusModuleConfig& config); + void downloadModuleConfig(int rce, int id, ipc::AFPHPTDCModuleConfig& config); + void addModule(const char* name, const char* type, int id, int inLink, int outLink, int rce, const char* formatter); + int setupTrigger(const char* type="default"); + void removeAllModules(); + void resetFE(); + void configureModulesHW(); + + unsigned writeHWglobalRegister(const char* name, int reg, unsigned short val); + unsigned readHWglobalRegister(const char* name, int reg, unsigned short& val); + unsigned writeHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> data, std::vector<unsigned> &retvec); + unsigned readHWdoubleColumn(const char* name, unsigned bit, unsigned dcol, std::vector<unsigned> &retvec); + + unsigned writeHWregister(int rce, unsigned addr, unsigned val); + unsigned readHWregister(int rce, unsigned addr, unsigned& val); + unsigned sendHWcommand(int rce, unsigned char opcode); + unsigned writeHWblockData(int rce, std::vector<unsigned> &data); + unsigned readHWblockData(int rce, std::vector<unsigned> &data, std::vector<unsigned>& retvec); + unsigned readHWbuffers(int rce, std::vector<unsigned char>& retvec); + + void downloadScanConfig(ipc::ScanOptions &scn); + int verifyModuleConfigHW(int rce, int id); + + void waitForScanCompletion(ipc::Priority pr, IPCCallback* callb=0); + void runScan(ipc::Priority pr, IPCCallback* callb=0); + void startScan(); + void abortScan(); + void stopWaitingForData(); + void getEventInfo(unsigned* nevent); + int getScanStatus(); + unsigned getNEventsProcessed(); + void resynch(); + void setupParameter(const char* par, int val); + void setupMaskStage(int stage); +private: + + IPCPartition m_partition; + std::vector<int> m_rces; +}; + +#endif diff --git a/rce/rcecalib/server/IPCGuiCallback.cc b/rce/rcecalib/server/IPCGuiCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..2c53a8b08ef5ccab0423e83ed83a451d3bd0acd6 --- /dev/null +++ b/rce/rcecalib/server/IPCGuiCallback.cc @@ -0,0 +1,29 @@ + +#include "rcecalib/server/IPCGuiCallback.hh" +#include "rcecalib/server/CallbackInfo.hh" + +void IPCGuiCallback::notify(const ipc::CallbackParams& msg){ + if(msg.status==ipc::SCANNING){ + m_cbinfo->setStage(msg.maskStage); + m_cbinfo->addToMask(CallbackInfo::NEWSTAGE); + std::cout<<"RCE "<<msg.rce<<": Mask Stage "<<msg.maskStage<<std::endl; + }else if(msg.status==ipc::FITTING){ + std::cout<<"RCE "<<msg.rce<<": Fitting"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::FIT); + }else if(msg.status==ipc::DOWNLOADING){ + std::cout<<"RCE "<<msg.rce<<": Downloading"<<std::endl; + m_cbinfo->addToMask(CallbackInfo::DOWNLOAD); + }else if(msg.status==ipc::FAILED){ + m_cbinfo->addToMask(CallbackInfo::FAILED); + std::cout<<"RCE "<<msg.rce<<": Failed"<<std::endl; + } +} + +void IPCGuiCallback::stopServer(){ + m_rce--; + if(m_rce<=0){ + m_cbinfo->addToMask(CallbackInfo::STOP); + stop(); + } +} + diff --git a/rce/rcecalib/server/IPCGuiCallback.hh b/rce/rcecalib/server/IPCGuiCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..48f5fb659f0b326c31c5e31030410119a26adaf1 --- /dev/null +++ b/rce/rcecalib/server/IPCGuiCallback.hh @@ -0,0 +1,18 @@ +#ifndef IPCGUICALLBACK_HH +#define IPCGUICALLBACK_HH + +#include "rcecalib/server/IPCCallback.hh" + +class CallbackInfo; + +class IPCGuiCallback : public IPCCallback { +public: + IPCGuiCallback(CallbackInfo* info): IPCCallback(),m_cbinfo(info){ + } + void notify( const ipc::CallbackParams & msg ); + void stopServer(); +private: + CallbackInfo* m_cbinfo; +}; + +#endif diff --git a/rce/rcecalib/server/IPCHistoController.cc b/rce/rcecalib/server/IPCHistoController.cc new file mode 100644 index 0000000000000000000000000000000000000000..44a9e6846e219e61156580507b33d872d9ba75b8 --- /dev/null +++ b/rce/rcecalib/server/IPCHistoController.cc @@ -0,0 +1,207 @@ + +#include "rcecalib/server/IPCHistoController.hh" +#include "IPCScanRootAdapter.hh" +#include "ers/ers.h" +#include <oh/OHIterator.h> +#include <oh/OHServerIterator.h> +#include <oh/OHProviderIterator.h> +#include <oh/OHRootReceiver.h> +#include "TH1D.h" +#include "TH2D.h" +#include "TH2C.h" +#include "TH2S.h" + +class HistoReceiver : public OHRootReceiver { +public: + void clearList(){ + m_list.clear(); + } + void receive( OHRootHistogram & h ) + { + m_list.push_back(h.histogram.get()); + h.histogram.release(); // we ask the histogram auto_ptr to drop ownership + // for the histogram since it will be kept by ROOT + } + std::vector<TH1*>& getHistos(){return m_list;} +private: + std::vector<TH1*> m_list; +}; + +IPCHistoController::IPCHistoController(IPCPartition &p):m_partition(p){} + +void IPCHistoController::addRce(int rce){ + for(size_t i=0;i<m_rces.size();i++)if(m_rces[i]==rce)return; //RCE has already been added. + m_rces.push_back(rce); +} + +void IPCHistoController::removeAllRces(){ + m_rces.clear(); +} + +// std::vector<TH1*> IPCHistoController::getHistosFromIS(const char* reg){ +// HistoReceiver hr; +// try{ +// OHProviderIterator pii( m_partition, "RceIsServer"); +// while(pii++){ +// OHIterator it( m_partition, "RceIsServer", pii.name(), reg); +// while ( it++ ){ +// it.retrieve( hr ); +// } +// } +// }catch(daq::is::InvalidCriteria){ +// std::cout<<"Invalid object"<<std::endl; +// }catch(daq::is::RepositoryNotFound){ +// std::cout<<"Object not found"<<std::endl; +// }catch ( daq::ipc::InvalidPartition & ex ){ +// std::cout<<"partition does not exist"<<std::endl; +// }catch ( daq::is::Exception & ex ){ +// std::cout<<"IS exception"<<std::endl; +// }catch(...){ +// std::cout<<"Something else went wrong"<<std::endl; +// } +// return hr.getHistos(); +// } + +std::vector<TH1*> IPCHistoController::getHistosFromIS(const char* reg){ + HistoReceiver hr; + try{ + OHHistogramIterator it( m_partition, "RceIsServer", ".*", reg); + while ( it++ ){ + it.retrieve( hr ); + if(hr.getHistos().back()!=0) + hr.getHistos().back()->SetName(it.name().c_str()); + } + }catch(daq::is::InvalidCriteria){ + std::cout<<"Invalid object"<<std::endl; + }catch(daq::is::RepositoryNotFound){ + std::cout<<"Object not found"<<std::endl; + }catch ( daq::ipc::InvalidPartition & ex ){ + std::cout<<"partition does not exist"<<std::endl; + }catch ( daq::is::Exception & ex ){ + std::cout<<"IS exception"<<std::endl; + }catch(...){ + std::cout<<"Something else went wrong"<<std::endl; + } + return hr.getHistos(); +} + +std::vector<std::string> IPCHistoController::getHistoNames(const char* reg){ + std::vector<std::string> retvect; + ipc::StringVect_var stringvect; + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + stringvect=handle -> IPCgetHistoNames(reg); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + + for(unsigned int i=0;i<stringvect->length();i++){ + retvect.push_back(std::string(stringvect[i])); + } + } + return retvect; +} + +std::vector<std::string> IPCHistoController::getPublishedHistoNames(){ + std::vector<std::string> retvect; + ipc::StringVect_var stringvect; + ipc::IPCScanRootAdapter_var handle; + char cfa[128]; + for(size_t i=0;i<m_rces.size();i++){ + sprintf(cfa, "scanRoot_RCE%d", m_rces[i]); + try { + handle = m_partition.lookup<ipc::IPCScanRootAdapter>( cfa ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + stringvect=handle -> IPCgetPublishedHistoNames(); + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + + for(unsigned int i=0;i<stringvect->length();i++){ + retvect.push_back(std::string(stringvect[i])); + } + } + return retvect; + } + + + +bool IPCHistoController::clearISServer(std::string regex, bool verbose) +{ + try + { + OHServerIterator sit( m_partition, "RceIsServer" ); + if ( verbose ) + { + std::cout << "Partition \"" << m_partition.name() + << "\" contains " << sit.entries() + << " IS server(s):" << std::endl; + } + + while ( sit++ ) + { + try { + OHHistogramIterator hit(m_partition, sit.name(), ".*", regex); + + if ( hit.entries() ) + { + if ( verbose ){ + std::cout << "removing " << hit.entries() + << " histogram(s) from the '" << sit.name() << "' server ... "; + } + + hit.removeAll(); + + if ( verbose ){ + std::cout << "done" << std::endl; + } + } + } + catch( ers::Issue & ex ) + { + ers::error( ex ); + return false; + } + } + } + catch ( ers::Issue & ex ) + { + ers::error( ex ); + return false; + } + + return true; + +} + diff --git a/rce/rcecalib/server/IPCHistoController.hh b/rce/rcecalib/server/IPCHistoController.hh new file mode 100644 index 0000000000000000000000000000000000000000..12e1fe7a54db92c311efbf0e83575444b38ffc5a --- /dev/null +++ b/rce/rcecalib/server/IPCHistoController.hh @@ -0,0 +1,30 @@ +#ifndef IPCHISTOCONTROLLER_HH +#define IPCHISTOCONTROLLER_HH + +#include "ipc/partition.h" +#include "IPCScanRootAdapter.hh" +#include <vector> + +#include <TH1.h> + + +class IPCHistoController{ +public: + IPCHistoController() {}; + IPCHistoController(IPCPartition &p); + void addRce(int rce); + void removeAllRces(); + + std::vector<TH1*> getHistosFromIS(const char* reg); + std::vector<std::string> getHistoNames(const char* reg); + std::vector<std::string> getPublishedHistoNames(); + + std::string getIPCPartitionName() { return m_partition.name(); } + + bool clearISServer(std::string regex="RCE.*", bool verbose=false); + + IPCPartition m_partition; + std::vector<int> m_rces; +}; + +#endif diff --git a/rce/rcecalib/server/IPCRegularCallback.cc b/rce/rcecalib/server/IPCRegularCallback.cc new file mode 100644 index 0000000000000000000000000000000000000000..625b0f915f4461751ceb91126f5af6c36fd69984 --- /dev/null +++ b/rce/rcecalib/server/IPCRegularCallback.cc @@ -0,0 +1,19 @@ + +#include "rcecalib/server/IPCRegularCallback.hh" + +void IPCRegularCallback::notify(const ipc::CallbackParams& msg){ + if(msg.status==ipc::SCANNING){ + std::cout<<"RCE "<<msg.rce<<": Mask Stage "<<msg.maskStage<<std::endl; + }else if(msg.status==ipc::FITTING){ + std::cout<<"RCE "<<msg.rce<<": Fitting"<<std::endl; + } +} + +void IPCRegularCallback::stopServer(){ + m_rce--; + if(m_rce<=0){ + std::cout<<"Done"<<std::endl; + stop(); + } +} + diff --git a/rce/rcecalib/server/IPCRegularCallback.hh b/rce/rcecalib/server/IPCRegularCallback.hh new file mode 100644 index 0000000000000000000000000000000000000000..105d3dad3f90f3d81c7ec7321f774694aeaec884 --- /dev/null +++ b/rce/rcecalib/server/IPCRegularCallback.hh @@ -0,0 +1,13 @@ +#ifndef IPCREGULARCALLBACK_HH +#define IPCREGULARCALLBACK_HH + +#include "rcecalib/server/IPCCallback.hh" + +class IPCRegularCallback : public IPCCallback { +public: + IPCRegularCallback(): IPCCallback(){} + void notify( const ipc::CallbackParams & msg ); + void stopServer(); +}; + +#endif diff --git a/rce/rcecalib/server/Makefile b/rce/rcecalib/server/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c98722e2a353c150a4fe6003ee701b6a5808e30d --- /dev/null +++ b/rce/rcecalib/server/Makefile @@ -0,0 +1,29 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables + +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(RELEASE) +endif +include $(RELEASE_DIR)/Makefile.inc + +default: .server + +clean: + +$(MAKE) -j$(JOBS) -C. $(HOST_ARCH).clean $(RCE_ARCH).clean + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +include $(RELEASE_DIR)/make/sw/rootcint.mk +endif + diff --git a/rce/rcecalib/server/Mean.hh b/rce/rcecalib/server/Mean.hh new file mode 100644 index 0000000000000000000000000000000000000000..51b6acd20a297556019100bb95645ba3290815bf --- /dev/null +++ b/rce/rcecalib/server/Mean.hh @@ -0,0 +1,28 @@ +#ifndef MEAN_HH +#define MEAN_HH +#include <math.h> + +class Mean{ +public: + Mean():sum(0),sum2(0),n(0){} + void clear(){sum=0;sum2=0;n=0;} + void accumulate(float val){ + sum+=val; + sum2+=val*val; + n++; + } + float mean(){ + if(n>0)return sum/n; + else return 0; + } + float sigma(){ + if(n>0)return sqrt(1/(float)n*sum2-mean()*mean()); + else return 0; + } + int nEntries(){return n;} +private: + float sum; + float sum2; + int n; +}; +#endif diff --git a/rce/rcecalib/server/PixScan.cc b/rce/rcecalib/server/PixScan.cc new file mode 100644 index 0000000000000000000000000000000000000000..0404a286828f1484d1fd00e2542b85ea930c6789 --- /dev/null +++ b/rce/rcecalib/server/PixScan.cc @@ -0,0 +1,851 @@ +///////////////////////////////////////////////////////////////////// +// PixScan.cxx +///////////////////////////////////////////////////////////////////// +// +// 17/06/05 Version 1.0 (PM) +// +// +// Still missing: +// setting up of the rod scan structure before sending reference +// presets +// histogram downloads +// histogram staging + +#include "rcecalib/server/PixScan.hh" + +#include <sstream> +#include <iostream> +namespace RCE { + PixScan::PixScan(ScanType presetName, FEflavour feFlavour) { + // initConfig(); + presetRCE(presetName, feFlavour); + setupRCE(presetName, feFlavour); + resetScan(); + } + + + PixScan::~PixScan() { + } + + + bool PixScan::setupRCE(ScanType presetName, FEflavour feFlavour) { + m_name="Scan"; + m_receiver="Pgp"; + m_dataHandler="RegularScan"; + m_dataProc="OCCUPANCY"; + m_scanType="RegularCfg"; + m_triggerType="default"; + m_formatterType="JJ"; + m_analysisType="NONE"; + m_hitbusConfig=0; + m_callbackPriority=ipc::LOW; + m_timeout_seconds=0; + m_timeout_nanoseconds=100000000; + m_firstStage = 0; + m_stepStage = 1; + m_oneByOne=false; + m_LVL1Latency_Secondary=0; + m_moduleTrgMask=0; + m_deadtime=0; + m_mixedTrigger=false; + m_setupThreshold=false; + m_triggerMask=0; + m_triggerDataOn=false; + m_threshold=100; + m_fitfun="SCURVE"; + m_verifyConfig=false; + m_eventInterval=0; + m_hitbusConfig=0; + m_clearMasks=false; + m_protectFifo=false; + m_runnumber=0; + m_injectForTrigger=0; + m_overrideLatency=false; + m_allowedTimeouts=5; + m_nTriggers=0; + m_noiseThreshold=1e-6; + m_useAbsoluteNoiseThreshold=false; + m_useVcal=false; + + bool fei3=(feFlavour == PM_FE_I2); + bool fei4=(feFlavour == PM_FE_I4A || feFlavour == PM_FE_I4B || feFlavour == PM_FE_I4); + if (presetName == DIGITAL_TEST && fei3) { + m_scanType="Regular"; + m_analysisType = "Fei3DigitalTest"; + addHistoName(".*FEI4_Errors"); + addHistoName("Mod_[0-9]+_Occupancy_Point_000"); + } else if (presetName == DIGITAL_TEST && fei4) { + m_firstStage = 0; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType = "Fei4DigitalTest"; + // addHistoName("RCE[0-9]+_Mod_0_Occupancy_Point_000"); + addHistoName(".*"); + } else if (presetName == DIGITALTEST_SELFTRIGGER && fei4) { + m_firstStage = 0; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType = "Fei4DigitalTest"; + m_allowedTimeouts=1000; + m_callbackPriority=ipc::HIGH; + // addHistoName("RCE[0-9]+_Mod_0_Occupancy_Point_000"); + addHistoName(".*"); + } else if (presetName == MULTISHOT && fei4) { + m_formatterType="FEI4B"; + addHistoName("Mod_0_Occupancy_Point_000"); + m_triggerType="MultiShot"; + m_eventInterval=5; + } else if (presetName == ANALOG_TEST && fei3) { + m_scanType="Regular"; + addHistoName(".*"); + } else if (presetName == TOT_TEST && fei3) { + m_scanType="Regular"; + m_dataProc="TOT"; + m_analysisType="TOT"; + addHistoName(".*"); + } else if (presetName == ANALOG_TEST && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_analysisType = "Fei4DigitalTest"; + m_formatterType=""; + addHistoName(".*"); + } else if (presetName == TOT_TEST && fei4) { + m_formatterType="FEI4"; + m_dataProc="TOT"; + m_analysisType="TOT"; + addHistoName(".*"); + } else if (presetName == TOT_CALIB && fei4) { + m_formatterType="FEI4"; + m_dataProc="TOTCALIB"; + m_analysisType="TOTCALIB"; + addHistoName(".*"); + } else if (presetName == THRESHOLD_SCAN && fei3) { + m_scanType="Regular"; + m_analysisType="Threshold"; + addHistoName(".*"); + } else if (presetName == THRESHOLD_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Threshold"; + addHistoName(".*"); + } else if (presetName == TEMPERATURE_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="Temperature"; + m_triggerType="Temperature"; + m_formatterType=""; + m_analysisType="Temperature"; + addHistoName(".*"); + } else if (presetName == MONLEAK_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="Monleak"; + m_triggerType="Monleak"; + m_formatterType=""; + m_analysisType="Temperature"; + addHistoName(".*"); + } else if (presetName == SERIAL_NUMBER_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="SerialNumber"; + m_triggerType="SerialNumber"; + m_formatterType=""; + m_analysisType="SerialNumber"; + addHistoName(".*"); + } else if (presetName == MODULE_CROSSTALK && fei4) { + m_dataHandler="ModuleCrosstalkRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Threshold"; + m_LVL1Latency_Secondary=238; + m_moduleTrgMask=1; + // have to use m_oneByOne for this scan + m_oneByOne=true; + m_mixedTrigger=true; + m_analysisType="ModuleCrosstalk"; + addHistoName(".*"); + } else if (presetName == OFFSET_SCAN && fei4) { + m_stepStage = 5; + //m_setupThreshold=true; + //m_threshold=120; + m_fitfun="SCURVE_NOCONV"; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Offset"; + addHistoName(".*"); + } else if (presetName == CROSSTALK_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_fitfun="SCURVE_XTALK"; + m_formatterType=""; + m_analysisType="Crosstalk"; + m_callbackPriority=ipc::MEDIUM; + addHistoName(".*"); + } else if (presetName == DIFFUSION && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_fitfun="SCAN_SCURVE_XTALK"; + m_analysisType="Crosstalk"; + m_callbackPriority=ipc::MEDIUM; + addHistoName(".*"); + std::vector<float> pixels; // = row + 336*col + 1 (row from 0-335, col from 0-79. We add 1 because maskStage==0 has special + + pixels.push_back(20 + 336*11 + 1); + pixels.push_back(40 + 336*31 + 1); + pixels.push_back(176 + 336*55 + 1); + pixels.push_back(177 + 336*55 + 1); + pixels.push_back(178 + 336*55 + 1); + pixels.push_back(175 + 336*56 + 1); + pixels.push_back(176 + 336*56 + 1); + + setLoopVarValues(1, pixels); + + } else if (presetName == TWOTRIGGER_THRESHOLD && fei4) { + m_eventInterval=245; + m_dataHandler="RegularScan"; + m_injectForTrigger=3; //bit mask. 3: inject on both triggers, 2: inject on 2nd trigger, 1: inject on 1st trigger, 0: no inject + m_dataProc="MultiTrigOccupancy"; + m_formatterType="FEI4"; + m_triggerType="MultiTrigger"; + m_analysisType="MultiTrig"; + addHistoName(".*"); + } else if (presetName == TWOTRIGGER_NOISE && fei4) { + m_eventInterval=245; // Overwritten by MULTITRIG_INTERVAL loop + m_dataHandler="RegularScan"; + m_dataProc="MultiTrigNoise"; + m_formatterType="FEI4"; + m_triggerType="MultiTrigger"; + m_analysisType="MultiTrigNoise"; + addHistoName(".*"); + + } else if (presetName == GDAC_SCAN && fei4) { + if(feFlavour == PM_FE_I4A){ //FEI4A + m_maskStageTotalSteps= FEI4_COL_ANL_40; + m_maskStageSteps = 24; + }else{ //FEI4B + m_maskStageTotalSteps= FEI4_COLPR1x6; + m_maskStageSteps = 5; + } + m_stepStage = 5; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Gdac"; + addHistoName(".*"); + } else if ((presetName == GDAC_TUNE || presetName == GDAC_RETUNE) && fei4) { + m_stepStage = 5; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Gdac"; + addHistoName(".*"); + } else if ((presetName == GDAC_FAST_TUNE || presetName == GDAC_FAST_RETUNE) && fei4) { + m_stepStage = 2; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="GdacFast"; + addHistoName(".*"); + } else if (presetName == GDAC_COARSE_FAST_TUNE && fei4) { + m_stepStage = 2; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="GdacCoarseFast"; + addHistoName(".*"); + } else if (presetName == IF_TUNE && fei4) { + m_formatterType="FEI4"; + m_scanType="IfScan"; + m_dataProc="TOT"; + m_analysisType = "Iffanalysis"; + m_callbackPriority=ipc::MEDIUM; + addHistoName("^([^T]|T[^o]|To[^T]|ToT[^2])*.{0,3}$"); //anything except ToT2 histos + } else if (presetName == FDAC_TUNE && fei4) { + m_formatterType="FEI4"; + m_dataProc="TOT"; + m_analysisType = "Fei4Fdacanalysis"; + addHistoName(".*"); + } else if (presetName == VTHIN_SCAN && fei4) { + m_formatterType="FEI4"; + addHistoName(".*"); + } else if (presetName == DELAY_SCAN && fei4) { + m_formatterType="FEI4"; + } else if (presetName == MEASUREMENT_SCAN) { + m_firstStage = 5; + m_timeout_nanoseconds=1; + m_allowedTimeouts=-1; + m_name="172.21.6.43:1444"; //address of the computer that does the measurement + m_receiver="Measurement"; + m_dataProc="Measurement"; + m_triggerType="Measurement"; + m_dataHandler="Simple"; + addHistoName(".*"); + } else if (presetName == SELFTRIGGER && fei4) { + //m_name="data_RUNNUM.hit"; + m_formatterType="FEI4"; + m_scanType="Selftrigger"; + m_dataProc="Selftrigger"; + m_dataHandler="CosmicData"; + m_timeout_seconds=1000000000; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + m_protectFifo=true; + addHistoName(".*"); + } else if (presetName == REGISTER_TEST && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="Fei4RegisterTest"; + m_triggerType="Fei4RegisterTest"; + m_formatterType=""; + m_analysisType="RegisterTest"; + m_allowedTimeouts=0; + m_useVcal=true; + addHistoName(".*"); + } else if (presetName == EXT_REGISTER_VERIFICATION && fei4) { + m_formatterType="FEI4"; + m_scanType="CosmicData"; + m_dataProc="Selftrigger"; + m_dataHandler="CosmicData"; + m_timeout_seconds=0; + m_timeout_nanoseconds=100000000; + m_verifyConfig=true; + } else if (presetName == NOISESCAN && fei4) { + m_formatterType="FEI4"; + m_scanType="Noisescan"; + m_dataProc="Noisescan"; + m_dataHandler="CosmicData"; + m_receiver="PgpCosmic"; + m_analysisType="Fei4Noise"; + m_timeout_seconds=60; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + m_triggerMask=0x2; //Trigger mask 1=scint 2=cyclic 4=Eudet 8=HSIO + m_eventInterval=20; + m_protectFifo=true; + m_noiseThreshold=1e-6; + m_useAbsoluteNoiseThreshold=false; + addHistoName(".*"); + } else if (presetName == NOISESCAN_SELFTRIGGER && fei4) { + m_formatterType="FEI4"; + m_scanType="Selftrigger"; + m_dataProc="Noisescan"; + m_dataHandler="CosmicData"; + m_receiver="PgpCosmic"; + m_analysisType="Fei4Noise"; + m_timeout_seconds=60; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + m_protectFifo=true; + m_noiseThreshold=10; + m_useAbsoluteNoiseThreshold=true; + addHistoName(".*"); + } else if (presetName == STUCKPIXELS && fei4) { + m_dataProc="Hitor"; + m_formatterType="FEI4Hitor"; + m_analysisType="Fei4StuckPixel"; + m_callbackPriority=ipc::HIGH; + m_triggerType="Hitor"; + addHistoName(".*"); + } else if (presetName == LV1LATENCY_SCAN && fei3) { + m_dataHandler="CosmicData"; + m_receiver="PgpCosmic"; + m_timeout_seconds=60; + m_timeout_nanoseconds=0; + } else if (presetName == SCINTDELAY_SCAN) { + m_scanType="Delay"; + m_dataProc="Delay"; + m_dataHandler="DelayScan"; + m_receiver="PgpCosmic"; + m_timeout_seconds=5; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + addHistoName(".*"); + } else if (presetName == COSMIC_DATA) { + m_hitbusConfig=1; + m_scanType="CosmicData"; + m_dataHandler="CosmicData"; + //m_dataProc="CosmicData"; + m_receiver="PgpCosmicNw"; + m_triggerDataOn=true; + m_timeout_seconds=1000000000; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + m_overrideLatency=true; + } else if (presetName == COSMIC_RCE) { + m_digitalInjection = false; + m_scanType="CosmicData"; + m_dataHandler="CosmicData"; + m_dataProc="CosmicData"; + m_receiver="PgpCosmic"; + m_triggerDataOn=true; + m_timeout_seconds=1000000000; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + } else if (presetName == EXTTRIGGER && fei4) { + m_triggerDataOn=true; + m_overrideLatency=true; + m_LVL1Latency = 210; + m_hitbusConfig=1; + //m_eventInterval=750; + m_triggerMask=0x8; //Trigger mask 1=scint 2=cyclic 4=Eudet 8=HSIO + m_formatterType="FEI4"; + m_scanType="CosmicData"; + m_dataProc="Selftrigger"; + m_dataHandler="CosmicData"; + m_receiver="PgpCosmic"; + //Setup below for multiple hardware triggers: + //Trigger stream with m_strobeLVL1Delay leading 0s, + //then m_consecutiveLvl1TrigA[1] triggers m_LVL1Latency_Secondary ticks apart + //m_triggerType="MultiShot"; + //m_consecutiveLvl1TrigA[1]= 2; //n L1A + //m_consecutiveLvl1TrigA[0]= 1; + //m_LVL1Latency_Secondary=10; + //m_strobeLVL1Delay=32; + //------- + m_timeout_seconds=1000000000; + m_timeout_nanoseconds=0; + m_allowedTimeouts=-1; + addHistoName(".*"); + } else if ((presetName == TDAC_TUNE || presetName == GDAC_TUNE) && fei3) { + + if (presetName == TDAC_TUNE) { + m_analysisType="Fei3Tdac_tune"; + } else { + m_analysisType="Gdac"; + } + addHistoName(".*"); + } else if ((presetName == TDAC_TUNE || presetName==TDAC_TUNE_ITERATED) && fei4) { + m_thresholdTargetValue = 1600; + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_analysisType="Fei4Tdac_tune"; + m_formatterType=""; + addHistoName(".*"); + } else if ((presetName == TDAC_FAST_TUNE || presetName==TDAC_FAST_RETUNE) && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_analysisType="Fei4TdacFast_tune"; + m_formatterType=""; + addHistoName(".*"); + } else if (presetName == T0_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_fitfun="SCURVE_NOCONV"; + m_formatterType=""; + m_analysisType="T0"; + addHistoName(".*"); + } else if (presetName == TIMEWALK_MEASURE && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_fitfun="SCURVE_NOCONV"; + m_formatterType=""; + m_analysisType="TimeWalk"; + addHistoName(".*"); + } else if (presetName == INTIME_THRESH_SCAN && fei4) { + m_dataHandler="RegularScanRaw"; + m_dataProc="RawFei4Occupancy"; + m_formatterType=""; + m_analysisType="Threshold"; + addHistoName(".*"); + } else if ((presetName == FDAC_TUNE || presetName == IF_TUNE) && fei3) { + addHistoName(".*"); + m_dataProc="TOT"; + + if (presetName == FDAC_TUNE) { + m_analysisType = "Fei3Fdacanalysis"; + } else { + m_analysisType = "Iffanalysis"; + } + } else if (presetName == TOT_CALIB && fei3) { + m_scanType="Regular"; + m_dataProc="TOT"; + } else if (presetName == T0_SCAN && fei3) { + m_scanType="Regular"; + addHistoName(".*"); + } else if (presetName == TIMEWALK_MEASURE && fei3) { + m_scanType="Regular"; + addHistoName(".*"); + } else if (presetName == INTIME_THRESH_SCAN && fei3) { + m_scanType="Regular"; + } else if (presetName == CROSSTALK_SCAN && fei3) { + m_scanType="Regular"; + addHistoName(".*"); + } else if (presetName == INCREMENTAL_TDAC_SCAN && feFlavour == PM_FE_I2) { + m_scanType="Regular"; + /* no RCE BOC scans at this point */ + } else if (presetName == BOC_RX_DELAY_SCAN) { return false; + } else if (presetName == BOC_V0_RX_DELAY_SCAN) { return false; + } else if (presetName == BOC_THR_RX_DELAY_SCAN) { return false; + } else { + + std::cout<<"Scan not implemented (index= "<< presetName<< ")"<<std::endl; + return false; + } + return true; + } + + bool PixScan::presetRCE(ScanType presetName, FEflavour feFlavour) { + #include "PixScanBase_presetRCE.h" + } + /* void PixScan::preset(ScanType presetName) now in PixScanBase - + to sync with PixLib */ + + + + + + bool PixScan::loop(int index) { + if (index < MAX_LOOPS) { + if (m_loopTerminating[index]) { + m_loopTerminating[index] = false; + m_loopEnded[index] = true; + if (index == 0) { + m_FECounter = 0; + m_maskStageIndex = 0; + m_newMaskStage = true; + m_newScanStep = true; + m_newFE = m_FEbyFE; + if (m_dspProcessing[0]) m_newScanStep = false; + if (m_dspMaskStaging || m_maskStageMode == STATIC || m_runType != NORMAL_SCAN) m_newMaskStage = false; + } + m_loopIndex[index] = 0; + return false; + } else { + m_loopEnded[index] = false; + return true; + } + } + assert(0); + return false; + } + + int PixScan::scanIndex(int index) { + if (index < MAX_LOOPS) { + return m_loopIndex[index]; + } + assert(0); + return 0; + } + + void PixScan::next(int index) { + if (index == 0) { + if ((m_dspProcessing[0] || !m_loopActive[0]) && + (m_dspMaskStaging || m_maskStageMode == STATIC || m_runType != NORMAL_SCAN)) { + m_loopIndex[index] = m_loopVarNSteps[index] - 1; + m_maskStageIndex = m_maskStageSteps - 1; + m_loopTerminating[0] = true; + m_newScanStep = false; + m_newMaskStage = false; + } else if (m_dspProcessing[0] || !m_loopActive[0]) { + if (m_maskStageIndex < m_maskStageSteps - 1) { + m_maskStageIndex++; + m_newScanStep = false; + m_newMaskStage = true; + } else { + m_loopTerminating[0] = true; + } + } else if (m_dspMaskStaging || m_maskStageMode == STATIC || m_runType != NORMAL_SCAN) { + if (m_loopIndex[0] < m_loopVarNSteps[0] - 1) { + m_loopIndex[0]++; + m_newScanStep = true; + m_newMaskStage = false; + } else { + m_loopTerminating[0] = true; + } + } else { + if ((m_loopIndex[0] == m_loopVarNSteps[0] - 1) && (m_maskStageIndex == m_maskStageSteps - 1)) { + m_loopTerminating[0] = true; + m_newScanStep = false; + m_newMaskStage = false; + } else { + if (m_innerLoopSwap) { + if (m_loopIndex[0] < m_loopVarNSteps[0] - 1) { + m_loopIndex[0]++; + m_newScanStep = true; + m_newMaskStage = false; + } else { + m_loopIndex[0] = 0; + m_maskStageIndex++; + m_newScanStep = false; + m_newMaskStage = true; + } + } else { + + if (m_maskStageIndex < m_maskStageSteps - 1) { + m_maskStageIndex++; + m_newScanStep = false; + m_newMaskStage = true; + } else { + m_maskStageIndex = 0; + m_loopIndex[0]++; + m_newScanStep = true; + m_newMaskStage = false; + } + } + } + } + } else if (index < MAX_LOOPS) { + if (m_dspProcessing[index] || !m_loopActive[index]) { + m_loopIndex[index] = m_loopVarNSteps[index] - 1; + m_loopTerminating[index] = true; + } else { + if ((m_loopIndex[index] < m_loopVarNSteps[index] - 1) || m_loopVarValuesFree[index]) { + m_loopIndex[index]++; + } else { + m_loopTerminating[index] = true; + } + } + } else { + assert(0); + } + } + + void PixScan::terminate(int index) { + if (index > 0 && index < MAX_LOOPS) { + if (m_loopVarValuesFree[index]) { + m_loopTerminating[index] = true; + m_loopVarNSteps[index] = m_loopIndex[index]+1; + } + } else { + assert(0); + } + } + + bool PixScan::newMaskStep() { + return m_newMaskStage; + } + + bool PixScan::newScanStep() { + return m_newScanStep; + } + + void PixScan::resetScan() { + m_FECounter=0; + m_actualFE = -1; + // Reset indexes + for (int i=0; i<MAX_LOOPS; i++) { + m_loopIndex[i] = 0; + m_loopTerminating[i] = false; + m_loopEnded[i] = false; + } + m_maskStageIndex = 0; + m_newMaskStage = true; + m_newScanStep = true; + if (m_dspProcessing[0]) m_newScanStep = false; + if (m_dspMaskStaging || m_maskStageMode == STATIC || m_runType != NORMAL_SCAN) m_newMaskStage = false; + // Reset histograms + } + + + + void PixScan::convertScanConfig(ipc::ScanOptions& scanPar){ + // Initialize ScanPar structure + int nLoopTot = 0; + int i; + int m_nBinTot = 0; + for (i=0; i<MAX_LOOPS; i++) { + if (getLoopActive(i) && getDspProcessing(i)) { + nLoopTot++; + m_nBinTot += getLoopVarNSteps(i); + } else { + break; + } + } + // zero everything + char* pointer=(char*)&scanPar; + for (unsigned i=0;i<sizeof(ipc::ScanOptions);i++){ + *pointer++=0; + } + + PixLib::EnumMaskSteps mss; + PixLib::EnumMaskStageMode msm; + PixLib::EnumScanParam sp; + PixLib::EnumFitFunc ff; + PixLib::EnumScanAct sa; + PixLib::EnumTriggMode tm; + PixLib::EnumTriggOptions to; + + // Load scan config + scanPar.runNumber=m_runnumber; + scanPar.name=CORBA::string_dup(m_name.c_str()); + scanPar.scanType=CORBA::string_dup(m_scanType.c_str()); + scanPar.receiver=CORBA::string_dup(m_receiver.c_str()); + scanPar.dataHandler=CORBA::string_dup(m_dataHandler.c_str()); + scanPar.dataProc=CORBA::string_dup(m_dataProc.c_str()); + scanPar.timeout.seconds=m_timeout_seconds; + scanPar.timeout.nanoseconds=m_timeout_nanoseconds; + scanPar.timeout.allowedTimeouts=m_allowedTimeouts; + if (getMaskStageMode() == PixScan::STATIC) { + scanPar.stagingMode = CORBA::string_dup(msm.lookup(STATIC).c_str()); + //scanPar.general.stageAdvanceFirst = 0; //? + scanPar.maskStages = CORBA::string_dup(mss.lookup(STEPS_32).c_str()); + scanPar.nMaskStages = 32; + } else { + scanPar.stagingMode = CORBA::string_dup(msm.lookup(getMaskStageMode()).c_str()); + if (getInnerLoopSwap()) { + //scanPar.general.stageAdvanceFirst = 0; //? + } else { + //scanPar.general.stageAdvanceFirst = 1; //? + } + scanPar.maskStages = CORBA::string_dup(mss.lookup(getMaskStageTotalSteps()).c_str()); + scanPar.nMaskStages = getMaskStageSteps(); + } + scanPar.firstStage=m_firstStage; + scanPar.stepStage=m_stepStage; + scanPar.nLoops = 0; + scanPar.scanLoop.length(nLoopTot); + for (int i=0; i<nLoopTot; i++) { + if (getLoopActive(i) && getDspProcessing(i)) { + scanPar.nLoops++; + scanPar.scanLoop[i].scanParameter = CORBA::string_dup(sp.lookup(getLoopParam(i)).c_str()); + scanPar.scanLoop[i].nPoints = getLoopVarNSteps(i); + //scanPar.scanLoop[i].dataPointsPtr = 0x0; + scanPar.scanLoop[i].endofLoopAction.Action = CORBA::string_dup(sa.lookup(PixLib::EnumScanAct::NO_ACTION).c_str()); + if (getDspLoopAction(i)) { + if (getLoopAction(i) == PixScan::SCURVE_FIT) { + // scanPar.scanLoop[i].endofLoopAction.Action = SCAN_CALC_THRESH; + scanPar.scanLoop[i].endofLoopAction.Action = CORBA::string_dup(sa.lookup(PixLib::EnumScanAct::FIT).c_str()); + scanPar.scanLoop[i].endofLoopAction.fitFunction = CORBA::string_dup(m_fitfun.c_str()); + } else if (getLoopAction(i) == PixScan::TDAC_TUNING) { + scanPar.scanLoop[i].endofLoopAction.Action = CORBA::string_dup(sa.lookup(PixLib::EnumScanAct::TUNE_THRESH).c_str()); + scanPar.scanLoop[i].endofLoopAction.fitFunction = CORBA::string_dup(ff.lookup(PixLib::EnumFitFunc::SCURVE).c_str()); + scanPar.scanLoop[i].endofLoopAction.targetThreshold = getThresholdTargetValue(); + } else if (getLoopAction(i) == PixScan::NORMALIZE) { + scanPar.scanLoop[i].endofLoopAction.Action = CORBA::string_dup(sa.lookup(PixLib::EnumScanAct::FIT).c_str()); + scanPar.scanLoop[i].endofLoopAction.fitFunction = CORBA::string_dup("NORMALIZE"); + } + } + if (scanPar.scanLoop[i].nPoints > 0) { + //Add loop values at the very end + std::vector<float> loopvalues = getLoopVarValues(i); + scanPar.scanLoop[i].dataPoints.length(scanPar.scanLoop[i].nPoints); + for(unsigned int k=0;k<scanPar.scanLoop[i].nPoints;k++){ + scanPar.scanLoop[i].dataPoints[k]= (int)loopvalues[k]; + } + } + + } else { + scanPar.scanLoop[i].scanParameter = CORBA::string_dup(sp.lookup(NO_PAR).c_str()); + scanPar.scanLoop[i].endofLoopAction.Action = CORBA::string_dup(sa.lookup(PixLib::EnumScanAct::NO_ACTION).c_str()); + scanPar.scanLoop[i].endofLoopAction.fitFunction = CORBA::string_dup(""); + } + } + //scanPar.general.configSet = getModConfig(); //? + scanPar.trigOpt.nEvents = getRepetitions(); + scanPar.trigOpt.moduleTrgMask = m_moduleTrgMask; + scanPar.trigOpt.triggerMask = m_triggerMask; + scanPar.trigOpt.deadtime = m_deadtime; + scanPar.trigOpt.triggerDataOn = m_triggerDataOn; + scanPar.trigOpt.nL1AperEvent = getConsecutiveLvl1TrigA(0); + scanPar.trigOpt.nTriggersPerGroup = getConsecutiveLvl1TrigA(1); + scanPar.trigOpt.nTriggers = m_nTriggers; + scanPar.trigOpt.Lvl1_Latency = getLVL1Latency(); + scanPar.trigOpt.Lvl1_Latency_Secondary = m_LVL1Latency_Secondary; + scanPar.trigOpt.strobeDuration = getStrobeDuration(); + scanPar.trigOpt.strobeMCCDelay = getStrobeMCCDelay(); + scanPar.trigOpt.strobeMCCDelayRange = getStrobeMCCDelayRange(); + scanPar.trigOpt.injectForTrigger = m_injectForTrigger; + scanPar.trigOpt.hitbusConfig = m_hitbusConfig; + //override + scanPar.trigOpt.CalL1ADelay = getStrobeLVL1Delay(); + scanPar.trigOpt.eventInterval = m_eventInterval; + scanPar.trigOpt.threshold=m_threshold; + std::vector<std::string> optMask; + if(m_totTargetCharge!=0 && m_useVcal==false){ + scanPar.trigOpt.vcal_charge = getTotTargetCharge(); + optMask.push_back(to.lookup(PixLib::EnumTriggOptions::SPECIFY_CHARGE_NOT_VCAL).c_str()); + } else { + scanPar.trigOpt.vcal_charge = getFeVCal(); + } + //getModScanConcurrent() //? + //getFeHitbus() //? + if (getDigitalInjection()) optMask.push_back(to.lookup(PixLib::EnumTriggOptions::DIGITAL_INJECT).c_str()); + else if (getChargeInjCapHigh()) { + optMask.push_back(to.lookup(PixLib::EnumTriggOptions::USE_CHIGH).c_str()); + } else { + optMask.push_back(to.lookup(PixLib::EnumTriggOptions::USE_CLOW).c_str()); + } + if(m_oneByOne==true)optMask.push_back("ONE_BY_ONE"); + if(m_setupThreshold==true)optMask.push_back("SETUP_THRESHOLD"); + if(m_clearMasks==true)optMask.push_back("CLEAR_MASKS"); + if(m_protectFifo==true)optMask.push_back("PROTECT_FIFO"); + if(m_overrideLatency==true)optMask.push_back("OVERRIDE_LATENCY"); + scanPar.trigOpt.optionsMask.length(optMask.size()); + for(size_t i=0;i<optMask.size();i++){ + scanPar.trigOpt.optionsMask[i]=CORBA::string_dup(optMask[i].c_str()); + } + + if (getSelfTrigger()) { + scanPar.trigOpt.triggerMode = CORBA::string_dup(tm.lookup(PixLib::EnumTriggMode::INTERNAL_SELF).c_str()); + } else if (m_mixedTrigger==true){ + scanPar.trigOpt.triggerMode = CORBA::string_dup(tm.lookup(PixLib::EnumTriggMode::MIXED).c_str()); + } else { + // More options needed here in PixScan + scanPar.trigOpt.triggerMode = CORBA::string_dup(tm.lookup(PixLib::EnumTriggMode::DSP).c_str()); + } + + scanPar.histos.length(m_histoNames.size()); + for(size_t i=0;i<m_histoNames.size();i++){ + scanPar.histos[i]=CORBA::string_dup(m_histoNames[i].c_str()); + } + } + void PixScan::dump(std::ostream &os, const ipc::ScanOptions& scanPar) + { + /* force decimal output */ + os <<std::dec<<"Run number = " << m_runnumber << std::endl; + os <<"Formatter = " << m_formatterType << std::endl; + os << "Analysis = " << m_analysisType << std::endl; + os << "ToT target value = " << m_totTargetValue << std::endl; + os << "ToT target charge = " << m_totTargetCharge << std::endl; + os << "Threshold target value = " << m_thresholdTargetValue << std::endl; + os << "scanPar.name = " << scanPar.name << std::endl; + os << "scanPar.receiver = " << scanPar.receiver << std::endl; + os << "scanPar.dataHandler = " << scanPar.dataHandler << std::endl; + os << "scanPar.dataProc = " << scanPar.dataProc << std::endl; + os << "scanPar.scanType = " << scanPar.scanType << std::endl; + os << "scanPar.timeout.seconds = " << scanPar.timeout.seconds << std::endl; + os << "scanPar.timeout.nanaseconds = " << scanPar.timeout.nanoseconds << std::endl; + os << "scanPar.stagingMode = " << scanPar.stagingMode << std::endl; + os << "scanPar.nMaskStages = " << scanPar.nMaskStages << std::endl; + os << "scanPar.maskStages = " << scanPar.maskStages << std::endl; + os << "scanPar.firstStage = " << scanPar.firstStage << std::endl; + os << "scanPar.stepStage = " << scanPar.firstStage << std::endl; + os << "scanPar.trigOpt.nEvents = " << scanPar.trigOpt.nEvents << std::endl; + os << "scanPar.trigOpt.moduleTrgMask = " << scanPar.trigOpt.moduleTrgMask << std::endl; + os << "scanPar.trigOpt.nL1AperEvent = " << (int) scanPar.trigOpt.nL1AperEvent << std::endl; + os << "scanPar.trigOpt.nTriggersPerGroup = " << (int) scanPar.trigOpt.nTriggersPerGroup << std::endl; + os << "scanPar.trigOpt.nTriggers = " << (int) scanPar.trigOpt.nTriggers << std::endl; + os << "scanPar.trigOpt.Lvl1_Latency = " << (int) scanPar.trigOpt.Lvl1_Latency << std::endl; + os << "scanPar.trigOpt.Lvl1_Latency_Secondary = " << (int) scanPar.trigOpt.Lvl1_Latency_Secondary << std::endl; + os << "scanPar.trigOpt.strobeDuration = " << scanPar.trigOpt.strobeDuration << std::endl; + os << "scanPar.trigOpt.strobeMCCDelay = " << scanPar.trigOpt.strobeMCCDelay << std::endl; + os << "scanPar.trigOpt.strobeMCCDelayRange = " << scanPar.trigOpt.strobeMCCDelayRange << std::endl; + os << "scanPar.trigOpt.CalL1ADelay = " << scanPar.trigOpt.CalL1ADelay << std::endl; + os << "scanPar.trigOpt.eventInterval = " << scanPar.trigOpt.eventInterval << std::endl; + os << "scanPar.trigOpt.threshold = " << scanPar.trigOpt.threshold << std::endl; + os << "scanPar.trigOpt.triggerMode = " << scanPar.trigOpt.triggerMode << std::endl; + os << "scanPar.trigOpt.triggerMask = " << scanPar.trigOpt.triggerMask << std::endl; + os << "scanPar.trigOpt.triggerDataOn = " << (int)scanPar.trigOpt.triggerDataOn << std::endl; + os << "scanPar.trigOpt.injectForTrigger = " << (int)scanPar.trigOpt.injectForTrigger << std::endl; + os << "scanPar.trigOpt.hitbusConfig = " << (int)scanPar.trigOpt.hitbusConfig << std::endl; + os << "scanPar.trigOpt.deadtime = " << scanPar.trigOpt.deadtime << std::endl; + os << "scanPar.trigOpt.vcal_charge = " << scanPar.trigOpt.vcal_charge << std::endl; + for(unsigned i=0;i<scanPar.trigOpt.optionsMask.length();i++) + os << "scanPar.trigOpt.optionsMask["<<i<<"] = " << scanPar.trigOpt.optionsMask[i] << std::endl; + + os << "scanPar.nLoops = " << (int)scanPar.nLoops << std::endl; + for(int i=0;i<scanPar.nLoops;i++) { + os << "scanPar.scanLoop["<<i<<"].scanParameter = " << scanPar.scanLoop[i].scanParameter << std::endl; + os << "scanPar.scanLoop["<<i<<"].endofLoopAction.Action = " << scanPar.scanLoop[i].endofLoopAction.Action << std::endl; + os << "scanPar.scanLoop["<<i<<"].endofLoopAction.fitFunction = " << scanPar.scanLoop[i].endofLoopAction.fitFunction << std::endl; + os << "scanPar.scanLoop["<<i<<"].endofLoopAction.targetThreshold = " << scanPar.scanLoop[i].endofLoopAction.targetThreshold << std::endl; + os << "scanPar.scanLoop["<<i<<"].nPoints = " << scanPar.scanLoop[i].nPoints << std::endl; + for(unsigned int j=0;j<scanPar.scanLoop[i].nPoints;j++) { + os << "scanPar.scanLoop["<<i<<"].dataPoints["<<j<<"] = " << scanPar.scanLoop[i].dataPoints[j] <<std::endl; + } + } + for(unsigned i=0;i<scanPar.histos.length();i++) + os << "scanPar.histos["<<i<<"] = " << scanPar.histos[i] << std::endl; + } +} diff --git a/rce/rcecalib/server/PixScan.hh b/rce/rcecalib/server/PixScan.hh new file mode 100644 index 0000000000000000000000000000000000000000..2b9d46e9d4380df122ab64d8ec0c0445ba689891 --- /dev/null +++ b/rce/rcecalib/server/PixScan.hh @@ -0,0 +1,216 @@ +#ifndef PIXSCAN_HH +#define PIXSCAN_HH + +#include "ScanOptions.hh" +#include "Callback.hh" +#include "PixScanBase.h" +using namespace ipc; + + +#include <vector> +#include <list> +#include <map> +#include <string> +#include <assert.h> +#include <sys/time.h> + +namespace RCE { + + class PixScan : public PixLib::PixScanBase{ + + +private: + // Global scan config + // RCE specific + std::string m_name; + std::string m_scanType; + std::string m_triggerType; + std::string m_formatterType; + std::string m_receiver; + std::string m_dataHandler; + std::string m_dataProc; + std::string m_analysisType; + ipc::Priority m_callbackPriority; + unsigned m_timeout_seconds; + unsigned m_timeout_nanoseconds; + std::vector<std::string>m_histoNames; + int m_eventInterval; + bool m_oneByOne; + int m_firstStage; + int m_stepStage; + int m_LVL1Latency_Secondary; + unsigned short m_moduleTrgMask; + bool m_mixedTrigger; + bool m_setupThreshold; + unsigned short m_threshold; + std::string m_fitfun; + bool m_verifyConfig; + unsigned short m_triggerMask; + bool m_triggerDataOn; + int m_injectForTrigger; + unsigned short m_deadtime; + unsigned short m_hitbusConfig; + bool m_clearMasks; + bool m_protectFifo; + int m_runnumber; + bool m_overrideLatency; + int m_allowedTimeouts; + unsigned m_nTriggers; + double m_noiseThreshold; + bool m_useAbsoluteNoiseThreshold; + bool m_useVcal; + + + std::map<std::string, int> m_histogramTypes; + std::map<std::string, int> m_scanTypes; + void prepareIndexes(HistogramType type, unsigned int mod, int ix2, int ix1, int ix0); + +public: + //! Constructors + PixScan() {}; + PixScan(ScanType presetName, FEflavour feFlavour); + PixScan(PixLib::PixScanBase &base):PixLib::PixScanBase(base){}; + + //! Destructor + ~PixScan(); + + + //! Load predefined configurations + + // setup RCE specific fields + bool setupRCE(ScanType presetName, FEflavour feFlavour); + bool presetRCE(ScanType presetName, FEflavour feFlavour); + + void resetScan(); + + void convertScanConfig(ipc::ScanOptions& scanPar); + void dump(std::ostream &os, const ipc::ScanOptions& scanPar); + //! Scan attributes + void setFirstStage(int firstStage){ + m_firstStage=firstStage; + } + int getFirstStage(){ + return m_firstStage; + } + void setStepStage(int stepStage){ + m_stepStage=stepStage; + } + int getStepStage(){ + return m_stepStage; + } + void setSetupThreshold(bool setupThreshold) { + m_setupThreshold=setupThreshold; + } + bool getSetupThreshold() { + return m_setupThreshold; + } + void setThreshold(unsigned short threshold){ + m_threshold=threshold; + } + unsigned short getThreshold(){ + return m_threshold; + } + void setTimeoutSeconds(unsigned timeoutSeconds){ + m_timeout_seconds=timeoutSeconds; + } + unsigned getTimeoutSeconds(){ + return m_timeout_seconds; + } + + void setName(const char* name){ + m_name=name; + } + std::string getName(){ + return m_name; + } + void addHistoName(const char* name){ + m_histoNames.push_back(name); + } + std::vector<std::string>& getHistoNames(){ + return m_histoNames; + } + unsigned short getModuleTrgMask(){ + return m_moduleTrgMask; + } + void setModuleTrgMask (unsigned short modTrgMask){ + m_moduleTrgMask=modTrgMask; + } + const char* getAnalysisType(){ + return m_analysisType.c_str(); + } + ipc::Priority getCallbackPriority(){ + return m_callbackPriority; + } + const char* getScanTypeName(){ + return m_scanType.c_str(); + } + + const char* getTriggerType(){ + return m_triggerType.c_str(); + } + const char* getFormatterType(){ + return m_formatterType.c_str(); + } + const bool verifyConfig(){ + return m_verifyConfig; + } + void setTriggerMask(unsigned short mask){ + m_triggerMask=mask; + } + void setEventInterval(unsigned val){ + m_eventInterval=val; + } + void setDeadtime(unsigned val){ + m_deadtime=val; + } + void setHitbusConfig(unsigned short val){ + m_hitbusConfig=val; + } + unsigned short getHitbusConfig(){ + return m_hitbusConfig; + } + bool clearMasks(){ + return m_clearMasks; + } + void setClearMasks(bool on){ + m_clearMasks=on; + } + bool protectFifo(){ + return m_protectFifo; + } + void setRunNumber(int runnum){ + m_runnumber=runnum; + } + int getRunNumber(){ + return m_runnumber; + } + double getNoiseThreshold(){ + return m_noiseThreshold; + } + bool useAbsoluteNoiseThreshold(){ + return m_useAbsoluteNoiseThreshold; + } + void setSecondaryLatency(int lat){ + m_LVL1Latency_Secondary=lat; + } + int getSecondaryLatency(){ + return m_LVL1Latency_Secondary; + } + //! Scan coontrol + + void initConfig(); + bool loop(int index); + int scanIndex(int index); + void next(int index); + void terminate(int index); + bool newMaskStep(); + bool newScanStep(); + + + }; + +} +#endif + + + diff --git a/rce/rcecalib/server/PrimList.cc b/rce/rcecalib/server/PrimList.cc new file mode 100644 index 0000000000000000000000000000000000000000..4d8856b3039352c4c30f26daa866d4599ac2bbd3 --- /dev/null +++ b/rce/rcecalib/server/PrimList.cc @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////////////// +// PixScan.cxx +///////////////////////////////////////////////////////////////////// +// +// 14/06/12 Version 1.0 (Author:Jackie Brosamer) +// +// + + + +#include "rcecalib/server/PrimList.hh" + +#include <sstream> +#include <iostream> + +namespace RCE { + + //! Constructors + //Load saved primlist from file + /*PrimList::PrimList() { + m_scans = new std::vector <PixScan*> (); + }*/ + + + + //! Destructor + PrimList::~PrimList(){ + for(size_t i=0;i<m_scans.size();i++){ + delete m_scans[i]; + delete m_options[i]; + } + } + + PixScan* PrimList::getScan(int index) { + if((unsigned)index<m_scans.size())return m_scans.at(index); + else return 0; + } + std::string PrimList::getScanName(int index){ + if((unsigned)index<m_scannames.size())return m_scannames.at(index); + else return ""; + } + std::string PrimList::getPreScript(int index){ + if((unsigned)index<m_preScripts.size())return m_preScripts.at(index); + else return ""; + } + std::string PrimList::getPostScript(int index){ + if((unsigned)index<m_postScripts.size())return m_postScripts.at(index); + else return ""; + } + std::string PrimList::getTopConfig(int index){ + if((unsigned)index<m_topConfigs.size())return m_topConfigs.at(index); + else return ""; + } + ipc::ScanOptions* PrimList::getScanOptions(int index) { + if((unsigned)index<m_options.size())return m_options.at(index); + else return 0; + } + std::vector<std::string>& PrimList::getDisabledList(int index) { + assert((unsigned)index<m_disabled.size()); + return m_disabled.at(index); + } + std::vector<std::string>& PrimList::getEnabledList(int index) { + assert((unsigned)index<m_enabled.size()); + return m_enabled.at(index); + } + int PrimList::getPause(int index){ + if((unsigned)index<m_scannames.size())return m_pause.at(index); + else return 0; + } + bool PrimList::getUpdateConfig(int index) + { + assert((unsigned)index<m_enabled.size()); + return m_updateConfigs.at(index); + } + void PrimList::addScan(std::string scanname, PixScan* scan, std::string preScript, std::string postScript, std::vector<std::string> enables, std::vector<std::string> disables, bool updateConfig, std::string topConfig, int pause) { + m_scannames.push_back(scanname); + m_preScripts.push_back(preScript); + m_postScripts.push_back(postScript); + m_enabled.push_back(enables); + m_disabled.push_back(disables); + m_scans.push_back(scan); + m_updateConfigs.push_back(updateConfig); + ipc::ScanOptions *scanopt=new ipc::ScanOptions; + scan->convertScanConfig(*scanopt); + m_options.push_back(scanopt); + m_topConfigs.push_back(topConfig); + m_pause.push_back(pause); + } + + void PrimList::clearScans() + { + for(size_t i=0;i<m_scans.size();i++){ + delete m_scans[i]; + delete m_options[i]; + } + m_scans.clear(); + m_options.clear(); + m_scannames.clear(); + m_preScripts.clear(); + m_postScripts.clear(); + m_enabled.clear(); + m_disabled.clear(); + m_updateConfigs.clear(); + m_topConfigs.clear(); + m_pause.clear(); + } + + + + + + +} + + + + + + diff --git a/rce/rcecalib/server/PrimList.hh b/rce/rcecalib/server/PrimList.hh new file mode 100644 index 0000000000000000000000000000000000000000..a1ccdd704c232329dc7a6966e6deced2081924fe --- /dev/null +++ b/rce/rcecalib/server/PrimList.hh @@ -0,0 +1,69 @@ +#ifndef PRIMLIST_HH +#define PRIMLIST_HH + +#include "PixScan.hh" +#include "ScanOptions.hh" +#include "Callback.hh" +#include "PixScanBase.h" + +using namespace ipc; + + +#include <vector> +#include <list> +#include <map> +#include <string> +#include <assert.h> +#include <sys/time.h> +#include "ScanOptions.hh" + + +namespace RCE { + + class PixScan; + + + class PrimList //: public PixLib::PixScanBase +{ + + + +private: + std::vector <PixScan*> m_scans; + std::vector <ipc::ScanOptions*> m_options; + std::vector <std::string> m_scannames; + std::vector <std::string> m_preScripts; //filepath of shell scripts to be executed before scan + std::vector <std::string> m_postScripts; //filepath of scripts to be executed after scan + std::vector <std::vector<std::string> > m_enabled; //enabled frontends + std::vector <std::vector<std::string> > m_disabled; //disabled frontends + std::vector <bool> m_updateConfigs; + std::vector<std::string> m_topConfigs; + std::vector<int> m_pause; +public: + //! Constructors + PrimList() {}; + + //! Destructor + ~PrimList(); + + //! Get Functions + PixScan* getScan(int index); + ipc::ScanOptions* getScanOptions(int index); + unsigned nScans(){return m_scans.size();} + std::string getScanName(int index); + std::string getPreScript(int index); + std::string getPostScript(int index); + std::vector<std::string>& getDisabledList(int index); + std::vector<std::string>& getEnabledList(int index); + bool getUpdateConfig(int index); + void addScan(std::string scanname, PixScan* scan, std::string preScript, std::string postScript, std::vector<std::string> enables, std::vector<std::string> disables, bool updateConfig, std::string topConfig, int pause); + void clearScans(); + std::string getTopConfig(int index); + int getPause(int index); + }; + +} +#endif + + + diff --git a/rce/rcecalib/server/PrimListGui.cc b/rce/rcecalib/server/PrimListGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..00ecb10a6efa9b0be1d8bdab4591a72be21e6613 --- /dev/null +++ b/rce/rcecalib/server/PrimListGui.cc @@ -0,0 +1,572 @@ +#include "rcecalib/server/PrimListGui.hh" +#include "rcecalib/server/PrimList.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/ConfigGui.hh" +#include "ScanOptions.hh" +#include <iostream> +#include <fstream> +#include <string> +#include <sstream> +#include <algorithm> +using namespace RCE; + +PrimListGui::PrimListGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options): + + TGVerticalFrame(p,w,h,options), m_pList(new PrimList) +{ + + m_name=new TGLabel(this,name); + AddFrame(m_name,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 10, 0)); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_name->SetTextFont(labelfont); + + TGHorizontalFrame *btnFrame = new TGHorizontalFrame(this, 2,2 ); + AddFrame(btnFrame,new TGLayoutHints(kLHintsExpandX )); + TGTextButton* loadBtn =new TGTextButton(btnFrame,"Load Primlist"); + loadBtn->SetFont(labelfont); + loadBtn->SetMargins(5,10,5,5); + loadBtn->Connect("Clicked()", "PrimListGui", this,"load()"); + btnFrame->AddFrame(loadBtn,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + + TGTextButton* clearBtn =new TGTextButton(btnFrame,"Clear Primlist"); + clearBtn->SetFont(labelfont); + clearBtn->SetMargins(5,10,5,5); + clearBtn->Connect("Clicked()", "PrimListGui", this,"clear()"); + btnFrame->AddFrame(clearBtn,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + plStatusLabel = new TGLabel(btnFrame, " "); + FontStruct_t statusfont= gClient->GetFontByName("-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1"); + plStatusLabel->SetTextFont(statusfont); + btnFrame->AddFrame(plStatusLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 20, 2, 2, 0)); + +} + + + + +PrimListGui::~PrimListGui(){ + Cleanup(); +} + +void PrimListGui::updateText(TGLabel* label, const char* newtext){ + //unsigned len=strlen(label->GetText()->GetString()); + label->SetText(newtext); + //if (strlen(newtext)>len)Layout(); + Layout(); +} + +void PrimListGui::disableControls(){ + +} +void PrimListGui::enableControls(){ + +} + +void PrimListGui::printFromGui(){ + // print(std::cout); +} + +void PrimListGui::print(std::ostream &os){ + +} + +RCE::PrimList* PrimListGui::getPrimList(){ + return m_pList; +} +int PrimListGui::loadPrimList(const char* fPath)//Name,Flavor,Threshold,Charge,ToT +{std::cout << "LOADING" << std::endl; + int loaded=0; + std::ifstream file; + file.open(fPath); + if (file.is_open()) + { + std::string line; + int i = 1; + while (file.good() ) + { + std::getline(file,line); + if(line.compare("")== 0) + break; + int err = parseScan(line); + if (err == 0) + { + loaded++; + } + else + { + //m_pList=new PrimList(); + std::string failSt = "Failed to load PrimList on item " + i; + updateStatus(failSt); + std::cout << "NULL SCAN" << line << " error "<<err<<std::endl; + clear(); + return 0; + } + + } + + file.close(); + } + //check to make sure scannames are good (DEBUG LATER) +/* + std::vector<std::string>::iterator itr; + for ( itr = m_scannames.begin(); itr != m_scannames.end(); ++itr ) + { + int str = m_scantypes.find(*itr)->second; + std::cout << "NAME " << *itr << str << std::endl; + //std::map <std::string, int>::const_iterator itr2; + if (m_scantypes.find(*itr) == m_scantypes.end()) + { + std::string failSt = "Bad scan name: ";// + str + "!"; + updateStatus(failSt); + m_pList = new PrimList(); + return -1; + } + }*/ + return loaded; + +} + +void PrimListGui::setScanTypes (std::map<int, std::string> pscantypes) +{ + std::map<std::string,int> revMap; + std::map<int,std::string>::iterator it; + for ( it=pscantypes.begin() ; it != pscantypes.end(); it++ ) + { + std::transform((*it).second.begin(), (*it).second.end(), (*it).second.begin(), ::toupper); + revMap.insert(std::pair<std::string, int>((*it).second, (*it).first)); + } + m_scantypes = revMap; + +} + +void PrimListGui::setFlavor(std::string pFlavor) +{ + flavor = pFlavor; +} +int PrimListGui::parseScan(std::string line)//Name,Flavor,Options +{ + PixScan* scan; + std::string scnName, scnFlavour, tmp; + std::istringstream buf(line); + getline(buf, scnName, ','); + getline(buf, scnFlavour, ','); + //to uppercase for user error + std::transform(scnName.begin(), scnName.end(), scnName.begin(), ::toupper); + std::transform(scnFlavour.begin(), scnFlavour.end(), scnFlavour.begin(), ::toupper); + //remove accidental spaces + std::string::iterator end_pos = std::remove(line.begin(), line.end(), ' '); + line.erase(end_pos, line.end()); + if (scnName == NULL || scnName == "" || scnFlavour == NULL || scnFlavour == "" ) + { + return 1; //error + } + PixLib::EnumFEflavour::FEflavour fl=PixLib::EnumFEflavour::PM_FE_I4A; + if(scnFlavour=="FEI3")fl=PixLib::EnumFEflavour::PM_FE_I2; + else if (scnFlavour=="FEI4A")fl=PixLib::EnumFEflavour::PM_FE_I4A; + else if (scnFlavour=="FEI4B")fl=PixLib::EnumFEflavour::PM_FE_I4B; + if(m_scantypes.find(scnName)==m_scantypes.end())return 2; //error + scan = new PixScan((PixScan::ScanType) m_scantypes[scnName],fl); + std::string preScript=""; + std::string postScript=""; + std::string topConfig=""; + bool updateConfig=true; + std::vector<std::string> enables; + std::vector<std::string> disables; + int pause=0; + //Look for optional scan parameters + std::string optPar; + while (getline(buf, optPar, ',')) + { + std::string paramName, paramVal; + std::istringstream buf2 (optPar); + getline(buf2, paramName, '='); + getline(buf2, paramVal); + int err=setScanParam(paramName, paramVal, scan, preScript, postScript, enables, disables, + updateConfig, topConfig, pause); + if(err!=0){ + delete scan; + return 3; + } + } + m_pList->addScan(scnName, scan, preScript, postScript, enables, disables, updateConfig, topConfig, pause); + + + return 0; + +} +int PrimListGui::toInt(std::string str) +{ + int result; + std::stringstream(str) >> result; + return result; +} + +void PrimListGui::load() +{ + + TGFileInfo fileinfo; + new TGFileDialog(gClient->GetRoot(), 0, kFDOpen, &fileinfo); + if(!fileinfo.fFilename){ + printf("Scheisse\n"); + return; + } + int load = loadPrimList(fileinfo.fFilename); + std::stringstream buf; + if(load != 0 && isLoaded()) { + buf << "Loaded "<< load << " items from " << fileinfo.fFilename<<". "<<getNumScans()<<" items total."; + updateStatus(buf.str()); + } + currentScan=0; +} +void PrimListGui::clear() +{ + currentScan=0; + m_pList->clearScans(); + std::stringstream buf; + buf << "No primlist loaded."; + updateStatus(buf.str()); +} +int PrimListGui::setScanParam(std::string name, std::string value, PixScan* pScan, std::string &preScript, + std::string &postScript, std::vector<std::string> &enabled, std::vector<std::string> &disabled, + bool &updateConfig, std::string &topConfig, int &pause) +{ + //convert name to uppercase to avoid any case issue + + std::transform(name.begin(), name.end(), name.begin(), ::toupper); + if(name.compare("TOPCONFIG")==0 ) + { + topConfig=value; + return 0; + } + if(name.compare("SCRIPT")==0 || name.compare("PRESCRIPT")==0 )//Don't want to change case! + { + preScript=value; + return 0; + } + if(name.compare("POSTSCRIPT")==0) + { + postScript=value; + return 0; + } + std::transform(value.begin(), value.end(), value.begin(), ::toupper); + if(name.compare("UPDATECONFIG")==0) + { + updateConfig=toBool(value); + } + else if(name.compare("PAUSE")==0) + { + pause=toInt(value); + } + else if(name.compare("MODSCANCONCURRENT")==0) + { + pScan->setModScanConcurrent(toBool(value)); + } + else if(name.compare("MASKSTAGESTEPS")==0) + { + pScan->setMaskStageSteps(toInt(value)); + } + else if (name.compare("TUNINGSTARTFROMCONFIGVALUE")==0) + { + pScan->tuningStartsFromCfgValues(toBool(value)); + } + else if (name.compare("REPETITIONS")==0) + { + pScan->setRepetitions(toInt(value)); + } + else if (name.compare("SELFTRIGGER")==0) + { + pScan->setSelfTrigger(toBool(value)) ; + } + else if (name.compare("STROBELVL1DELAYOVERRIDE")==0) + { + pScan->setStrobeLVL1DelayOveride(toBool(value)) ; + } + else if (name.compare("STROBELVL1DELAY")==0) + { + pScan->setStrobeLVL1Delay(toInt(value)) ; + } + else if (name.compare("LVL1LATENCY")==0) + { + pScan->setLVL1Latency(toInt(value)) ; + } + else if (name.compare("STROBEMCCDELAY")==0) + { + pScan->setStrobeMCCDelay(toInt(value)) ; + } + else if (name.compare("STROBEMCCDELAYRANGE")==0) + { + pScan->setStrobeMCCDelayRange(toInt(value)) ; + } + else if (name.compare("STROBEDURATION")==0) + { + pScan->setStrobeDuration(toInt(value)) ; + } + else if (name.compare("CLEARMASKS")==0) + { + pScan->setClearMasks(toInt(value)) ; + } + else if (name.compare("MODULEMASK")==0)//format MODULEMASK=Group;Mask + { + std::vector <std::string> values = toVector(value); + int group = toInt(values[0]); + int mask = toInt(values[1]); + pScan->setModuleMask(group,mask); + } + else if (name.compare("CONFIGENABLED")==0)//format Group;Enabled + { + std::vector <std::string> values = toVector(value); + int group = toInt(values[0]); + bool ena = toBool(values[1]); + pScan->setConfigEnabled(group,ena); + } + else if (name.compare("TRIGGERENABLED")==0)//format Group;Enabled + { + std::vector <std::string> values = toVector(value); + int group = toInt(values[0]); + bool ena = toBool(values[1]); + pScan->setTriggerEnabled(group,ena); + } + else if (name.compare("STROBEENABLED")==0)//format Group;Enabled + { + std::vector <std::string> values = toVector(value); + int group = toInt(values[0]); + bool ena = toBool(values[1]); + pScan->setStrobeEnabled(group,ena); + } + else if (name.compare("MODULEMASK")==0) + { + pScan->setStrobeMCCDelayRange(toInt(value)) ; + } + else if (name.compare("FEVCAL")==0) + { + pScan->setFeVCal(toInt(value)) ; + } + else if (name.compare("THRESHOLDTARGETVALUE")==0) + { + if(toInt(value)>0)//If value is 0, should just use default + pScan->setThresholdTargetValue(toInt(value)); + } + else if (name.compare("TOTTARGETCHARGE")==0) + { + if(toInt(value)>0)//If value is 0, should just use default + pScan->setTotTargetCharge(toInt(value)); + } + else if (name.compare("TOTTARGETVALUE")==0) + { + if(toInt(value)>0)//If value is 0, should just use default + pScan->setTotTargetValue(toInt(value)); + } + else if (name.compare("STEPSTAGE")==0) + { + pScan->setStepStage(toInt(value)); + } + else if (name.compare("SETUPTHRESHOLD")==0) + { + pScan->setSetupThreshold(toBool(value)); + } + else if (name.compare("THRESHOLD")==0) + { + pScan->setThreshold(toInt(value)); + } + else if (name.compare("TIMEOUTSECONDS")==0) + { + pScan->setTimeoutSeconds(toInt(value)); + } + else if (name.compare("LVL1LATENCY")==0) + { + pScan->setLVL1Latency(toInt(value)); + } + else if (name.compare("STROBEDURATION")==0) + { + pScan->setStrobeDuration(toInt(value)); + } + + else if (name.compare("MODCONFIGTYPE")==0) + { + PixLib::EnumModConfigType enumObj; + std::map<std::string, int> enummap = enumObj.EnumModConfigTypeMap(); + pScan->setModConfig((PixLib::EnumModConfigType::ModConfigType)enummap[value]); + } + else if (name.compare("MASKSTAGEMODE")==0) + { + PixLib::EnumMaskStageMode enumObj; + std::map<std::string, int> enummap = enumObj.EnumMaskStageModeMap(); + pScan->setMaskStageMode((PixLib::EnumMaskStageMode::MaskStageMode)enummap[value]); + + } + else if (name.compare("MASKSTAGETOTALSTEPS")==0) + { + PixLib::EnumMaskSteps enumObj; + std::map<std::string, int> enummap = enumObj.EnumMaskStageStepsMap(); + pScan->setMaskStageTotalSteps((PixLib::EnumMaskSteps::MaskStageSteps)enummap[value]); + } + else if (name.compare("MODULETRGMASK")==0) + { + pScan->setModuleTrgMask(toInt(value)); + } + //Loop Variable Values + else if (name.compare("LOOPVARVALUES")==0) + { + int index; + std::string tmp; + std::istringstream buf (value); + getline(buf, tmp, ';'); + index = toInt(tmp); + size_t begOfVector = value.find('['); + if(begOfVector == std::string::npos)//then format index;startVal;endVal;nSteps + { + int nSteps; + double startVal, endVal; + getline(buf, tmp, ';'); + startVal=toDouble(tmp); + getline(buf, tmp, ';'); + endVal=toDouble(tmp); + getline(buf, tmp, ';'); + nSteps=toInt(tmp); + pScan->setLoopVarValues(index, startVal, endVal, nSteps); + } + else //then format [val1;val2;val3;...] + { + std::vector <float> values; + size_t endOfVector = value.find(']'); + value = value.substr(begOfVector+1, endOfVector-begOfVector-1); //trim off index[, ] + new (&buf) std::istringstream (value); + while (getline(buf, tmp, ';')) + { + values.push_back(toDouble(tmp)); + } + pScan->setLoopVarValues(index, values); + + } + + } + else if (name.compare("ENABLEFES")==0 || name.compare("DISABLEFES")==0 ) + { + value.erase (std::remove (value.begin(), value.end(), ' '), value.end()); + std::string tmp; + std::istringstream buf (value); + std::vector <float> values; + while (getline(buf, tmp, ';')) + { + if(name.compare("ENABLEFES")==0)enabled.push_back(tmp); + else disabled.push_back(tmp); + } + } + else + { + std::string st = "Unrecognized scan parameter name: " + name; + updateStatus(st); + return 1; + } + return 0; + +} +std::vector <std::string> PrimListGui::toVector(std::string value) +{ + std::vector <std::string> values; + std::istringstream buf (value); + std::string tmp; + while (getline(buf, tmp, ';')) + { + values.push_back(tmp); + } + return values; +} +double PrimListGui::toDouble(std::string val) +{ + double result; + std::stringstream(val) >> result; + return result; +} +bool PrimListGui::toBool(std::string val) +{ + bool result; + std::stringstream(val) >> result; + return result; +} + +bool PrimListGui::isLoaded() +{ + return m_pList->nScans() > 0; +} +void PrimListGui::updateStatus(std::string str) +{ + updateText(plStatusLabel, str.c_str()); +} +int PrimListGui::getNumScans() +{ + return m_pList->nScans(); +} +std::string PrimListGui::getCurrScanName() +{ + return m_pList->getScanName(currentScan); + +} +RCE::PixScan* PrimListGui::getCurrentScan() +{ + return getPrimList()->getScan(currentScan); +} +std::string PrimListGui::getCurrentPreScript() +{ + return m_pList->getPreScript(currentScan); +} +std::string PrimListGui::getCurrentPostScript() +{ + return m_pList->getPostScript(currentScan); +} +int PrimListGui::getCurrentPause() +{ + return m_pList->getPause(currentScan); +} +std::string PrimListGui::getCurrentTopConfig() +{ + return m_pList->getTopConfig(currentScan); +} +ipc::ScanOptions* PrimListGui::getCurrentScanConfig() +{ + return getPrimList()->getScanOptions(currentScan); +} +std::vector<std::string>& PrimListGui::getCurrentDisabledList(){ + return m_pList->getDisabledList(currentScan); +} +std::vector<std::string>& PrimListGui::getCurrentEnabledList(){ + return m_pList->getEnabledList(currentScan); +} +void PrimListGui::setRunNumber(int runnum){ + getCurrentScan()->setRunNumber(runnum); + getCurrentScanConfig()->runNumber=runnum; +} + +bool PrimListGui::getCurrentUpdateConfig() +{ + return m_pList->getUpdateConfig(currentScan); +} + +void PrimListGui::changeIncludes(ConfigGui* cfg[]){ + for (int i=0;i<ConfigGui::MAX_MODULES;i++){ + if(cfg[i]->isIncluded()){ + std::vector<std::string> dis=getCurrentDisabledList(); + for(size_t j=0;j<dis.size();j++){ + if (cfg[i]->getName()==dis[j]){ + cfg[i]->setIncluded(false); + std::cout<<"Disabled FE "<<dis[j]<<std::endl; + break; + } + } + }else if (cfg[i]->isValid()){ + std::vector<std::string> en=getCurrentEnabledList(); + for(size_t j=0;j<en.size();j++){ + if (cfg[i]->getName()==en[j]){ + cfg[i]->setIncluded(true); + std::cout<<"Enabled FE "<<en[j]<<std::endl; + break; + } + } + } + } +} + + + + + diff --git a/rce/rcecalib/server/PrimListGui.hh b/rce/rcecalib/server/PrimListGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..a306e60534dce39b4083c4f4b783a0251f516924 --- /dev/null +++ b/rce/rcecalib/server/PrimListGui.hh @@ -0,0 +1,83 @@ +#ifndef PRIMLISTGUI_HH +#define PRIMLISTGUI_HH + +#include <TGButton.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include <TGLabel.h> +#include <TGComboBox.h> +#include <TGListBox.h> +#include <TGFileDialog.h> +#include <TGListView.h> +#include <fstream> +#include <string> +#include <map> +#include <utility> + + +//push update after scan +namespace ipc{ + class ScanOptions; +} +namespace RCE { + class PixScan; + class PrimList; +} +class ConfigGui; + +class PrimListGui: public TGVerticalFrame{ +public: + PrimListGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options); + virtual ~PrimListGui(); + void print(std::ostream &os); + void printFromGui(); + void disableControls(); + void enableControls(); + RCE::PrimList* getPrimList(); + void load(); + int loadPrimList(const char* fPath); + void clear(); + void setFlavor(std::string pFlavor); + void setScanTypes (std::map<int, std::string> pscantypes); + bool isLoaded(); + void updateStatus(std::string str); + int currentScan; + std::string getCurrScanName(); + int getNumScans(); + RCE::PixScan* getCurrentScan(); + ipc::ScanOptions* getCurrentScanConfig(); + std::string getCurrentPreScript(); + std::string getCurrentPostScript(); + std::string getCurrentTopConfig(); + std::vector<std::string>& getCurrentDisabledList(); + std::vector<std::string>& getCurrentEnabledList(); + bool getCurrentUpdateConfig(); + int getCurrentPause(); + void changeIncludes(ConfigGui* cfg[]); + void setFailed(bool on){m_failed=on;} + bool failed(){return m_failed;} + void setRunNumber(int runnum); +private: + RCE::PrimList* m_pList; + TGLabel *m_name; + TGLabel *plStatusLabel; + void updateText(TGLabel* label, const char* newtext); + //both flavor passed from CalibGui + std::string flavor; + //scan types copied from ScanGui + std::map<std::string, int> m_scantypes; + bool m_failed; + //helper functions + int toInt(std::string); + int parseScan(std::string line); + int setScanParam(std::string name, std::string value, RCE::PixScan* pScan, std::string &preScript, + std::string &postScript, std::vector<std::string> &enabled, + std::vector<std::string> &disabled, bool &updateConfig, std::string &topConfig, int &pause); + bool toBool(std::string val); + double toDouble(std::string val); + std::vector <std::string> toVector(std::string value); + + ClassDef(PrimListGui,0); +}; + +#endif diff --git a/rce/rcecalib/server/RceControl.cc b/rce/rcecalib/server/RceControl.cc new file mode 100644 index 0000000000000000000000000000000000000000..6a2aef1228620f7c615171459d948545c4a2750a --- /dev/null +++ b/rce/rcecalib/server/RceControl.cc @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <iostream> +#include <fstream> +#include <string.h> +#include "rcecalib/server/BootLoaderPort.hh" +#include <boost/algorithm/string.hpp> +#include <termios.h> +#include "RceControl.hh" + +#include <arpa/inet.h> // for htonl +namespace RCE { + RceControl::RceControl(const char *rce,int timeout):m_rce(rce),m_timeout(timeout) { + m_dst=RceNet::IpAddress(RceNet::getaddr(rce),BootloaderPort);} + + int RceControl::setEnvVar(const char *var,const char *val) { + std::string inpline; + inpline="setenv "+std::string(var)+std::string(" ")+std::string(val); + sendCommand(inpline); + return 0; + } + + + + int RceControl::setIorFromFile(const char *iorfile) { + std::string inpline; + //std::istream *inp; + if(!iorfile) iorfile=getenv("TDAQ_IPC_INIT_REF"); + if(strstr(iorfile,"file:/") )iorfile+=6; + if(iorfile){ + std::ifstream g(iorfile); + if (!g.good()) { + std::cout<<"Error: Could not find file "<<iorfile<<std::endl; + return -1; + } + inpline=""; + getline (g,inpline); + g.close(); + if(inpline.substr(0,4)!="IOR:"){ + std::cout<<"Error: "<<iorfile<<" does not contain an IOR string"<<std::endl; + return -1; + } + inpline="setenv TDAQ_IPC_INIT_REF "+inpline; + sendCommand(inpline); + } + return 0; + } + +int RceControl::loadModule(const char *filename) { + if(!filename) return -1; + // Read module into buffer + std::ifstream f(filename); + if (!f.good()) { + std::cout<<"Error: Could not find file "<<filename<<std::endl; + return -1; + } + f.seekg(0, std::ios::end); + unsigned length = f.tellg(); + f.seekg(0, std::ios::beg); + char *buffer=new char[length]; + f.read(buffer,length); + char msg[128]; + // send download command + sprintf(msg,"download %d bytes",length); + std::string rep=sendCommand(msg); + if(rep!="OK") return -1; + std::cout<<"HOST"<<" => "<<m_rce<<": Uploading module."<<std::endl; + // download module + RceNet::SocketTcp socket2; + socket2.connect(m_dst); + socket2.send(buffer, length); + delete [] buffer; + // receive confirmation + socket2.setrcvtmo(m_timeout); + int bytes=socket2.recv(msg,128); + socket2.close(); + if(bytes<0){ + std::cout<<"Receive error."<<std::endl; + } + msg[bytes]=0; + std::cout<<"HOST"<<" <= "<<m_rce<<": "<<msg<<std::endl; + return 0; +} + +const char* RceControl::sendCommand(std::string inpline){ + std::cout<<"HOST"<<" => "<<m_rce<<": "<<inpline<<std::endl; + RceNet::SocketTcp *socket=0; + int nretries=10; + while(nretries>0){ + try{ + socket=new RceNet::SocketTcp; + socket->connect(m_dst); + socket->send(inpline.c_str(), inpline.size()); + break; + } catch (...){ + //std::cout<<"Connect failed. Trying again"<<std::endl; + nretries--; + delete socket; + sleep(1); + } + } + if(nretries==0){ + std::cout<<"Network error. Exiting."<<std::endl; + exit(0); + } + static char line[128]; + try{ + socket->setrcvtmo(m_timeout); + int bytes=socket->recv(line,128); + line[bytes]=0; + std::cout<<"HOST"<<" <= "<<m_rce<<": "<<line<<std::endl; + //if(std::string(line)=="Rebooting...")sleep(1); // wait for reboot to finish + } + catch (...){ + std::cout<<"Network error. Exiting."<<std::endl; + delete socket; + return 0; + } + socket->close(); + delete socket; + return line; +} + +} diff --git a/rce/rcecalib/server/RceControl.hh b/rce/rcecalib/server/RceControl.hh new file mode 100644 index 0000000000000000000000000000000000000000..4e89e2a87c0c1fc2bfd85c299de934af51ac940f --- /dev/null +++ b/rce/rcecalib/server/RceControl.hh @@ -0,0 +1,34 @@ +#ifndef __RCE_CONTROL_HH__ +#define __RCE_CONTROL_HH__ +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( oldPpi, net, IpAddress.hh) +#include DAT_PUBLIC( oldPpi, net, Error.hh) +#include DAT_PUBLIC( oldPpi, net, Getaddr.hh) +#include DAT_PUBLIC( oldPpi, net, SocketTcp.hh) + +#else +#include "rce/net/IpAddress.hh" +#include "rce/net/Getaddr.hh" +#include "rce/net/IpAddress.hh" +#include "rce/net/SocketTcp.hh" +#include "rce/net/Error.hh" +#endif +#include "namespace_aliases.hh" +namespace RCE { + class RceControl { + public: + RceControl(){}; + RceControl(const char *rce,int timeout=10000); + int setIorFromFile(const char* iorfile=NULL); + int setEnvVar(const char* var,const char *val); + int loadModule(const char *name); + int runScript(const char *name); + const char* sendCommand(std::string inpline); + private: + std::string m_rce; + int m_timeout; + RceNet::IpAddress m_dst; + }; +} +#endif diff --git a/rce/rcecalib/server/RceOfflineProducer.cc b/rce/rcecalib/server/RceOfflineProducer.cc new file mode 100644 index 0000000000000000000000000000000000000000..ba429f85dfbe4e55ecd3bbe0a7597f6c8a1c9ae6 --- /dev/null +++ b/rce/rcecalib/server/RceOfflineProducer.cc @@ -0,0 +1,380 @@ +#include "rcecalib/server/RceOfflineProducer.hh" +#include "rcecalib/server/CosmicDataReceiver.hh" +#include "rcecalib/server/CosmicDataReceiver.hh" +#include "rcecalib/config/ModuleInfo.hh" +#include "rcecalib/eudaq/ProducerIF.hh" +#include "rcecalib/eudaq/RawDataEvent.hh" +#include "rcecalib/eudaq/Utils.hh" +#include "rcecalib/eudaq/Exception.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/server/HitbusConfigFile.hh" +#include "rcecalib/config/FEI3/JJFormatter.hh" +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FEI4/FEI4BFormatter.hh" +#include <cmdl/cmdargs.h> +#include "rcecalib/util/RceName.hh" +#include <iostream> +#include <ostream> +#include <vector> +#include <stdio.h> +#include <sys/stat.h> +#include <ipc/core.h> + +#include <netdb.h> + +namespace{ + static const std::string EVENT_TYPE = "APIX-CT"; + + void startScan(void* arg){ + IPCController* controller=(IPCController*)arg; + controller->startScan(); + } +} +using namespace RCE; + +RceOfflineProducer::RceOfflineProducer(const std::string & name, const std::string & runcontrol, IPCPartition& p, int rce) + : eudaq::Producer(name, runcontrol), m_run(0), m_PlaneMask(0), m_conseq(1), m_rce(rce), m_controller(new IPCController(p)), + m_options(0), m_datareceiver(0){ + std::cout<<"Rce producer on RCE "<<m_rce<<std::endl; +} + +RceOfflineProducer::~RceOfflineProducer(){ + delete m_controller; + if (m_datareceiver) delete m_datareceiver; + m_datareceiver = 0; +} +// This gets called whenever the DAQ is configured +void RceOfflineProducer::OnConfigure(const eudaq::Configuration & config) { + std::cout << "Configuring: " << config.Name() << std::endl; + std::cout<<config<<std::endl; + char msg[64]; + try{ + //Default Trigger IF + for(size_t i=0;i<m_moduleinfo.size();i++){ + delete m_moduleinfo[i]->getFormatter(); + delete m_moduleinfo[i]; + } + m_moduleinfo.clear(); + m_controller->removeAllRces(); + m_controller->addRce(m_rce); + m_controller->setupTrigger(); + m_controller->removeAllModules(); + m_numboards = config.Get("nFrontends", -1); + if(m_numboards==-1)throw eudaq::Exception("nFrontends not defined"); + m_link.clear(); + m_sensor.clear(); + m_pos.clear(); + m_stype.clear(); + for(int i=0;i<m_numboards;i++){ + int outlink = config.Get("Module" + eudaq::to_string(i) + ".OutLink", "OutLink", -1); + if(outlink==-1){ + sprintf(msg,"Module %d: Outlink is not defined.",i); + throw eudaq::Exception(msg); + } + m_link.push_back(outlink); + int inlink = config.Get("Module" + eudaq::to_string(i) + ".InLink", "InLink", -1); + if(inlink==-1){ + sprintf(msg,"Module %d: Inlink is not defined.",i); + throw eudaq::Exception(msg); + } + int id = config.Get("Module" + eudaq::to_string(i) + ".FEID", "FEID", -1); + if(id==-1){ + sprintf(msg,"Frontend %d: FEID is not defined.",i); + throw eudaq::Exception(msg); + } + int sid = config.Get("Module" + eudaq::to_string(i) + ".SensorId", "SensorId", -1); + if(sid==-1){ + sprintf(msg,"Frontend %d: sensor id is not defined.",i); + throw eudaq::Exception(msg); + } + m_sensor.push_back(sid); + int lr = config.Get("Module" + eudaq::to_string(i) + ".Position", "Position", -1); + if(lr==-1){ + sprintf(msg,"Frontend %d: Position is not defined.",i); + throw eudaq::Exception(msg); + } + m_pos.push_back(lr); + int stype = config.Get("Module" + eudaq::to_string(i) + ".ModuleType", "ModuleType", -1); + if(stype==-1){ + sprintf(msg,"Frontend %d: Module sensor type is not defined.",i); + throw eudaq::Exception(msg); + } + if(stype<1 || stype>4){ //only 1, 2, and 4-chip modules and FEI3 chips are defined at this point + sprintf(msg,"Frontend %d: Module sensor type %d does not exist.", i, stype); + throw eudaq::Exception(msg); + } + if(stype!=3 && lr>=stype){ + sprintf(msg,"Frontend %d: Position %d does not exist in %d-chip sensors.", i, lr, stype); + throw eudaq::Exception(msg); + } + if(m_stype.find(sid)==m_stype.end())m_stype[sid]=stype; + else if(m_stype[sid]!=stype){ + sprintf(msg, "Module %d: Definition of module type clashes with the definition for a different FE of the same sensor", i); + throw eudaq::Exception(msg); + } + std::string modtype = config.Get("Module" + eudaq::to_string(i) + ".Type", "Type", ""); + if(modtype==""){ + sprintf(msg,"Module %d: Module frontend type is not defined.",i); + throw eudaq::Exception(msg); + } + std::string filename = config.Get("Module" + eudaq::to_string(i) + ".File", "File", ""); + if(filename==""){ + sprintf(msg,"Module %d: Configuration filename is not defined.",i); + throw eudaq::Exception(msg); + } + + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(filename.c_str(),&stFileInfo); + if(intStat!=0) { //file does not exist + sprintf(msg, "Configuration: File %s does not exist.",filename.c_str()); + throw eudaq::Exception(msg); + } + // create module via IPC + char modname[32]; + sprintf(modname,"RCE%d_module_%d",m_rce, outlink); + if(modtype=="FEI4A"){ + printf("FEI4A: addModule (%s, %d, %d, %d, %d)\n",modname, 0, inlink, outlink, m_rce); + m_controller->addModule(modname, "FEI4A",id, inlink, outlink, m_rce, "FEI4A"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 1, 336, 80, new FEI4AFormatter(id))); + FEI4AConfigFile fei4af; + ipc::PixelFEI4AConfig *cfg=new ipc::PixelFEI4AConfig; + fei4af.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(m_rce, id,*cfg); + delete cfg; + // assert(m_controller.writeHWregister(15,0x80)==0); //setup mux + } else if(modtype=="FEI4B"){ + printf("FEI4B: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, m_rce); + m_controller->addModule(modname, "FEI4B",id, inlink, outlink, m_rce, "FEI4B"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 1, 336, 80, new FEI4BFormatter(id))); + FEI4BConfigFile fei4bf; + ipc::PixelFEI4BConfig *cfg=new ipc::PixelFEI4BConfig; + fei4bf.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(m_rce, id,*cfg); + delete cfg; + }else if(modtype=="FEI3"){ + printf("FEI3: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, m_rce); + m_controller->addModule(modname, "FEI3",id, inlink, outlink, m_rce, "JJ"); + m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 16, 160, 18, new JJFormatter(id))); + TurboDaqFile turbo; + ipc::PixelModuleConfig *cfg=new ipc::PixelModuleConfig; + turbo.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(m_rce, id,*cfg); + delete cfg; + } else if(modtype=="Hitbus"){ + printf("Hitbus: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, m_rce); + m_controller->addModule(modname, "Hitbus",id, inlink, outlink, m_rce, ""); + //m_moduleinfo.push_back(new ModuleInfo(modname, id, inlink, outlink, 0, 0, 0, 0)); + HitbusConfigFile hitbusf; + ipc::HitbusModuleConfig *cfg=new ipc::HitbusModuleConfig; + hitbusf.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(m_rce, id,*cfg); + }else{ + std::cout<<"Unknown config"<<std::endl; + } + } + // set up hardware trigger + unsigned goodHSIOconnection=0; + goodHSIOconnection=m_controller->writeHWregister(m_rce, 3,2); //runmode 0=normal 1=tdccalib 2=eudaq assert(serstat==0); + assert(goodHSIOconnection==0); + m_controller->sendHWcommand(m_rce, 17); // Tell the HSIO that the RCE is present. + //serstat=m_controller->writeHWregister(0, 22,1); // coincidence l1 + //serstat=m_controller->writeHWregister(0, 23,1); // coincidence hitbus + //serstat=m_controller->writeHWregister(0, 24,3); // coincidence hitbus + //m_controller.writeHWregister(3,0); //Normal mode + + // Scan configuration + std::cout<<"Deleting scan options "<<m_options<<std::endl; + delete m_options; + PixScan scn(PixScan::COSMIC_DATA, PixLib::EnumFEflavour::PM_FE_I2); + m_options=new ipc::ScanOptions; + scn.setName("TCP"); // send data over the network rather than to file + // Override l1a latency + int latency = config.Get("Latency", -1); + if(latency==-1){ + throw eudaq::Exception("Latency is not defined."); + } + scn.setLVL1Latency(latency); + m_conseq = config.Get("ConseqTriggers", -1); + if(m_conseq==(unsigned)-1){ + throw eudaq::Exception("Number of consecutive triggers is not defined."); + } + scn.setConsecutiveLvl1TrigA(0,m_conseq); + int trgdelay = config.Get("Trgdelay", -1); + if(trgdelay==-1){ + throw eudaq::Exception("Trigger delay is not defined."); + } + scn.setStrobeLVL1Delay(trgdelay); + int deadtime = config.Get("Deadtime", 0); + scn.setDeadtime(deadtime); + int cyclic = config.Get("Cyclic_Period", 40000000); + scn.setEventInterval(cyclic); + scn.setTriggerMask(4); // eudet=4 + + scn.convertScanConfig(*m_options); + //m_controller->downloadScanConfig(*m_options); + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Configured (" + config.Name() + ")"); + } catch (const std::exception & e) { + printf("Caught exception: %s\n", e.what()); + SetStatus(eudaq::Status::LVL_ERROR, "Configuration Error"); + } catch (...) { + printf("Unknown exception\n"); + SetStatus(eudaq::Status::LVL_ERROR, "Configuration Error"); + } +} + + // This gets called whenever a new run is started + // It receives the new run number as a parameter +void RceOfflineProducer::OnStartRun(unsigned param) { + m_run = param; + std::string port="33000"; + std::cout << "Start Run: " << m_run << std::endl; + std::stringstream ss("tcp://"); + ss<<getenv("ORBHOST"); + ss << ":" << port; + std::string address = ss.str(); + std::cout << "<CosmicGui::startRun> : Server address is: " << address << std::endl; + char name[128]; + sprintf(name,"CosmicGui|%05d|%s",m_run,address.c_str()); + m_options->name=CORBA::string_dup(name); + + std::cout << "CosmicGui: starting CosmicDataReceiver at tcp://" << port << std::endl; + std::vector<int> rcesAll; + if(m_numboards>0) for(int i=0;i<m_numboards;i++)rcesAll.push_back(m_rce); //only one RCE + else rcesAll.push_back(m_rce); // no FEs + m_datareceiver = new CosmicDataReceiver(0, m_controller, m_moduleinfo, rcesAll, + m_run, "tcp://" + port, "", false, false); + + m_controller->downloadScanConfig(*m_options); + // It must send a BORE to the Data Collector + eudaq::RawDataEvent bore(eudaq::RawDataEvent::BORE(EVENT_TYPE, m_run)); + // You can set tags on the BORE that will be saved in the data file + // and can be used later to help decoding + bore.SetTag("nFrontends", eudaq::to_string(m_numboards)); + bore.SetTag("consecutive_lvl1", eudaq::to_string(m_conseq)); + char tagname[128]; + for(int i=0;i<m_numboards;i++){ + sprintf(tagname, "OutLink_%d", i); + bore.SetTag(tagname, eudaq::to_string(m_link[i])); + sprintf(tagname, "SensorId_%d", i); + bore.SetTag(tagname, eudaq::to_string(m_sensor[i])); + sprintf(tagname, "Position_%d", i); + bore.SetTag(tagname, eudaq::to_string(m_pos[i])); + sprintf(tagname, "ModuleType_%d", i); + bore.SetTag(tagname, eudaq::to_string(m_stype[m_sensor[i]])); + } + // Send the event to the Data Collector + SendEvent(bore); + // Enable writing events via tcp/ip + ProducerIF::setProducer(this); + //start run + omni_thread::create(startScan,(void*)m_controller); + //m_controller->startScan(); + + std::cout<<"Started scan"<<std::endl; + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Running"); + } + + // This gets called whenever a run is stopped +void RceOfflineProducer::OnStopRun() { + std::cout << "Stopping Run" << std::endl; + + m_controller->stopWaitingForData(); + //wait for late events to trickle in + sleep(1); + //wait for scan to be complete + bool idle=false; + for(int i=0;i<50;i++){ + if(m_controller->getScanStatus()==0){ + std::cout<<"called getstatus"<<std::endl; + idle=true; + break; + } + usleep(100000); + } + if(idle==false)std::cout<<"Scan did not go into idle state"<<std::endl; + //disable sending events via TCP/IP + if (m_datareceiver) delete m_datareceiver; + m_datareceiver = 0; + + ProducerIF::setProducer(0); + // Send an EORE after all the real events have been sent + // You can also set tags on it (as with the BORE) if necessary + unsigned evnum=m_controller->getNEventsProcessed(); + SendEvent(eudaq::RawDataEvent::EORE(EVENT_TYPE, m_run, evnum)); + SetStatus(eudaq::Status::LVL_OK, "Stopped"); + } + + // This gets called when the Run Control is terminating, + // we should also exit. +void RceOfflineProducer::OnTerminate() { + std::cout << "Terminating..." << std::endl; + if (m_datareceiver) delete m_datareceiver; + m_datareceiver = 0; + exit(0); + } + +int main ( int argc, char ** argv ) +{ + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdArgInt rce_number ('r', "rce", "rce-number", "RCE to connect to", CmdArg::isREQ | CmdArg::isVALREQ); + CmdArgStr hostname ('d', "runcontrol", "runcontrol-host", "Run control hostname.", CmdArg::isREQ | CmdArg::isVALREQ); + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + // Declare command object and its argument-iterator + CmdLine cmd(*argv, &partition_name, &rce_number, &hostname, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + + // Parse arguments + + cmd.parse(arg_iter); + + std::string rchost; + hostent * ipAddrContainer = gethostbyname((const char*)hostname); + if (ipAddrContainer != 0) { + int nBytes; + if (ipAddrContainer->h_addrtype == AF_INET) nBytes = 4; + else if (ipAddrContainer->h_addrtype == AF_INET6) nBytes = 6; + else { + std::cout << "Unrecognized IP address type. Run not started." + << std::endl; + exit(0); + } + std::stringstream ss("tcp://"); + ss << "tcp://"; + for (int i = 0, curVal; i < nBytes; i++) + { + curVal = static_cast<int>(ipAddrContainer->h_addr[i]); + if (curVal < 0) curVal += 256; + ss << curVal; + if (i != nBytes - 1) ss << "."; + } + ss<<":44000"; + rchost=ss.str(); + }else{ + std::cout<<"Bad IP address. Exiting."<<std::endl; + exit(0); + } + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(! partition_name.isNULL()) p_name= (const char*)partition_name; + int rce=(int)rce_number; + IPCPartition p(p_name ); + IPCController controller(p); + new IPCHistoManager(p,"RceIsServer", "dummy"); + RceOfflineProducer producer("RceOfflineProducer", rchost.c_str(), p, rce); + sleep(100000000); +} diff --git a/rce/rcecalib/server/RceOfflineProducer.hh b/rce/rcecalib/server/RceOfflineProducer.hh new file mode 100644 index 0000000000000000000000000000000000000000..6cef3ac3b151fe81e3c0fdbf674eb4744fd91c57 --- /dev/null +++ b/rce/rcecalib/server/RceOfflineProducer.hh @@ -0,0 +1,38 @@ +#ifndef RCEPRODUCER_HH +#define RCEPRODUCER_HH + +#include "eudaq/Producer.hh" + +#include "rcecalib/server/IPCController.hh" +#include <vector> + +class ModuleInfo; +class CosmicDataReceiver; + +class RceOfflineProducer : public eudaq::Producer { +public: + RceOfflineProducer(const std::string & name, const std::string & runcontrol, IPCPartition& p, int rce); + virtual ~RceOfflineProducer(); + virtual void OnConfigure(const eudaq::Configuration & config) ; + virtual void OnStartRun(unsigned param) ; + virtual void OnStopRun() ; + virtual void OnTerminate() ; + +private: + unsigned m_run; + unsigned m_PlaneMask; + unsigned m_conseq; + int m_numboards; + int m_rce; + std::vector<int> m_sensor; + std::vector<int> m_pos; + std::vector<int> m_link; + std::vector<int> m_id; + std::map<int, int> m_stype; + IPCController* m_controller; + ipc::ScanOptions* m_options; + std::vector<ModuleInfo*> m_moduleinfo; + CosmicDataReceiver *m_datareceiver; +}; + +#endif diff --git a/rce/rcecalib/server/RceProducer.cc b/rce/rcecalib/server/RceProducer.cc new file mode 100644 index 0000000000000000000000000000000000000000..8d9ca1ea1a71468fc42ad506fb1decabb6593da2 --- /dev/null +++ b/rce/rcecalib/server/RceProducer.cc @@ -0,0 +1,217 @@ +#include "rcecalib/server/RceProducer.hh" +#include "rcecalib/eudaq/ProducerIF.hh" +#include "rcecalib/eudaq/RawDataEvent.hh" +#include "rcecalib/eudaq/Utils.hh" +#include "rcecalib/eudaq/Exception.hh" +#include "rcecalib/server/PixScan.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/util/RceName.hh" +#include <iostream> +#include <ostream> +#include <vector> +#include <stdio.h> +#include <sys/stat.h> + + +namespace{ + static const std::string EVENT_TYPE = "APIX-CT"; + + void startScan(void* arg){ + IPCController* controller=(IPCController*)arg; + controller->startScan(); + } +} +using namespace RCE; + +// This gets called whenever the DAQ is configured +void RceProducer::OnConfigure(const eudaq::Configuration & config) { + std::cout << "Configuring: " << config.Name() << std::endl; + std::cout<<"Deleting scan options "<<m_options<<std::endl; + char msg[64]; + unsigned rce=RceName::getRceNumber(); + try{ + //Default Trigger IF + m_controller.removeAllRces(); + m_controller->addRce(rce); + m_controller->setupTrigger(); + m_controller->removeAllModules(); + int numboards = config.Get("NumModules", -1); + if(numboards==-1)throw eudaq::Exception("NumModules not defined"); + for(int i=0;i<numboards;i++){ + int outlink = config.Get("Module" + eudaq::to_string(i) + ".OutLink", "OutLink", -1); + if(outlink==-1){ + sprintf(msg,"Module %d: Outlink is not defined.",i); + throw eudaq::Exception(msg); + } + m_PlaneMask|=1<<outlink; + int inlink = config.Get("Module" + eudaq::to_string(i) + ".InLink", "InLink", -1); + if(inlink==-1){ + sprintf(msg,"Module %d: Inlink is not defined.",i); + throw eudaq::Exception(msg); + } + int id = config.Get("Module" + eudaq::to_string(i) + ".Id", "Id", -1); + if(id==-1){ + sprintf(msg,"Module %d: id is not defined.",i); + throw eudaq::Exception(msg); + } + std::string modtype = config.Get("Module" + eudaq::to_string(i) + ".Type", "Type", ""); + if(modtype==""){ + sprintf(msg,"Module %d: Module type is not defined.",i); + throw eudaq::Exception(msg); + } + std::string filename = config.Get("Module" + eudaq::to_string(i) + ".File", "File", ""); + if(filename==""){ + sprintf(msg,"Module %d: Configuration filename is not defined.",i); + throw eudaq::Exception(msg); + } + + filename="/nfs/moduleconfigs/"+filename; + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(filename.c_str(),&stFileInfo); + if(intStat!=0) { //file does not exist + sprintf(msg, "Configuration: File %s does not exist.",filename.c_str()); + throw eudaq::Exception(msg); + } + // create module via IPC + char modname[32]; + sprintf(modname,"RCE%d_module_%d",rce, outlink); + if(modtype=="FEI4A"){ + printf("FEI4A: addModule (%s, %d, %d, %d, %d)\n",modname, 0, inlink, outlink, rce); + m_controller->addModule(modname, "FEI4A",id, inlink, outlink, rce, "FEI4A"); + FEI4AConfigFile fei4af; + ipc::PixelFEI4AConfig *cfg=new ipc::PixelFEI4AConfig; + fei4af.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(modname,*cfg); + delete cfg; + // assert(m_controller.writeHWregister(15,0x80)==0); //setup mux + } else if(modtype=="FEI4B"){ + printf("FEI4B: addModule (%s, %d, %d, %d, %d)\n",modname, id, inlink, outlink, rce); + m_controller->addModule(modname, "FEI4B",id, inlink, outlink, rce, "FEI4B"); + FEI4BConfigFile fei4bf; + ipc::PixelFEI4BConfig *cfg=new ipc::PixelFEI4BConfig; + fei4bf.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(modname,*cfg); + delete cfg; + }else{ + printf("FEI3: addModule (%s, %d, %d, %d, %d)\n",modname, inlink, inlink, rce, outlink); + m_controller->addModule(modname, "FEI3",id, inlink, outlink, rce, "JJ"); + TurboDaqFile turbo; + ipc::PixelModuleConfig *cfg=new ipc::PixelModuleConfig; + turbo.readModuleConfig(cfg, filename); + m_controller->downloadModuleConfig(modname,*cfg); + delete cfg; + } + } + // set up hardware trigger + unsigned serstat=0; + serstat=m_controller->writeHWregister(RceName::getRceNumber(), 3,1); //runmode 0=normal 1=tdccalib 2=eudaq + assert(serstat==0); + //m_controller.writeHWregister(3,0); //Normal mode + + // Scan configuration + std::cout<<"Deleting scan options "<<m_options<<std::endl; + delete m_options; + PixScan scn(PixScan::COSMIC_RCE, PixLib::EnumFEflavour::PM_FE_I2); + m_options=new ipc::ScanOptions; + scn.setName("TCP"); // send data over the network rather than to file + // Override l1a latency + int latency = config.Get("Latency", -1); + if(latency==-1){ + throw eudaq::Exception("Latency is not defined."); + } + scn.setLVL1Latency(latency); + m_conseq = config.Get("ConseqTriggers", -1); + if(m_conseq==(unsigned)-1){ + throw eudaq::Exception("Number of consecutive triggers is not defined."); + } + scn.setConsecutiveLvl1TrigA(0,m_conseq); + int trgdelay = config.Get("Trgdelay", -1); + if(trgdelay==-1){ + throw eudaq::Exception("Trigger delay is not defined."); + } + scn.setStrobeLVL1Delay(trgdelay); + int deadtime = config.Get("Deadtime", 0); + scn.setDeadtime(deadtime); + int cyclic = config.Get("Cyclic_Period", 40000000); + scn.setEventInterval(cyclic); + scn.setTriggerMask(4); // eudet=4 + + scn.convertScanConfig(*m_options); + //m_controller->downloadScanConfig(*m_options); + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Configured (" + config.Name() + ")"); + } catch (const std::exception & e) { + printf("Caught exception: %s\n", e.what()); + SetStatus(eudaq::Status::LVL_ERROR, "Configuration Error"); + } catch (...) { + printf("Unknown exception\n"); + SetStatus(eudaq::Status::LVL_ERROR, "Configuration Error"); + } +} + + // This gets called whenever a new run is started + // It receives the new run number as a parameter +void RceProducer::OnStartRun(unsigned param) { + m_run = param; + std::cout << "Start Run: " << m_run << std::endl; + char name[20]; + sprintf(name,"TCP_%d",m_run); + m_options->name=CORBA::string_dup(name); + + m_controller->downloadScanConfig(*m_options); + // It must send a BORE to the Data Collector + eudaq::RawDataEvent bore(eudaq::RawDataEvent::BORE(EVENT_TYPE, m_run)); + // You can set tags on the BORE that will be saved in the data file + // and can be used later to help decoding + bore.SetTag("PlaneMask", eudaq::to_string(m_PlaneMask)); + bore.SetTag("nFrames", eudaq::to_string(m_conseq)); + // Send the event to the Data Collector + SendEvent(bore); + // Enable writing events via tcp/ip + ProducerIF::setProducer(this); + //start run + omni_thread::create(startScan,(void*)m_controller); + //m_controller->startScan(); + + std::cout<<"Started scan"<<std::endl; + // At the end, set the status that will be displayed in the Run Control. + SetStatus(eudaq::Status::LVL_OK, "Running"); + } + + // This gets called whenever a run is stopped +void RceProducer::OnStopRun() { + std::cout << "Stopping Run" << std::endl; + + m_controller->stopWaitingForData(); + //wait for late events to trickle in + sleep(1); + //wait for scan to be complete + bool idle=false; + for(int i=0;i<50;i++){ + if(m_controller->getScanStatus()==0){ + std::cout<<"called getstatus"<<std::endl; + idle=true; + break; + } + usleep(100000); + } + if(idle==false)std::cout<<"Scan did not go into idle state"<<std::endl; + //disable sending events via TCP/IP + ProducerIF::setProducer(0); + // Send an EORE after all the real events have been sent + // You can also set tags on it (as with the BORE) if necessary + unsigned evnum=m_controller->getNEventsProcessed(); + SendEvent(eudaq::RawDataEvent::EORE(EVENT_TYPE, m_run, evnum)); + SetStatus(eudaq::Status::LVL_OK, "Stopped"); + } + + // This gets called when the Run Control is terminating, + // we should also exit. +void RceProducer::OnTerminate() { + std::cout << "Terminating..." << std::endl; + } + diff --git a/rce/rcecalib/server/RceProducer.hh b/rce/rcecalib/server/RceProducer.hh new file mode 100644 index 0000000000000000000000000000000000000000..69ad544e8efb51aec6d6013c44218f5371bccf2b --- /dev/null +++ b/rce/rcecalib/server/RceProducer.hh @@ -0,0 +1,29 @@ +#ifndef RCEPRODUCER_HH +#define RCEPRODUCER_HH + +#include "eudaq/Producer.hh" + +#include "rcecalib/server/IPCController.hh" + +class RceProducer : public eudaq::Producer { +public: + RceProducer(const std::string & name, const std::string & runcontrol, IPCPartition& p) + : eudaq::Producer(name, runcontrol), m_run(0), m_PlaneMask(0), m_conseq(1), m_controller(new IPCController(p)), + m_options(0){std::cout<<"Rce producer constructor "<< m_options<<std::endl;} + virtual ~RceProducer(){ + delete m_controller; + } + virtual void OnConfigure(const eudaq::Configuration & config) ; + virtual void OnStartRun(unsigned param) ; + virtual void OnStopRun() ; + virtual void OnTerminate() ; + +private: + unsigned m_run; + unsigned m_PlaneMask; + unsigned m_conseq; + IPCController* m_controller; + ipc::ScanOptions* m_options; +}; + +#endif diff --git a/rce/rcecalib/server/ScanGui.cc b/rce/rcecalib/server/ScanGui.cc new file mode 100644 index 0000000000000000000000000000000000000000..44ba489cb63f9237102c316647629562a1866cbb --- /dev/null +++ b/rce/rcecalib/server/ScanGui.cc @@ -0,0 +1,276 @@ +#include "rcecalib/server/ScanGui.hh" +#include "rcecalib/server/PixScan.hh" +#include "ScanOptions.hh" +#include <iostream> +using namespace RCE; + +ScanGui::ScanGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options): + TGVerticalFrame(p,w,h,options), m_scan(0), m_scanopt(0), m_scn(0), + m_thresholdTargetC(-1), m_targetChargeC(-1), m_targetValueC(-1){ + + m_name=new TGLabel(this,name); + AddFrame(m_name,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 10, 0)); + FontStruct_t labelfont; + labelfont = gClient->GetFontByName("-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1"); + m_name->SetTextFont(labelfont); + + TGLabel *cfg=new TGLabel(this,"Scan Type:"); + AddFrame(cfg,new TGLayoutHints(kLHintsCenterX|kLHintsTop, 2, 2, 10, 0)); + + m_scan=new TGComboBox(this,100); + AddFrame(m_scan,new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX ,2,2,5,0)); + if(!m_initialized)initScanTypes(); + m_scan->Resize(150,20); + //m_scan->Connect("Selected(Int_t)", "ScanGui", this, "selected(Int_t)"); + + m_typestring=""; + //Injection + TGHorizontalFrame *conf0 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf0,new TGLayoutHints(kLHintsExpandX )); + TGLabel *masklabel=new TGLabel(conf0,"Injection:"); + FontStruct_t maskfont= gClient->GetFontByName("-adobe-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1"); + masklabel->SetTextFont(maskfont); + conf0->AddFrame(masklabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_dig=new TGLabel(conf0,""); + conf0->AddFrame(m_dig,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + masklabel=new TGLabel(conf0,"Repetitions:"); + conf0->AddFrame(masklabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_rep=new TGLabel(conf0,""); + conf0->AddFrame(m_rep,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + + // mask + TGHorizontalFrame *conf1 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf1,new TGLayoutHints(kLHintsExpandX )); + masklabel=new TGLabel(conf1,"Mask:"); + masklabel->SetTextFont(maskfont); + conf1->AddFrame(masklabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_maskmode=new TGLabel(conf1,""); + conf1->AddFrame(m_maskmode,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + TGLabel *mslabel=new TGLabel(conf1,"Number of Steps:"); + conf1->AddFrame(mslabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_maskstages=new TGLabel(conf1,""); + conf1->AddFrame(m_maskstages,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + //Loops + TGHorizontalFrame *loopframe[3]; + char loopstr[128]; + for(int i=0;i<3;i++){ + loopframe[i] = new TGHorizontalFrame(this, 2,2 ); + AddFrame(loopframe[i],new TGLayoutHints(kLHintsExpandX )); + sprintf(loopstr, "Loop %d:",i); + m_active[i]=new TGCheckButton(loopframe[i],loopstr); + m_active[i]->SetFont(maskfont); + m_active[i]->SetOn(0); + m_active[i]->Connect("Toggled(Bool_t)", "ScanGui", this, "dummyAct(Bool_t)"); + loopframe[i]->AddFrame(m_active[i],new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_par[i]=new TGLabel(loopframe[i],""); + loopframe[i]->AddFrame(m_par[i],new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + TGLabel *looplabel=new TGLabel(loopframe[i],"N:"); + loopframe[i]->AddFrame(looplabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_steps[i]=new TGLabel(loopframe[i],""); + loopframe[i]->AddFrame(m_steps[i],new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + looplabel=new TGLabel(loopframe[i],"Lo:"); + loopframe[i]->AddFrame(looplabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_low[i]=new TGLabel(loopframe[i],""); + loopframe[i]->AddFrame(m_low[i],new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + looplabel=new TGLabel(loopframe[i],"Hi:"); + loopframe[i]->AddFrame(looplabel,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 10, 2, 2, 0)); + m_high[i]=new TGLabel(loopframe[i],""); + loopframe[i]->AddFrame(m_high[i],new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 2, 0)); + m_rce[i]=new TGCheckButton(loopframe[i],"RCE"); + m_rce[i]->SetOn(false); + m_rceb[i]=false; + loopframe[i]->AddFrame(m_rce[i],new TGLayoutHints(kLHintsRight|kLHintsCenterY, 10, 2, 2, 0)); + m_rce[i]->Connect("Toggled(Bool_t)", "ScanGui", this, "dummy(Bool_t)"); + } + TGHorizontalFrame *conf2 = new TGHorizontalFrame(this, 2,2 ); + AddFrame(conf2,new TGLayoutHints(kLHintsExpandX )); + TGLabel *linklabeltune=new TGLabel(conf2,"Tuning Parameters:"); + linklabeltune->SetTextFont(maskfont); + conf2->AddFrame(linklabeltune,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + TGLabel *linklabel2=new TGLabel(conf2,"Target threshold:"); + conf2->AddFrame(linklabel2,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_thresholdTarget=new TGNumberEntry(conf2, 0, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 20000); + conf2->AddFrame(m_thresholdTarget,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 0, 5)); + TGLabel *linklabel3=new TGLabel(conf2," Target charge:"); + conf2->AddFrame(linklabel3,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_targetCharge=new TGNumberEntry(conf2, 0, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 50000); + conf2->AddFrame(m_targetCharge,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 0, 5)); + TGLabel *linklabel4=new TGLabel(conf2," ToT target value:"); + conf2->AddFrame(linklabel4,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 2, 2, 0, 0)); + m_targetValue=new TGNumberEntry(conf2, 0, 3, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative, TGNumberFormat::kNELLimitMinMax, 0, 127); + conf2->AddFrame(m_targetValue,new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0, 2, 0, 5)); + +} + +void ScanGui::dummy(bool on){ + // disable clicking + for(int i=0;i<3;i++)m_rce[i]->SetOn(m_rceb[i]); +} + +void ScanGui::dummyAct(bool on){ + // disable clicking + if(m_scn) + for(int i=0;i<3;i++)m_active[i]->SetOn(m_scn->getLoopActive(i)); + else + for(int i=0;i<3;i++)m_active[i]->SetOn(false); +} + +ScanGui::~ScanGui(){ + Cleanup(); +} + +void ScanGui::updateText(TGLabel* label, const char* newtext){ + //unsigned len=strlen(label->GetText()->GetString()); + label->SetText(newtext); + //if (strlen(newtext)>len)Layout(); + Layout(); +} + +void ScanGui::enableControls(bool on){ + m_scan->SetEnabled(on); + m_targetCharge->SetState(on); + m_targetValue->SetState(on); + m_thresholdTarget->SetState(on); +} + + +void ScanGui::print(std::ostream &os){ + getScanConfig(); + if(m_scanopt!=0){ + m_scn->dump(os, *m_scanopt); + } +} + +RCE::PixScan* ScanGui::getPixScan(){ + return m_scn; +} + + +ipc::ScanOptions *ScanGui::getScanConfig(){ + return m_scanopt; +} + +void ScanGui::initScanTypes(){ + PixLib::EnumScanType scantypes; + m_scantypes[PixScan::DIGITAL_TEST]=scantypes.lookup(PixScan::DIGITAL_TEST); + m_scantypes[PixScan::ANALOG_TEST]=scantypes.lookup(PixScan::ANALOG_TEST); + m_scantypes[PixScan::THRESHOLD_SCAN]=scantypes.lookup(PixScan::THRESHOLD_SCAN); + m_scantypes[PixScan::CROSSTALK_SCAN]=scantypes.lookup(PixScan::CROSSTALK_SCAN); + m_scantypes[PixScan::T0_SCAN]=scantypes.lookup(PixScan::T0_SCAN); + m_scantypes[PixScan::TIMEWALK_MEASURE]=scantypes.lookup(PixScan::TIMEWALK_MEASURE); + m_scantypes[PixScan::INTIME_THRESH_SCAN]=scantypes.lookup(PixScan::INTIME_THRESH_SCAN); + m_scantypes[PixScan::DELAY_SCAN]=scantypes.lookup(PixScan::DELAY_SCAN); + m_scantypes[PixScan::MEASUREMENT_SCAN]=scantypes.lookup(PixScan::MEASUREMENT_SCAN); + m_scantypes[PixScan::VTHIN_SCAN]=scantypes.lookup(PixScan::VTHIN_SCAN); + m_scantypes[PixScan::SELFTRIGGER]=scantypes.lookup(PixScan::SELFTRIGGER); + m_scantypes[PixScan::EXTTRIGGER]=scantypes.lookup(PixScan::EXTTRIGGER); + m_scantypes[PixScan::MULTISHOT]=scantypes.lookup(PixScan::MULTISHOT); + m_scantypes[PixScan::STUCKPIXELS]=scantypes.lookup(PixScan::STUCKPIXELS); + m_scantypes[PixScan::IF_TUNE]=scantypes.lookup(PixScan::IF_TUNE); + m_scantypes[PixScan::FDAC_TUNE]=scantypes.lookup(PixScan::FDAC_TUNE); + m_scantypes[PixScan::NOISESCAN]=scantypes.lookup(PixScan::NOISESCAN); + m_scantypes[PixScan::GDAC_TUNE]=scantypes.lookup(PixScan::GDAC_TUNE); + m_scantypes[PixScan::TDAC_TUNE]=scantypes.lookup(PixScan::TDAC_TUNE); + m_scantypes[PixScan::TOT_TEST]=scantypes.lookup(PixScan::TOT_TEST); + m_scantypes[PixScan::TOT_CALIB]=scantypes.lookup(PixScan::TOT_CALIB); + m_scantypes[PixScan::CROSSTALK_SCAN]=scantypes.lookup(PixScan::CROSSTALK_SCAN); + m_scantypes[PixScan::TWOTRIGGER_THRESHOLD]=scantypes.lookup(PixScan::TWOTRIGGER_THRESHOLD); + m_scantypes[PixScan::TWOTRIGGER_NOISE]=scantypes.lookup(PixScan::TWOTRIGGER_NOISE); + m_scantypes[PixScan::DIFFUSION]=scantypes.lookup(PixScan::DIFFUSION); + m_scantypes[PixScan::OFFSET_SCAN]=scantypes.lookup(PixScan::OFFSET_SCAN); + m_scantypes[PixScan::TDAC_TUNE_ITERATED]=scantypes.lookup(PixScan::TDAC_TUNE_ITERATED); + m_scantypes[PixScan::MODULE_CROSSTALK]=scantypes.lookup(PixScan::MODULE_CROSSTALK); + m_scantypes[PixScan::REGISTER_TEST]=scantypes.lookup(PixScan::REGISTER_TEST); + m_scantypes[PixScan::GDAC_SCAN]=scantypes.lookup(PixScan::GDAC_SCAN); + m_scantypes[PixScan::GDAC_RETUNE]=scantypes.lookup(PixScan::GDAC_RETUNE); + m_scantypes[PixScan::TEMPERATURE_SCAN]=scantypes.lookup(PixScan::TEMPERATURE_SCAN); + m_scantypes[PixScan::MONLEAK_SCAN]=scantypes.lookup(PixScan::MONLEAK_SCAN); + m_scantypes[PixScan::SERIAL_NUMBER_SCAN]=scantypes.lookup(PixScan::SERIAL_NUMBER_SCAN); + m_scantypes[PixScan::TDAC_FAST_TUNE]=scantypes.lookup(PixScan::TDAC_FAST_TUNE); + m_scantypes[PixScan::TDAC_FAST_RETUNE]=scantypes.lookup(PixScan::TDAC_FAST_RETUNE); + m_scantypes[PixScan::GDAC_FAST_TUNE]=scantypes.lookup(PixScan::GDAC_FAST_TUNE); + m_scantypes[PixScan::GDAC_FAST_RETUNE]=scantypes.lookup(PixScan::GDAC_FAST_RETUNE); + m_scantypes[PixScan::EXT_REGISTER_VERIFICATION]=scantypes.lookup(PixScan::EXT_REGISTER_VERIFICATION); + m_scantypes[PixScan::GDAC_COARSE_FAST_TUNE]=scantypes.lookup(PixScan::GDAC_COARSE_FAST_TUNE); + m_scantypes[PixScan::NOISESCAN_SELFTRIGGER]=scantypes.lookup(PixScan::NOISESCAN_SELFTRIGGER); + m_scantypes[PixScan::DIGITALTEST_SELFTRIGGER]=scantypes.lookup(PixScan::DIGITALTEST_SELFTRIGGER); + + for(std::map<int, std::string>::iterator it=m_scantypes.begin();it!=m_scantypes.end();it++){ + m_scan->AddEntry((*it).second.c_str(), (*it).first); + } + m_initialized=true; +} + + +void ScanGui::setupScan(std::string flavor, int runnum){ + PixLib::EnumFEflavour::FEflavour fl; + if(flavor=="FEI3")fl=PixLib::EnumFEflavour::PM_FE_I2; + else if (flavor=="FEI4A")fl=PixLib::EnumFEflavour::PM_FE_I4A; + else if (flavor=="FEI4B")fl=PixLib::EnumFEflavour::PM_FE_I4B; + else return; + + delete m_scn; + + m_scn=new PixScan((PixScan::ScanType)m_scan->GetSelected(), fl); + // Set targets from GUI unless they are 0 in the GUI + if(m_targetCharge->GetIntNumber()!=0) + m_scn->setTotTargetCharge(m_targetCharge->GetIntNumber()); + else + m_targetCharge->SetIntNumber(m_scn->getTotTargetCharge()); + + if(m_thresholdTarget->GetIntNumber()!=0) + m_scn->setThresholdTargetValue(m_thresholdTarget->GetIntNumber()); + else + m_thresholdTarget->SetIntNumber(m_scn->getThresholdTargetValue()); + + if(m_targetValue->GetIntNumber()!=0) + m_scn->setTotTargetValue(m_targetValue->GetIntNumber()); + else + m_targetValue->SetIntNumber(m_scn->getTotTargetValue()); + + m_typestring=m_scantypes[m_scan->GetSelected()]; + m_scn->setRunNumber(runnum); + delete m_scanopt; + m_scanopt=new ipc::ScanOptions; + m_scn->convertScanConfig(*m_scanopt); + + char nms[128]; + if(m_scn->getDigitalInjection())updateText(m_dig, "Digital"); + else updateText(m_dig, "Analog"); + sprintf(nms, "%d", m_scn->getRepetitions()); + updateText(m_rep, nms); + updateText(m_maskmode, m_scanopt->maskStages); + sprintf(nms,"%d",m_scanopt->nMaskStages); + updateText(m_maskstages, nms); + m_thresholdTargetC=m_scn->getThresholdTargetValue(); + m_thresholdTarget->SetIntNumber(m_thresholdTargetC); + m_targetChargeC=m_scn->getTotTargetCharge(); + m_targetCharge->SetIntNumber(m_targetChargeC); + m_targetValueC=m_scn->getTotTargetValue(); + m_targetValue->SetIntNumber(m_targetValueC); + PixLib::EnumScanParam paramTypes; + for (int j=0;j<3;j++){ + updateText(m_par[j], paramTypes.lookup(m_scn->getLoopParam(j)).c_str()); + std::vector<float> vals=m_scn->getLoopVarValues(j); + sprintf(nms,"%d", vals.size()); + updateText(m_steps[j], nms); + float low=0; + float high=0; + if(vals.size()>0){ + low=vals.front(); + high=vals.back(); + } + sprintf(nms,"%d", (int)low); + updateText(m_low[j], nms); + sprintf(nms,"%d", (int)high); + updateText(m_high[j], nms); + if(m_scn->getDspProcessing(j))m_rceb[j]=true; + else m_rceb[j]=false; + m_rce[j]->SetOn(m_rceb[j]); + m_active[j]->SetOn(m_scn->getLoopActive(j)); + } + +} + +bool ScanGui::m_initialized=false; +std::map<int, std::string> ScanGui::m_scantypes; diff --git a/rce/rcecalib/server/ScanGui.hh b/rce/rcecalib/server/ScanGui.hh new file mode 100644 index 0000000000000000000000000000000000000000..9abef311a7e31d2a4f6743e2368085487292738f --- /dev/null +++ b/rce/rcecalib/server/ScanGui.hh @@ -0,0 +1,57 @@ +#ifndef SCANGUI_HH +#define SCANGUI_HH + +#include <TGButton.h> +#include <TGTextEntry.h> +#include <TGNumberEntry.h> +#include <TGLabel.h> +#include <TGComboBox.h> +#include <fstream> +#include <string> +#include <map> + + +namespace ipc{ + class ScanOptions; +} +namespace RCE { +class PixScan; +} + +class ScanGui: public TGVerticalFrame{ +public: + ScanGui(const char* name, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options); + virtual ~ScanGui(); + void print(std::ostream &os); + void enableControls(bool on); + std::string getTypeString(){return m_typestring;} + ipc::ScanOptions* getScanConfig(); + RCE::PixScan* getPixScan(); + //void selected(int i); + void dummy(bool); + void dummyAct(bool); + void setupScan(std::string flavor, int runnum); + static std::map<int, std::string> getScanTypes() {return m_scantypes;} +private: + void initScanTypes(); + TGLabel *m_name; + TGLabel *m_maskmode, *m_maskstages; + TGLabel *m_dig, *m_rep; + TGComboBox *m_scan; + TGCheckButton *m_active[3]; + TGCheckButton *m_rce[3]; + TGLabel *m_par[3], *m_steps[3], *m_low[3], *m_high[3]; + TGNumberEntry *m_thresholdTarget, *m_targetCharge, *m_targetValue; + bool m_rceb[3]; + ipc::ScanOptions *m_scanopt; + RCE::PixScan *m_scn; + void updateText(TGLabel* label, const char* newtext); + static std::map<int, std::string> m_scantypes; + static bool m_initialized; + std::string m_typestring; + int m_thresholdTargetC, m_targetChargeC, m_targetValueC; + ClassDef(ScanGui,0); +}; + +#endif + diff --git a/rce/rcecalib/server/ScanLog.cc b/rce/rcecalib/server/ScanLog.cc new file mode 100644 index 0000000000000000000000000000000000000000..9219b7a67e46bf26eb0c91a7da12ebda4aa36e90 --- /dev/null +++ b/rce/rcecalib/server/ScanLog.cc @@ -0,0 +1,316 @@ +#include "rcecalib/server/ScanLog.hh" +#include <stdlib.h> +#include <sys/stat.h> +#include <iostream> +#include <fstream> +#include <sstream> +#include <boost/algorithm/string.hpp> +#include <ctime> +#include <TROOT.h> +#ifdef SQLDB +#include <mysql.h> +#warning Including SQL database interface +#else +#warning Not including SQL database interface +#endif +//#define SQLDEBUG 1 +namespace{ + const char* hostname="atlpix01.cern.ch"; + const int port=443; +} + +ScanLog::ScanLog(){ + const char *ou_name=getenv("OLDUSER"); + const char *u_name=getenv("USER"); + m_user="Unknown"; + if(ou_name!=NULL) m_user=ou_name; + else if(u_name!=NULL)m_user=u_name; +} + + +void ScanLog::logScan(LogData& logdata){ + std::string logdir=std::string(getenv("HOME"))+"/scanlog"; + struct stat stFileInfo; + int intStat; + intStat = stat(logdir.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Creating directory for scan logs"<<std::endl; + mkdir(logdir.c_str(), 0777); + } + std::string runnrfilename=logdir+"/currentRunNumber.txt"; + ofstream runnrfile(runnrfilename.c_str()); + runnrfile<<m_runnumber<<std::endl; + runnrfile.close(); + m_infofilename=logdir+Form("/calibSetup_%06d.txt",m_runnumber); + char command[512]; + sprintf(command, "cd ~/daq; svn info | grep URL>%s;cd -", m_infofilename.c_str()); + system(command); + fstream infofile; + infofile.open(m_infofilename.c_str(),fstream::out | fstream::app); + infofile<<"Comment: "<<logdata.comment<<std::endl; + infofile<<"Run number: "<<m_runnumber<<std::endl; + infofile<<"User: "<<m_user<<std::endl; + infofile<<"Host: "; + const char *host_name=getenv("HOST"); + if(host_name!=0)infofile<<host_name<<std::endl; + else infofile<<"Unknown"<<std::endl; + infofile<<"Scan Type: "<<m_scanname<<std::endl; + infofile<<"Debugging Run: "<<m_debugging<<std::endl; + infofile<<"Data exported: "<<logdata.exported<<std::endl; + infofile<<"Data saved and analyzed: "<<logdata.saved<<std::endl; + infofile<<"Data Path: "; + if(logdata.saved==true)infofile<<logdata.datapath<<std::endl; + else infofile<<std::endl; + for (unsigned int i=0;i<logdata.configs.size();i++) + infofile<<logdata.configs[i]<<std::endl; + infofile<<"Started: " << formattedCurrentTime() << std::endl; + infofile.close(); + #ifdef SQLDB + startLogToDB(); + #endif + #ifdef ELOG + #warning ELOG included + if(m_debugging==false)writeToElog(); + #else + #warning ELOG not included + #endif +} +const char* ScanLog::formattedCurrentTime() +{ + time_t now = time(0); + tm *ltm = localtime(&now); + char formattedTime [128]; + sprintf(formattedTime, "%04d-%02d-%02d %02d:%02d:%02d", (1900+ltm->tm_year), (1+ltm->tm_mon), (ltm->tm_mday), (ltm->tm_hour), (ltm->tm_min), (ltm->tm_sec)); + std::string toReturn(formattedTime); + return toReturn.c_str(); +} +void ScanLog::finishLogFile(std::string runstatus, std::string lstatus){ + fstream infofile; + infofile.open(m_infofilename.c_str(),fstream::out | fstream::app); + infofile<<"Finished: " << formattedCurrentTime() << std::endl; + infofile<<"Status: "<<runstatus<<std::endl; + #ifdef ELOG + if(m_debugging==false)updateElog(lstatus); + #endif + #ifdef SQLDB + finishLogToDB(); + #endif +} + +void ScanLog::writeToElog(){ + char elogcmd[1024]; + char elogfile[512]; + sprintf(elogfile,"/tmp/elog_%d.txt", m_runnumber); + sprintf(elogcmd,"elog -h %s -s -x -p %d -d elog -l \"IBL Stave Test\" -u calibGUI rce -a Author=%s -a Title=\"Scan %d %s\" -a Category=\"Datataking\" -a \"Type of Entry\"=\"Scan Log\" -a Status=\"In progress\" -a \"People present\"=\"%s\" -a Automated=1 -m %s | tee %s &", + hostname, port, m_author.c_str(), m_runnumber, m_scanname.c_str(), + m_user, m_infofilename.c_str(), elogfile); + system(elogcmd); +} + +void ScanLog::updateElog(std::string lstatus){ + struct stat stFileInfo; + int intStat; + char elogfile[512]; + sprintf(elogfile,"/tmp/elog_%d.txt", m_runnumber); + intStat = stat(elogfile,&stFileInfo); + if(intStat!=0){ + std::cout<<"Logbook update failed"<<std::endl; + return; + } + int n=30; + ifstream reply(elogfile); + char rep[512]; + do{ + reply.getline(rep,512); + if(!reply.eof())break; + std::cout<<"Waiting for logbook"<<std::endl; + sleep(1); + reply.close(); + reply.open(elogfile); + }while(n-->0); + if(n==0){ + std::cout<<"ELOG entry failed"<<std::endl; + }else{ + int id; + int stat=sscanf (rep,"Message successfully transmitted, ID=%d",&id); + if(stat==EOF)std::cout<<"Bad logbook entry"<<std::endl; + else{ + char elogcmd[1024]; + sprintf(elogcmd,"elog -h %s -s -x -p %d -d elog -l \"IBL Stave Test\" -u calibGUI rce -a Author=%s -a Title=\"Scan %d %s\" -a Category=\"Datataking\" -a \"Type of Entry\"=\"Scan Log\" -a Status=\"%s\" -a \"People present\"=\"%s\" -a Automated=1 -m %s -e %d &", + hostname, port, m_author.c_str(), m_runnumber, m_scanname.c_str(), + lstatus.c_str(), m_user, m_infofilename.c_str(),id); + system(elogcmd); + remove(elogfile); + } + } +} +void ScanLog::startLogToDB() +{ + #ifdef SQLDB + ifstream log; + log.open(m_infofilename.c_str()); + std::string tmp, url, user, host, scanType, dataPath, startTime, endTime, comment, status; + int runNum; + bool debuggingRun, dataExported, dataSaved; + //std::vector <int> FEIds; + std::vector <std::string> modIds, cfgs, FEIds; + std::getline(log,tmp, ':'); + std::getline(log, url); + boost::algorithm::trim(url); + std::getline(log,tmp, ':'); + std::getline(log, comment); + boost::algorithm::trim(comment); + std::getline(log,tmp, ':'); + log >> runNum; + std::getline(log,tmp, ':'); + std::getline(log, user); + boost::algorithm::trim(user); + std::getline(log,tmp, ':'); + std::getline(log, host); + boost::algorithm::trim(host); + std::getline(log,tmp, ':'); + std::getline(log, scanType); + boost::algorithm::trim(scanType); + std::getline(log,tmp, ':'); + log >> debuggingRun; + std::getline(log,tmp, ':'); + log >> dataExported; + std::getline(log,tmp, ':'); + log >> dataSaved; + std::getline(log,tmp, ':'); + std::getline(log, dataPath); + boost::algorithm::trim(dataPath); + std::getline(log, tmp, ':'); + boost::algorithm::trim(tmp); + while (tmp.compare("Module") == 0) + { + std::string modId, cfgPath, FEId; + log >> modId; + boost::algorithm::trim(modId); + std::getline(log,tmp, ':'); + log >> FEId; + boost::algorithm::trim(FEId); + std::getline(log,tmp, ':'); + std::getline(log,cfgPath); + boost::algorithm::trim(cfgPath); + std::getline(log,tmp, ':'); + modIds.push_back(modId); + FEIds.push_back(FEId); + cfgs.push_back(cfgPath); + } + std::getline(log,startTime); + boost::algorithm::trim(startTime); + std::getline(log,tmp, ':');//times require special parsing bc whitespace + log.close(); + //Now insert into SQL DB + + MYSQL *conn; + conn = mysql_init(NULL); + char queryStr [1056]; + sprintf(queryStr, "UPDATE CalibRunLog SET URL='%s', User='%s', Host='%s', ScanType='%s', Debugging='%d', DataExported=%d, DataSaved=%d, DataPath='%s', StartTime='%s' WHERE RunNum=%d;", url.c_str(), user.c_str(), host.c_str(), scanType.c_str(), debuggingRun, dataExported, dataSaved, dataPath.c_str(), startTime.c_str(), runNum); + std::string dbName="RCECalibRuns"; + #ifdef SQLDEBUG + dbName="RCECalibRunsDev"; + #endif + if(mysql_real_connect(conn, "pixiblsr1daq1", "DBWriter", "W#1ter", dbName.c_str(), 0, NULL, 0)==NULL) + + { + std::cout << "SQL connection to " << dbName << " failed!! Nothing will be inserted!" <<std::endl; + return; + } + mysql_query(conn, queryStr); + //Now insert Module info + + for (unsigned int i=0; i < modIds.size(); i++) + { + sprintf(queryStr, "INSERT INTO ModuleLog (RunNum, ModuleId, FEId, CfgName) VALUES (%d, '%s', '%s', '%s');", runNum, modIds.at(i).c_str(), FEIds.at(i).c_str(), cfgs.at(i).c_str()); + mysql_query(conn, queryStr); + } + mysql_close(conn); +#endif +} +void ScanLog::finishLogToDB() +{ +#ifdef SQLDB + ifstream log; + log.open(m_infofilename.c_str()); + std::string tmp, url, user, host, scanType, dataPath, startTime, endTime, comment, status; + int runNum; + bool debuggingRun, dataExported, dataSaved; + //std::vector <int> FEIds;//Read in everything even though it's junk + std::vector <std::string> modIds, cfgs, FEIds; + std::getline(log,tmp, ':'); + std::getline(log, url); + boost::algorithm::trim(url); + std::getline(log,tmp, ':'); + std::getline(log, comment); + boost::algorithm::trim(comment); + std::getline(log,tmp, ':'); + log >> runNum; + std::getline(log,tmp, ':'); + std::getline(log, user); + boost::algorithm::trim(user); + std::getline(log,tmp, ':'); + std::getline(log, host); + boost::algorithm::trim(host); + std::getline(log,tmp, ':'); + std::getline(log, scanType); + boost::algorithm::trim(scanType); + std::getline(log,tmp, ':'); + log >> debuggingRun; + std::getline(log,tmp, ':'); + log >> dataExported; + std::getline(log,tmp, ':'); + log >> dataSaved; + std::getline(log,tmp, ':'); + std::getline(log, dataPath); + boost::algorithm::trim(dataPath); + std::getline(log, tmp, ':'); + boost::algorithm::trim(tmp); + while (tmp.compare("Module") == 0) + { + std::string modId, cfgPath, FEId; + log >> modId; + boost::algorithm::trim(modId); + std::getline(log,tmp, ':'); + log >> FEId; + boost::algorithm::trim(FEId); + std::getline(log,tmp, ':'); + std::getline(log,cfgPath); + boost::algorithm::trim(cfgPath); + std::getline(log,tmp, ':'); + modIds.push_back(modId); + FEIds.push_back(FEId); + cfgs.push_back(cfgPath); + } + std::getline(log,startTime); + boost::algorithm::trim(startTime); + std::getline(log,tmp, ':');//times require special parsing bc whitespace + std::getline(log,endTime); + boost::algorithm::trim(endTime); + std::getline(log,tmp, ':'); + std::getline(log, status); + boost::algorithm::trim(status); + + //Now insert into SQL DB + + MYSQL *conn; + conn = mysql_init(NULL); + char queryStr [1056]; + sprintf(queryStr, "UPDATE CalibRunLog SET EndTime='%s', Comment='%s', Status='%s' WHERE RunNum=%d", endTime.c_str(), comment.c_str(), status.c_str(), runNum); + std::string dbName="RCECalibRuns"; + #ifdef SQLDEBUG + dbName="RCECalibRunsDev"; + #endif + if(mysql_real_connect(conn, "pixiblsr1daq1", "DBWriter", "W#1ter", dbName.c_str(), 0, NULL, 0)==NULL) + + { + std::cout << "SQL connection to " << dbName << " failed!! Nothing will be inserted!" <<std::endl; + return; + } + mysql_query(conn, queryStr); + mysql_close(conn); +#endif + } + + diff --git a/rce/rcecalib/server/ScanLog.hh b/rce/rcecalib/server/ScanLog.hh new file mode 100644 index 0000000000000000000000000000000000000000..7f45871e125c72530407a3c60b41aa70adf86e9c --- /dev/null +++ b/rce/rcecalib/server/ScanLog.hh @@ -0,0 +1,51 @@ +#ifndef SCANLOG_HH +#define SCANLOG_HH + +#include <string> +#include <vector> + + +class LogData{ +public: + std::string comment; + bool exported; + bool saved; + std::string datapath; + std::vector<std::string> configs; +}; + +class ScanLog{ +public: + ScanLog(); + ~ScanLog(){} + void logScan(LogData&); + void finishLogFile(std::string runstatus, std::string lstatus); + void writeToElog(); + void updateElog(std::string lstatus); + void finishLogToDB(); + void startLogToDB(); + void setFile(std::string f){m_infofilename=f;} + void logOldFile(); + void setAuthor(const char* name){ + m_author=name; + } + void setScanName(const char* name){ + m_scanname=name; + } + void setRunNumber(int runnumber){ + m_runnumber=runnumber; + } + void setDebugging(bool db){ + m_debugging=db; + } +private: + std::string m_infofilename; + const char* m_user; + std::string m_author; + std::string m_scanname; + int m_runnumber; + bool m_debugging; + const char* formattedCurrentTime(); +}; + +#endif diff --git a/rce/rcecalib/server/StandardStream.o b/rce/rcecalib/server/StandardStream.o new file mode 100644 index 0000000000000000000000000000000000000000..d91a7f65ea6eb27d9c739428f9b331b36f0ab949 Binary files /dev/null and b/rce/rcecalib/server/StandardStream.o differ diff --git a/rce/rcecalib/server/ThrottleStream.o b/rce/rcecalib/server/ThrottleStream.o new file mode 100644 index 0000000000000000000000000000000000000000..1b05701bf348a405998e21b0b5fde67df0f9dbe6 Binary files /dev/null and b/rce/rcecalib/server/ThrottleStream.o differ diff --git a/rce/rcecalib/server/TurboDaqFile.cc b/rce/rcecalib/server/TurboDaqFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..20bdc554ddd78dba31ad4665ffa59343d5a15a2b --- /dev/null +++ b/rce/rcecalib/server/TurboDaqFile.cc @@ -0,0 +1,914 @@ +#include "TurboDaqFile.hh" +#include <sstream> +#include <string> +#include <vector> +#include <iostream> +#include <typeinfo> +#include <fstream> +#include "PixelModuleConfig.hh" +#include "rcecalib/util/exceptions.hh" +#include <sys/stat.h> +typedef unsigned int uint; + +const int numberofcolumns = 18; // number of columns read in the readoutenable, pream, strobe and hitbus config file +const int numberofrows = 160; // number of rows read in the tdacs and fdacs config file +const int nofchip = 16; // number of chips per module + +void TurboDaqFile::dump(const ipc::PixelModuleConfig &config) +{ + std::cout<<"config.maskEnableFEConfig "<<config.maskEnableFEConfig<<std::endl; + std::cout<<"config.maskEnableFEScan "<<config.maskEnableFEScan<<std::endl; + std::cout<<"config.maskEnableFEDacs "<<config.maskEnableFEDacs<<std::endl; + std::cout<<"config.feFlavour "<<(unsigned)config.feFlavour<<std::endl; + std::cout<<"config.mccFlavour "<<(unsigned)config.mccFlavour<<std::endl; + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + std::cout<<"Chip "<<i<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEIndex "<<(unsigned) config.FEConfig[i].FEIndex<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.latency "<<(unsigned) config.FEConfig[i].FEGlobal.latency<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIVDD2 "<<(unsigned) config.FEConfig[i].FEGlobal.dacIVDD2<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIP2 "<<(unsigned) config.FEConfig[i].FEGlobal.dacIP2<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacID "<<(unsigned) config.FEConfig[i].FEGlobal.dacID<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIP "<<(unsigned) config.FEConfig[i].FEGlobal.dacIP<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacITRIMTH "<<(unsigned) config.FEConfig[i].FEGlobal.dacITRIMTH<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIF "<<(unsigned)config.FEConfig[i].FEGlobal.dacIF <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacITH1 "<<(unsigned) config.FEConfig[i].FEGlobal.dacITH1<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacITH2 "<<(unsigned)config.FEConfig[i].FEGlobal.dacITH2 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIL "<<(unsigned) config.FEConfig[i].FEGlobal.dacIL<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacIL2 "<<(unsigned) config.FEConfig[i].FEGlobal.dacIL2<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacITRIMIF "<<(unsigned) config.FEConfig[i].FEGlobal.dacITRIMIF<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacSpare "<<(unsigned) config.FEConfig[i].FEGlobal.dacSpare<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.threshTOTMinimum "<<(unsigned) config.FEConfig[i].FEGlobal.threshTOTMinimum<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.threshTOTDouble "<<(unsigned) config.FEConfig[i].FEGlobal.threshTOTDouble<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.hitbusScaler "<<(unsigned) config.FEConfig[i].FEGlobal.hitbusScaler<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.capMeasure "<<(unsigned) config.FEConfig[i].FEGlobal.capMeasure<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.gdac "<<(unsigned)config.FEConfig[i].FEGlobal.gdac <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.selfWidth "<<(unsigned) config.FEConfig[i].FEGlobal.selfWidth<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.selfLatency "<<(unsigned)config.FEConfig[i].FEGlobal.selfLatency <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.muxTestPixel "<<(unsigned) config.FEConfig[i].FEGlobal.muxTestPixel<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.aregTrim "<<(unsigned) config.FEConfig[i].FEGlobal.aregTrim<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.aregMeas "<<(unsigned)config.FEConfig[i].FEGlobal.aregMeas <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dregTrim "<<(unsigned) config.FEConfig[i].FEGlobal.dregTrim<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dregMeas "<<(unsigned)config.FEConfig[i].FEGlobal.dregMeas <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.parity "<<(unsigned)config.FEConfig[i].FEGlobal.parity <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacMonLeakADC "<<(unsigned) config.FEConfig[i].FEGlobal.dacMonLeakADC<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.dacVCAL "<<(unsigned) config.FEConfig[i].FEGlobal.dacVCAL<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.widthSelfTrigger "<<(unsigned) config.FEConfig[i].FEGlobal.widthSelfTrigger<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.muxDO "<<(unsigned) config.FEConfig[i].FEGlobal.muxDO<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.muxMonHit "<<(unsigned)config.FEConfig[i].FEGlobal.muxMonHit <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.muxEOC "<<(unsigned) config.FEConfig[i].FEGlobal.muxEOC<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.frequencyCEU "<<(unsigned) config.FEConfig[i].FEGlobal.frequencyCEU<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.modeTOTThresh "<<(unsigned) config.FEConfig[i].FEGlobal.modeTOTThresh<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableTimestamp "<<(unsigned) config.FEConfig[i].FEGlobal.enableTimestamp<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableSelfTrigger "<<(unsigned) config.FEConfig[i].FEGlobal.enableSelfTrigger<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableHitParity "<<(unsigned) config.FEConfig[i].FEGlobal.enableHitParity<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monMonLeakADC "<<(unsigned)config.FEConfig[i].FEGlobal.monMonLeakADC <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monADCRef "<<(unsigned)config.FEConfig[i].FEGlobal.monADCRef <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableMonLeak "<<(unsigned)config.FEConfig[i].FEGlobal.enableMonLeak <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.statusMonLeak "<<(unsigned)config.FEConfig[i].FEGlobal.statusMonLeak <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCapTest "<<(unsigned) config.FEConfig[i].FEGlobal.enableCapTest<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableBuffer "<<(unsigned)config.FEConfig[i].FEGlobal.enableBuffer <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableVcalMeasure "<<(unsigned) config.FEConfig[i].FEGlobal.enableVcalMeasure<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableLeakMeasure "<<(unsigned) config.FEConfig[i].FEGlobal.enableLeakMeasure<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableBufferBoost "<<(unsigned)config.FEConfig[i].FEGlobal.enableBufferBoost <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP8 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP8 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIVDD2 "<<(unsigned) config.FEConfig[i].FEGlobal.monIVDD2<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monID "<<(unsigned)config.FEConfig[i].FEGlobal.monID <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP7 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP7 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIP2 "<<(unsigned)config.FEConfig[i].FEGlobal.monIP2 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIP "<<(unsigned) config.FEConfig[i].FEGlobal.monIP<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP6 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP6 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monITRIMTH "<<(unsigned)config.FEConfig[i].FEGlobal.monITRIMTH <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIF "<<(unsigned) config.FEConfig[i].FEGlobal.monIF<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP5 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP5 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monITRIMIF "<<(unsigned) config.FEConfig[i].FEGlobal.monITRIMIF<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monVCAL "<<(unsigned)config.FEConfig[i].FEGlobal.monVCAL <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP4 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP4 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCinjHigh "<<(unsigned)config.FEConfig[i].FEGlobal.enableCinjHigh <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableExternal "<<(unsigned)config.FEConfig[i].FEGlobal.enableExternal <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableTestAnalogRef "<<(unsigned) config.FEConfig[i].FEGlobal.enableTestAnalogRef<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableDigital "<<(unsigned)config.FEConfig[i].FEGlobal.enableDigital <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP3 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP3 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monITH1 "<<(unsigned) config.FEConfig[i].FEGlobal.monITH1<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monITH2 "<<(unsigned) config.FEConfig[i].FEGlobal.monITH2<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP2 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP2 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIL "<<(unsigned) config.FEConfig[i].FEGlobal.monIL<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monIL2 "<<(unsigned)config.FEConfig[i].FEGlobal.monIL2 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP1 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP1 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableCP0 "<<(unsigned)config.FEConfig[i].FEGlobal.enableCP0 <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableHitbus "<<(unsigned)config.FEConfig[i].FEGlobal.enableHitbus <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.monSpare "<<(unsigned)config.FEConfig[i].FEGlobal.monSpare <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableAregMeas "<<(unsigned)config.FEConfig[i].FEGlobal.enableAregMeas <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableAreg "<<(unsigned)config.FEConfig[i].FEGlobal.enableAreg <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableLvdsRegMeas "<<(unsigned)config.FEConfig[i].FEGlobal.enableLvdsRegMeas <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableDregMeas "<<(unsigned) config.FEConfig[i].FEGlobal.enableDregMeas<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableTune "<<(unsigned)config.FEConfig[i].FEGlobal.enableTune <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableBiasComp "<<(unsigned) config.FEConfig[i].FEGlobal.enableBiasComp<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEGlobal.enableIpMonitor "<<(unsigned) config.FEConfig[i].FEGlobal.enableIpMonitor<<std::endl; + for (int j=0;j<5;j++){ + for (int k=0;k<ipc::IPC_N_PIXEL_COLUMNS;k++){ + std::cout<<"config.FEConfig["<<i<<"].FEMasks.maskEnable["<<j<<"]["<<k<<"]"<< config.FEConfig[i].FEMasks.maskEnable[j][k]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEMasks.maskSelect["<<j<<"]["<<k<<"] "<< config.FEConfig[i].FEMasks.maskSelect[j][k]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEMasks.maskPreamp["<<j<<"]["<<k<<"] "<< config.FEConfig[i].FEMasks.maskPreamp[j][k]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FEMasks.maskHitbus["<<j<<"]["<<k<<"] "<<config.FEConfig[i].FEMasks.maskHitbus[j][k] <<std::endl; + } + } + for (int j=0;j<ipc::IPC_N_PIXEL_ROWS;j++){ + for (int k=0;k<ipc::IPC_N_PIXEL_COLUMNS;k++){ + std::cout<<"config.FEConfig["<<i<<"].FETrims.dacThresholdTrim["<<j<<"]["<<k<<"] "<< (unsigned)config.FEConfig[i].FETrims.dacThresholdTrim[j][k]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FETrims.dacFeedbackTrim["<<j<<"]["<<k<<"] "<< (unsigned)config.FEConfig[i].FETrims.dacFeedbackTrim[j][k]<<std::endl; + } + } + std::cout<<"config.FEConfig["<<i<<"].FECalib.cinjLo "<<config.FEConfig[i].FECalib.cinjLo <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.cinjHi "<< config.FEConfig[i].FECalib.cinjHi<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.vcalCoeff[0] "<<config.FEConfig[i].FECalib.vcalCoeff[0] <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.vcalCoeff[1] "<< config.FEConfig[i].FECalib.vcalCoeff[1]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.vcalCoeff[2] "<< config.FEConfig[i].FECalib.vcalCoeff[2]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.vcalCoeff[3] "<< config.FEConfig[i].FECalib.vcalCoeff[3]<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.chargeCoeffClo "<< config.FEConfig[i].FECalib.chargeCoeffClo<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.chargeCoeffChi "<<config.FEConfig[i].FECalib.chargeCoeffChi <<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.chargeOffsetClo "<< config.FEConfig[i].FECalib.chargeOffsetClo<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.chargeOffsetChi "<< config.FEConfig[i].FECalib.chargeOffsetChi<<std::endl; + std::cout<<"config.FEConfig["<<i<<"].FECalib.monleakCoeff "<<config.FEConfig[i].FECalib.monleakCoeff <<std::endl; + } + std::cout<<"config.MCCRegisters.regCSR "<<config.MCCRegisters.regCSR <<std::endl; + std::cout<<"config.MCCRegisters.regLV1 "<<config.MCCRegisters.regLV1 <<std::endl; + std::cout<<"config.MCCRegisters.regFEEN "<<config.MCCRegisters.regFEEN <<std::endl; + std::cout<<"config.MCCRegisters.regWFE "<<config.MCCRegisters.regWFE <<std::endl; + std::cout<<"config.MCCRegisters.regWMCC "<< config.MCCRegisters.regWMCC<<std::endl; + std::cout<<"config.MCCRegisters.regCNT "<<config.MCCRegisters.regCNT <<std::endl; + std::cout<<"config.MCCRegisters.regCAL "<< config.MCCRegisters.regCAL<<std::endl; + std::cout<<"config.MCCRegisters.regPEF "<<config.MCCRegisters.regPEF <<std::endl; + std::cout<<"config.MCCRegisters.regWBITD "<< config.MCCRegisters.regWBITD<<std::endl; + std::cout<<"config.MCCRegisters.regWRECD "<<config.MCCRegisters.regWRECD <<std::endl; + std::cout<<"config.MCCRegisters.regSBSR "<<config.MCCRegisters.regSBSR <<std::endl; + +} + + +void TurboDaqFile::getLineDos(std::ifstream& is, std::string& str){ + bool readline = false; + while(readline != true){ + if(!is.good()){ + std::ostringstream errorstring; + std::cout << "Error TurboDaqFile::getLineDos: not good file status" << std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + std::getline(is,str); + //std::cout<<str<<std::endl; + if(str.c_str()[str.size()-1] == '\r') + str.erase(str.size()-1, 1); + std::stringstream s(str); + std::string field; + s >> field; + if(field != "//"){ + readline = true; + } + } + // cout << str.c_str() << endl; +} + +int TurboDaqFile::columnPairMaskDecode(int mask, int columnPairNumber){ + + switch(columnPairNumber){ + case 0: + return ((mask & 0x001)>>0); + break; + case 1: + return ((mask & 0x002)>>1); + break; + case 2: + return ((mask & 0x004)>>2); + break; + case 3: + return ((mask & 0x008)>>3); + break; + case 4: + return ((mask & 0x010)>>4); + break; + case 5: + return ((mask & 0x020)>>5); + break; + case 6: + return ((mask & 0x040)>>6); + break; + case 7: + return ((mask & 0x080)>>7); + break; + case 8: + return ((mask & 0x100)>>8); + break; + default: + std::stringstream a; + a << "Request for decoding column pair number illegal in TurboDaqFile::columnPairMaskDecode. Mask value: " << mask; + a << "Column Pair value: " << columnPairNumber << std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + return 1; +} + +void TurboDaqFile::intMaskFileDecode(CORBA::Octet arr[][ipc::IPC_N_PIXEL_COLUMNS], int valflag, std::ifstream* file){ + if(valflag == 128){ // Turbo Daq alternative file found + int j; + for(j = 0; j < numberofrows; j++){ + std::string readstring; + getLineDos(*file,readstring); + std::stringstream a(readstring); + int ncols; + for(ncols = 0; ncols < numberofcolumns; ncols++){ + int val; + a>> val; + arr[j][ncols]=val; + } + } + } + else{ + for(int j = 0; j < numberofrows; j++){ + for(int ncols = 0; ncols < numberofcolumns; ncols++){ + arr[j][ncols]=valflag; + } + } + } +} + +void TurboDaqFile::boolMaskFileDecode(CORBA::ULong arr[][ipc::IPC_N_PIXEL_COLUMNS] , int valflag, std::ifstream* file){ + if(valflag == 0) { // Turbo Daq alternative file found + for(int j = 0; j < numberofcolumns; j++){ + std::string readstring; + getLineDos(*file,readstring); + std::stringstream a(readstring); + unsigned column; + a>>std::dec>>column; + for(int nrows = 0; nrows <5; nrows++){ + unsigned columnmask; + a >> std::hex >>columnmask; + arr[4-nrows][column]=columnmask; + } + } + } + else{ + unsigned val; + if(valflag == 1)val=0; // TurboDaq all off found + else if(valflag == 2)val=0xffffffff; // TurboDaq all on found + else{ + std::stringstream a; + a << "TurboDaqFile::intMaskFileDecode: Turbo daq code not correct (0, 1 or 2 allowed) " << valflag; + throw rcecalib::Config_File_Error(ERS_HERE); + } + for(int j = 0; j < numberofcolumns; j++){ + for(int nrows = 0; nrows < 5; nrows++){ + arr[nrows][j]=val; + } + } + } +} + + +void TurboDaqFile::openTurboDaqFiles(std::string filename){ + m_moduleCfgFile=new std::ifstream(filename.c_str()); + m_moduleCfgFilePath = filename; + if(!m_moduleCfgFile->good()){ + throw rcecalib::Config_File_Error(ERS_HERE); + } +} + +void TurboDaqFile::readModuleConfig(ipc::PixelModuleConfig* mod, std::string namefile){ + //std::cout<<namefile<<std::endl; + + std::string readstring; + std::stringstream modstream; + int modrunnint; + //clear structure + char* ccfg=(char*)mod; + for (unsigned int i=0;i<sizeof(ipc::PixelModuleConfig);i++)ccfg[i]=0; + openTurboDaqFiles(namefile); + std::string readString; + getLineDos(*m_moduleCfgFile,readString); + getLineDos(*m_moduleCfgFile,readString); + getLineDos(*m_moduleCfgFile,readString); + getLineDos(*m_moduleCfgFile,readString); + + if(readString == "1"){ // module + } + else if(readString == "0"){ // single chip + // readSingleChipConfig(m_rootRecord); + std::cout<<"Single Chip assembly record, not implemented"<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + else throw rcecalib::Config_File_Error(ERS_HERE); + + getLineDos(*m_moduleCfgFile, readstring); + getLineDos(*m_moduleCfgFile, readstring); // here we read the MCC type + modstream.str(readstring); + modstream >> modrunnint; modstream.clear(); + mod->mccFlavour=modrunnint; + // MCC + //mod->MCCRegisters.regFEEN=0xffff; + + getLineDos(*m_moduleCfgFile, readstring); + getLineDos(*m_moduleCfgFile, readstring); // here we read the FE type + modstream.str(readstring); + modstream >> modrunnint; modstream.clear(); + mod->feFlavour=modrunnint; + int feflavour=modrunnint; + + // variables used to temporary store the information from config file + std::vector<std::string> rmname; rmname.resize(nofchip); + std::vector<std::string> smname; smname.resize(nofchip); + std::vector<std::string> pkname; pkname.resize(nofchip); + std::vector<std::string> hmname; hmname.resize(nofchip); + std::vector<std::string> tdname; tdname.resize(nofchip); + std::vector<std::string> fdname; fdname.resize(nofchip); + + + int runnInt; + std::string runString; + std::stringstream a(readstring); // Chip 0 geographical address (0-15) + + // scan the config file + for(int i = 0; i < nofchip; i++){ + + for(int j = 0; j < 4; j++) getLineDos(*m_moduleCfgFile,readstring); + + getLineDos(*m_moduleCfgFile,readstring); + a.str(readstring); + a>>runnInt; a.clear(); + //mod->FEConfig[number].FECommand.address=runnInt; + mod->FEConfig[i].FEIndex=runnInt; + mod->FEConfig[i].FEGlobal.latency=255; + mod->FEConfig[i].FEGlobal.frequencyCEU=2; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 global configuration enable (0 = off, 1 = on) + a.str(readstring); + a>>runnInt; a.clear(); + mod->maskEnableFEConfig &= (~(0x1<<i)); mod->maskEnableFEConfig |= (runnInt<<i); + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 global scan/readout enable (0 = off, 1 = on) + a.str(readstring); + a>>runnInt; a.clear(); + mod->maskEnableFEScan &= (~(0x1<<i)); mod->maskEnableFEScan |= (runnInt<<i); + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 DACs enable (0 = off, 1 = on) + a.str(readstring); + a>>runnInt; a.clear(); + mod->maskEnableFEDacs &= (~(0x1<<i)); mod->maskEnableFEDacs |= (runnInt<<i); + + if(feflavour == 1){ + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 Global Threshold DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.gdac=runnInt; + } + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IVDD2 DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIVDD2=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 ID DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacID=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IP2 DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIP2=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IP DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIP=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 TRIMT DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacITRIMTH =runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IF DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIF=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 TRIMF DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacITRIMIF=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 ITH1 DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacITH1=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 ITH2 DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacITH2=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IL DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIL=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 IL2 DAC + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.dacIL2=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 column-pair mask parameter + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.enableCP0= columnPairMaskDecode(runnInt,0); + mod->FEConfig[i].FEGlobal.enableCP1= columnPairMaskDecode(runnInt,1); + mod->FEConfig[i].FEGlobal.enableCP2= columnPairMaskDecode(runnInt,2); + mod->FEConfig[i].FEGlobal.enableCP3= columnPairMaskDecode(runnInt,3); + mod->FEConfig[i].FEGlobal.enableCP4= columnPairMaskDecode(runnInt,4); + mod->FEConfig[i].FEGlobal.enableCP5= columnPairMaskDecode(runnInt,5); + mod->FEConfig[i].FEGlobal.enableCP6= columnPairMaskDecode(runnInt,6); + mod->FEConfig[i].FEGlobal.enableCP7= columnPairMaskDecode(runnInt,7); + mod->FEConfig[i].FEGlobal.enableCP8= columnPairMaskDecode(runnInt,8); + + mod->FEConfig[i].FEGlobal.hitbusScaler = 0; // : 8; ??? + mod->FEConfig[i].FEGlobal.selfWidth = 0; // : 4; ??? + mod->FEConfig[i].FEGlobal.selfLatency = 0; // : 4; ??? + mod->FEConfig[i].FEGlobal.aregTrim = 1; // : 2; + mod->FEConfig[i].FEGlobal.aregMeas = 0; // : 2; + mod->FEConfig[i].FEGlobal.dregTrim = 1; // : 2; + mod->FEConfig[i].FEGlobal.dregMeas = 0; // : 2; + mod->FEConfig[i].FEGlobal.parity = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableHitParity = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableMonLeak = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableHitbus = 1; // : 1; + mod->FEConfig[i].FEGlobal.monSpare = 0; // : 1; ??? + mod->FEConfig[i].FEGlobal.enableAregMeas = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableAreg = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableLvdsRegMeas = 0; // : 1; ??? + mod->FEConfig[i].FEGlobal.enableDregMeas = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableTune = 0; // : 1; + mod->FEConfig[i].FEGlobal.enableBiasComp = 1; // : 1; + mod->FEConfig[i].FEGlobal.enableIpMonitor = 0; // : 1; ??? + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 Timestamp enable (0 = OFF, 1 = ON) + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.enableTimestamp=runnInt; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 Decoupling capacitor enable (0 = OFF, 1 = ON) + a.str(readstring); + a>>runnInt; a.clear(); + mod->FEConfig[i].FEGlobal.enableCapTest=runnInt; + + std::ifstream * ifp = 0; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 readout mask mode (see end for details) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 readout mask file (if appl.) + a.str(readstring); + a>>rmname[i]; a.clear(); //cout << rmname[i].c_str() << endl; + + if(runnInt == 0){ + + std::string full_path = getFullPath(rmname[i]); + ifp = new std::ifstream; + + ifp->open(full_path.c_str()); + + if(!ifp->good()){ + + std::stringstream a; + a << "Chip " << i << " "; + a << "readout mask file not open as good: " << full_path.c_str(); + + throw rcecalib::Config_File_Error(ERS_HERE); + + } + } + + //ENABLE + boolMaskFileDecode(mod->FEConfig[i].FEMasks.maskEnable, runnInt, ifp); + if(runnInt == 0) delete ifp; + + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 strobe mask mode (see end for details) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 strobe mask file (if appl.) + a.str(readstring); + a>>smname[i]; a.clear(); + if(runnInt == 0){ + std::string full_path = getFullPath(smname[i]); + + ifp = new std::ifstream; + ifp->open(full_path.c_str()); + if(!ifp->good()){ + std::stringstream a; + a << "Chip " << i << " "; + a << "strobe mask file not open as good: " << full_path.c_str(); + throw rcecalib::Config_File_Error(ERS_HERE); + } + } + + + //SELECT + boolMaskFileDecode(mod->FEConfig[i].FEMasks.maskSelect, runnInt, ifp); + if (runnInt == 0) delete ifp; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 preamp kill mask mode (FE-I only) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 preamp mask file (if appl.) + a.str(readstring); + a>>pkname[i]; a.clear(); + if(runnInt == 0){ + std::string full_path = getFullPath(pkname[i]); + ifp = new std::ifstream; + ifp->open(full_path.c_str()); + if(!ifp->good()){ + std::stringstream a; + a << "Chip " << i << " "; + a << "preamp mask file not open as good: " << full_path.c_str(); + throw rcecalib::Config_File_Error(ERS_HERE); + } + } + //PREAMP + boolMaskFileDecode(mod->FEConfig[i].FEMasks.maskPreamp, runnInt, ifp); + if (runnInt == 0) delete ifp; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 hitbus mask mode (FE-I only) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 hitbus mask file (if appl.) + a.str(readstring); + a>>hmname[i]; a.clear(); + if(runnInt == 0){ + std::string full_path = getFullPath(hmname[i]); + ifp = new std::ifstream; + ifp->open(full_path.c_str()); + if(!ifp->good()){ + std::stringstream a; + a << "Chip " << i << " "; + a << "hitbus mask file not open as good: " << full_path.c_str(); + throw rcecalib::Config_File_Error(ERS_HERE); + } + } + //HITBUS + boolMaskFileDecode(mod->FEConfig[i].FEMasks.maskHitbus, runnInt, ifp); + if (runnInt == 0) delete ifp; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 TDAC mode (n = all n (for n = 0-31), 32 = alternative file) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 TDAC file + a.str(readstring); + a>>tdname[i]; a.clear(); + if(runnInt == 128){ + std::string full_path = getFullPath(tdname[i]); + ifp = new std::ifstream; + ifp->open(full_path.c_str()); + if(!ifp->good()){ + std::stringstream a; + a << "Chip " << i << " "; + a << "TDAC file not open as good: " << full_path.c_str(); + std::cout<<"Could not open file "<<full_path.c_str()<<std::endl; + throw rcecalib::Config_File_Error(ERS_HERE); + } + } + //TDAC + intMaskFileDecode(mod->FEConfig[i].FETrims.dacThresholdTrim, runnInt, ifp); + if (runnInt == 128) delete ifp; + + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 FDAC mode (n = all n (for n = 0-31), 32 = alternative file) + a.str(readstring); + a>>runnInt; a.clear(); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 FDAC file + a.str(readstring); + a>>fdname[i]; a.clear(); + if(runnInt == 128){ + std::string full_path = getFullPath(fdname[i]); + ifp = new std::ifstream; + ifp->open(full_path.c_str()); + if(!ifp->good()){ + std::stringstream a; + a << "Chip " << i << " "; + a << "FDAC file not open as good: " << full_path.c_str(); + throw rcecalib::Config_File_Error(ERS_HERE); + } + } + // FDAC + intMaskFileDecode(mod->FEConfig[i].FETrims.dacFeedbackTrim, runnInt, ifp); + if (runnInt == 128) delete ifp; + } + + getLineDos(*m_moduleCfgFile, readstring); + getLineDos(*m_moduleCfgFile, readstring); + getLineDos(*m_moduleCfgFile, readstring); + + float runnFloat; + {for(int k = 0; k < nofchip; k++){ + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip k Cinj-LO (fF) + a.str(readstring); + a>>runnFloat; a.clear(); + mod->FEConfig[k].FECalib.cinjLo = runnFloat; + }} + + {for(int k = 0; k < nofchip; k++){ + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip k Cinj-HI (fF) + a.str(readstring); + a>>runnFloat; a.clear(); + mod->FEConfig[k].FECalib.cinjHi = runnFloat; + }} + + + {for(int k = 0; k < nofchip; k++){ + bool isCubicFit=false; + getLineDos(*m_moduleCfgFile,readstring); + if((int)readstring.find("VCAL-FE coefficients")!=(int)std::string::npos) + isCubicFit = true; + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 VCAL-FE gradient (mV/count) + a.str(readstring); + float c0, c1, c2, c3; + if(isCubicFit){ // new TurboDAQ format has slope, cubic and quadratic fit pars in one row + a.str(readstring); + a>>c3>>c2>>c1>>c0; a.clear(); + } else { + a>>c1; a.clear(); + c0 = c2 = c3 = 0.0; + } + mod->FEConfig[k].FECalib.vcalCoeff[0]=c0; + mod->FEConfig[k].FECalib.vcalCoeff[1]=c1; + mod->FEConfig[k].FECalib.vcalCoeff[2]=c2; + mod->FEConfig[k].FECalib.vcalCoeff[3]=c3; + }} + + {for(int k = 0; k < nofchip; k++){ + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // Chip 0 Internal-injection offset correction (VCAL-FE counts) + a.str(readstring); + a>>runnFloat; a.clear(); + //fefi = new TurboDaqFileField("OffsetCorrection", FLOAT); + }} + + // two empty lines and TPLL XCKr phase + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); + + {for(int k = 0; k < 16; k++){ + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); // MCC CAL strobe-delay range 0: calibration factor (ns/count) + a.str(readstring); + a>>runnFloat; a.clear(); + std::string name = "DELAY_"; + std::stringstream b; + b << k; + name += b.str(); + // fefi = new TurboDaqFileField(name.c_str(), FLOAT); + //fefi->m_floatContent = runnFloat; + //insertField(*it, fefi); + }} + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); + getLineDos(*m_moduleCfgFile,readstring); + sprintf((char*)mod->idStr, readstring.c_str()); + delete m_moduleCfgFile; +} + +//FS: writing out config file... + + +void TurboDaqFile::writeMaskFile(CORBA::ULong arr[][ipc::IPC_N_PIXEL_COLUMNS], std::string path){ + std::ofstream file(path.c_str()); + for (int j = 0; j < ipc::IPC_N_PIXEL_COLUMNS; j++) { + if (j<10) + file<<std::dec<<j<<" "; + else + file<<std::dec<<j<<" "; + for (int i = 0; i < 5; i++){ + file<<std::hex<<arr[4-i][j]<<" "; + } + file<<std::endl; + } + file.close(); +} + +void TurboDaqFile::writeMaskFileFT(CORBA::Octet arr[][ipc::IPC_N_PIXEL_COLUMNS], std::string path){ + std::ofstream file(path.c_str()); + for (int i = 0; i < numberofrows; i++) { + for (int j = 0; j < numberofcolumns; j++){ + file<<(int) arr[i][j]<<" "; + } + file<<std::endl; + } + file.close(); +} + +void TurboDaqFile::writeModuleConfig(ipc::PixelModuleConfig* config, const std::string &base, const std::string &confdir, const std::string &configname, const std::string &key){ + struct stat stFileInfo; + int intStat; + // Attempt to get the file attributes + intStat = stat(base.c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<" does not exist. Not writing config file"<<std::endl; + return; + } + + intStat = stat((base+"/"+confdir).c_str(),&stFileInfo); + if(intStat != 0) { //File does not exist + std::cout<<"Directory "<<base<<"/"<<confdir<<" does not exist. Creating."<<std::endl; + mkdir (base.c_str(),0777); + mkdir ((base+"/"+confdir).c_str(),0777); + mkdir ((base+"/"+confdir+"/configs").c_str(),0777); + mkdir ((base+"/"+confdir+"/masks").c_str(),0777); + mkdir ((base+"/"+confdir+"/tdacs").c_str(),0777); + mkdir ((base+"/"+confdir+"/fdacs").c_str(),0777); + } + + std::string cfgname=configname; + if(key.size()!=0) cfgname+="__"+key; + std::string fullpath=base+"/"+confdir+"/configs/"+cfgname+".cfg"; + std::cout<<fullpath<<std::endl; + std::ofstream cfgfile(fullpath.c_str()); + cfgfile<<"TurboDAQ VERSION 6.6"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"Assembly type (0 = Single-chip, 1 = Module)"<<std::endl; + cfgfile<<"1"<<std::endl; + cfgfile<<"MCC flavour if applicable (1 = MCC-I1, 2 = MCC-I2)"<<std::endl; + cfgfile<<"2"<<std::endl; + cfgfile<<"FE flavour (0 = FE-I1, 1 = FE-I2)"<<std::endl; + cfgfile<<"1"<<std::endl; + cfgfile<<std::endl; + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + std::stringstream iStringstream; + std::string iString; + iStringstream << i; + if (i <10) + iString = "0" + iStringstream.str(); + else + iString = iStringstream.str(); + + cfgfile<<"CHIP "<<i<<":"<<std::endl; + cfgfile<<std::endl; + cfgfile<<"Chip "<<i<<" geographical address (0-15)"<<std::endl<<(unsigned) config->FEConfig[i].FEIndex<<std::endl; + + int enable = config->maskEnableFEConfig & (0x1<<i); + bool isEnable = (enable!=0); + cfgfile<<"Chip "<<i<<" global configuration enable (0 = off, 1 = on)"<<std::endl<<isEnable<<std::endl; + + enable = config->maskEnableFEScan & (0x1<<i); + isEnable = (enable!=0); + cfgfile<<"Chip "<<i<<" global scan/readout enable (0 = off, 1 = on)"<<std::endl<<isEnable<<std::endl; + + enable = config->maskEnableFEDacs & (0x1<<i); + isEnable = (enable!=0); + cfgfile<<"Chip "<<i<<" DACs enable (0 = off, 1 = on)"<<std::endl<<isEnable<<std::endl; + cfgfile<<"Chip "<<i<<" Global Threshold DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.gdac<<std::endl; + cfgfile<<"Chip "<<i<<" IVDD2 DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIVDD2<<std::endl; + cfgfile<<"Chip "<<i<<" ID DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacID<<std::endl; + cfgfile<<"Chip "<<i<<" IP2 DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIP2<<std::endl; + cfgfile<<"Chip "<<i<<" IP DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIP<<std::endl; + cfgfile<<"Chip "<<i<<" TRIMT DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacITRIMTH<<std::endl; + cfgfile<<"Chip "<<i<<" IF DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIF<<std::endl; + cfgfile<<"Chip "<<i<<" TRIMF DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacITRIMIF<<std::endl; + cfgfile<<"Chip "<<i<<" ITH1 DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacITH1<<std::endl; + cfgfile<<"Chip "<<i<<" ITH2 DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacITH2<<std::endl; + cfgfile<<"Chip "<<i<<" IL DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIL<<std::endl; + cfgfile<<"Chip "<<i<<" IL2 DAC"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.dacIL2<<std::endl; + + // FS: Encoding mask parameter from enableCPi's + int mask = 0; + mask = mask | config->FEConfig[i].FEGlobal.enableCP0; + mask = mask | (config->FEConfig[i].FEGlobal.enableCP1<<1); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP2<<2); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP3<<3); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP4<<4); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP5<<5); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP6<<6); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP7<<7); + mask = mask | (config->FEConfig[i].FEGlobal.enableCP8<<8); + cfgfile<<"Chip "<<i<<" column-pair mask parameter"<<std::endl<<mask<<std::endl; + + cfgfile<<"Chip "<<i<<" Timestamp enable (0 = OFF, 1 = ON)"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.enableTimestamp<<std::endl; + cfgfile<<"Chip "<<i<<" Decoupling capacitor enable (0 = OFF, 1 = ON)"<<std::endl<<(unsigned) config->FEConfig[i].FEGlobal.enableCapTest<<std::endl; + std::string path = confdir+"/masks/enable_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" readout mask mode (see end for details)"<<std::endl<<"0"<<std::endl; + cfgfile<<"Chip "<<i<<" readout mask file (if appl.)"<<std::endl<<path<<std::endl; + path = base+"/"+confdir+"/masks/enable_"+iString+"_"+cfgname+".dat"; + writeMaskFile(config->FEConfig[i].FEMasks.maskEnable, path); + + path=confdir+"/masks/strobe_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" strobe mask mode (see end for details)"<<std::endl<<"0"<<std::endl; + cfgfile<<"Chip "<<i<<" strobe mask file (if appl.)"<<std::endl<<path<<std::endl; + path=base+"/"+confdir+"/masks/strobe_"+iString+"_"+cfgname+".dat"; + writeMaskFile(config->FEConfig[i].FEMasks.maskSelect, path); + + path=confdir+"/masks/preamp_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" preamp kill mask mode (FE-I only)"<<std::endl<<"0"<<std::endl; + cfgfile<<"Chip "<<i<<" preamp mask file (if appl.)"<<std::endl<<path<<std::endl; + path=base+"/"+confdir+"/masks/preamp_"+iString+"_"+cfgname+".dat"; + writeMaskFile(config->FEConfig[i].FEMasks.maskPreamp, path); + + path=confdir+"/masks/hitbus_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" hitbus mask mode (FE-I only)"<<std::endl<<"0"<<std::endl; + cfgfile<<"Chip "<<i<<" hitbus mask file (if appl.)"<<std::endl<<path<<std::endl; + path=base+"/"+confdir+"/masks/hitbus_"+iString+"_"+cfgname+".dat"; + writeMaskFile(config->FEConfig[i].FEMasks.maskHitbus, path); + + path=confdir+"/tdacs/tdac_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" TDAC mode (n = all n (for n = 0-31), 128 = alternative file)"<<std::endl<<"128"<<std::endl; + cfgfile<<"Chip "<<i<<" TDAC file"<<std::endl<<path<<std::endl; + path=base+"/"+confdir+"/tdacs/tdac_"+iString+"_"+cfgname+".dat"; + writeMaskFileFT(config->FEConfig[i].FETrims.dacThresholdTrim, path); + + path=confdir+"/fdacs/fdac_"+iString+"_"+cfgname+".dat"; + cfgfile<<"Chip "<<i<<" FDAC mode (n = all n (for n = 0-31), 128 = alternative file)"<<std::endl<<"128"<<std::endl; + cfgfile<<"Chip "<<i<<" FDAC file"<<std::endl<<path<<std::endl; + path=base+"/"+confdir+"/fdacs/fdac_"+iString+"_"+cfgname+".dat"; + writeMaskFileFT(config->FEConfig[i].FETrims.dacFeedbackTrim, path); + cfgfile<<std::endl; + } + + cfgfile<<"Calibration Parameters:"<<std::endl; + cfgfile<<std::endl; + + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + cfgfile<<"Chip "<<i<<" Cinj-LO (fF)"<<std::endl<<(float) config->FEConfig[i].FECalib.cinjLo<<std::endl; + } + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + cfgfile<<"Chip "<<i<<" Cinj-HI (fF)"<<std::endl<<(float) config->FEConfig[i].FECalib.cinjHi<<std::endl; + } + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + cfgfile<<"Chip "<<i<<" VCAL-FE coefficients (V(mV) = [0]*vcal**3+[1]*vcal**2+[2]*vcal+[3])"<<std::endl; + cfgfile<<(float) config->FEConfig[i].FECalib.vcalCoeff[3]<<" "<<(float) config->FEConfig[i].FECalib.vcalCoeff[2]<<" "<<(float) config->FEConfig[i].FECalib.vcalCoeff[1]<<" "<<(float) config->FEConfig[i].FECalib.vcalCoeff[0]<<std::endl; + } + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + // FS: Is not used by read-in function, thus being set to 0 + cfgfile<<"Chip "<<i<<" Internal-injection offset correction (VCAL-FE counts)"<<std::endl<<"0"<<std::endl; + } + cfgfile<<std::endl; + cfgfile<<"TPLL XCKr phase"<<std::endl; + cfgfile<<"0"<<std::endl; // FS: Is not used by read-in function, thus being set to 0 + cfgfile<<std::endl; + + for(int i=0;i<ipc::IPC_N_PIXEL_FE_CHIPS;i++){ + // FS: Is not used by read-in function, thus being set to 0 + cfgfile<<"MCC CAL strobe-delay range "<<i<<": calibration factor (ns/count)"<<std::endl<<"0"<<std::endl; + } + cfgfile<<std::endl; + cfgfile<<"Module string identifier"<<std::endl; + cfgfile<<config->idStr<<std::endl; +} + +TurboDaqFile::TurboDaqFile() {} + + +std::string TurboDaqFile::getFullPath(std::string relPath){ + std::string newPath = relPath, basePath=m_moduleCfgFilePath, testName; + unsigned int pos; + // skip config file-name part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // skip "config" part of base path + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos,basePath.length()-pos); + // now skip module part of base path, but keep last "/" + pos = basePath.find_last_of('/'); + if(pos!=std::string::npos) basePath.erase(pos+1,basePath.length()-pos); + else basePath=""; + // then add relative path of DAC or mask file + newPath = basePath + newPath; + return newPath; +} + diff --git a/rce/rcecalib/server/TurboDaqFile.hh b/rce/rcecalib/server/TurboDaqFile.hh new file mode 100644 index 0000000000000000000000000000000000000000..94856ea1b6d60214810300791130f8308f7934ec --- /dev/null +++ b/rce/rcecalib/server/TurboDaqFile.hh @@ -0,0 +1,34 @@ +// Reads in module config from Turbo DAQ file. Modified version of PixLib's TurboDaqDB.h +#ifndef TURBODAQFILE_HH +#define TURBODAQFILE_HH + +#include <map> +#include <string> +#include <fstream> +#include "PixelModuleConfig.hh" + + + class TurboDaqFile { + protected: + void openTurboDaqFiles(std::string filename); + int columnPairMaskDecode(int mask, int chipNumber); + void boolMaskFileDecode(CORBA::ULong arr[][ipc::IPC_N_PIXEL_COLUMNS], int valflag, std::ifstream* file); + void intMaskFileDecode(CORBA::Octet arr[][ipc::IPC_N_PIXEL_COLUMNS], int valflag, std::ifstream* file); + void getLineDos(std::ifstream& is, std::string& str); + void writeMaskFile(CORBA::ULong arr[][ipc::IPC_N_PIXEL_COLUMNS], std::string path); + void writeMaskFileFT(CORBA::Octet arr[][ipc::IPC_N_PIXEL_COLUMNS], std::string path); + std::string getFullPath(std::string relPath); + + std::string m_moduleCfgFilePath; + std::ifstream *m_moduleCfgFile; + + public: + ~TurboDaqFile(){} + TurboDaqFile(); + void readModuleConfig(ipc::PixelModuleConfig*, std::string filename); + void writeModuleConfig(ipc::PixelModuleConfig* cfg, const std::string &base, const std::string &confdir, +const std::string &configname, const std::string &key); + void dump(const ipc::PixelModuleConfig&); + }; + +#endif diff --git a/rce/rcecalib/server/atlasimage.hh b/rce/rcecalib/server/atlasimage.hh new file mode 100644 index 0000000000000000000000000000000000000000..79de9cfbd4cbac5bf2345feac8bb48ba77f6925a --- /dev/null +++ b/rce/rcecalib/server/atlasimage.hh @@ -0,0 +1,364 @@ +#ifndef ATLASIMAGE_HH +#define ATLASIMAGE_HH +/* XPM */ +static const char *atlas_detector_small[] = { +/* width height num_colors chars_per_pixel */ +" 150 98 256 2", +/* colors */ +".. c #070819", +".# c #2084e4", +".a c #79360c", +".b c #34441e", +".c c #96893e", +".d c #b0c5a4", +".e c #404527", +".f c #53643a", +".g c #d48946", +".h c #968d8f", +".i c #4c1204", +".j c #04261c", +".k c #746018", +".l c #404a5d", +".m c #d1e4eb", +".n c #9aa5a2", +".o c #af621e", +".p c #426583", +".q c #738359", +".r c #766157", +".s c #8ca68c", +".t c #092850", +".u c #baa798", +".v c #6185a2", +".w c #dcc8a6", +".x c #664725", +".y c #0a4685", +".z c #787267", +".A c #626a78", +".B c #98a17b", +".C c #2d2719", +".D c #977461", +".E c #5e5058", +".F c #95a8c4", +".G c #d8d0d0", +".H c #719ab3", +".I c #656346", +".J c #1866ae", +".K c #3e3027", +".L c #43543e", +".M c #27150e", +".N c #be8445", +".O c #bcb698", +".P c #78757e", +".Q c #2e3614", +".R c #622e0b", +".S c #415665", +".T c #f3e4ce", +".U c #899970", +".V c #b1c9de", +".W c #292f48", +".X c #667447", +".Y c #52758a", +".Z c #96b49e", +".0 c #294f7a", +".1 c #665724", +".2 c #0a1721", +".3 c #858567", +".4 c #97887b", +".5 c #838798", +".6 c #b4828c", +".7 c #7e7110", +".8 c #99947f", +".9 c #cea88f", +"#. c #3e3536", +"## c #7a7b6c", +"#a c #67747f", +"#b c #dcd3c2", +"#c c #43463f", +"#d c #3f5a82", +"#e c #b6b5be", +"#f c #d4a2ac", +"#g c #999794", +"#h c #f8f5e0", +"#i c #204464", +"#j c #a9a597", +"#k c #87857f", +"#l c #67645d", +"#m c #f0dbd3", +"#n c #193753", +"#o c #a79b92", +"#p c #2e2a2a", +"#q c #51585f", +"#r c #9a5e28", +"#s c #3f6a9b", +"#t c #c7c3b0", +"#u c #6587b8", +"#v c #b0753b", +"#w c #774c26", +"#x c #18558e", +"#y c #31352f", +"#z c #5f4b3f", +"#A c #061738", +"#B c #a68a78", +"#C c #30455a", +"#D c #edcab5", +"#E c #8798a2", +"#F c #403829", +"#G c #50493f", +"#H c #d0b9ac", +"#I c #607ca1", +"#J c #867365", +"#K c #1c3210", +"#L c #c0a280", +"#M c #97b6cf", +"#N c #b9d3e9", +"#O c #cbcfc5", +"#P c #dddada", +"#Q c #515644", +"#R c #bcb6ac", +"#S c #2f5a86", +"#T c #898f84", +"#U c #9b5518", +"#V c #615445", +"#W c #040c31", +"#X c #b9aca7", +"#Y c #d9c9bd", +"#Z c #e7bcab", +"#0 c #42665d", +"#1 c #6e8fa4", +"#2 c #4276ab", +"#3 c #f0e5e2", +"#4 c #696b62", +"#5 c #09386b", +"#6 c #316593", +"#7 c #677b88", +"#8 c #a9a9aa", +"#9 c #655c49", +"a. c #506881", +"a# c #5484a4", +"aa c #64a8f4", +"ab c #4789d1", +"ac c #8bb2d7", +"ad c #cf7821", +"ae c #ce9986", +"af c #9d7247", +"ag c #b98a6e", +"ah c #d1b48e", +"ai c #4198f4", +"aj c #5c2404", +"ak c #3175b9", +"al c #af7a5d", +"am c #618584", +"an c #787146", +"ao c #745445", +"ap c #c6cad8", +"aq c #f1d7ba", +"ar c #b79c92", +"as c #3397f9", +"at c #ce9452", +"au c #613a14", +"av c #765e48", +"aw c #dff0f9", +"ax c #916857", +"ay c #b79580", +"az c #cad4e2", +"aA c #4e705d", +"aB c #ae6c32", +"aC c #0a2736", +"aD c #085ba8", +"aE c #a3ad80", +"aF c #957d76", +"aG c #6d9ed4", +"aH c #829dc1", +"aI c #422411", +"aJ c #2b3b4f", +"aK c #8cc2fc", +"aL c #e1ad7b", +"aM c #615b59", +"aN c #764014", +"aO c #34503c", +"aP c #b4d0b0", +"aQ c #281c12", +"aR c #7a7c82", +"aS c #413c39", +"aT c #976742", +"aU c #835327", +"aV c #74928c", +"aW c #807e3c", +"aX c #687461", +"aY c #325062", +"aZ c #2a69b0", +"a0 c #174980", +"a1 c #a9b5a5", +"a2 c #c17733", +"a3 c #a9b6c4", +"a4 c #ddb885", +"a5 c #5098e0", +"a6 c #a78554", +"a7 c #77691f", +"a8 c #6c90bb", +"a9 c #79684a", +"b. c #c09054", +"b# c #88909c", +"ba c #bcaf7f", +"bb c #c06d1c", +"bc c #5e3d2d", +"bd c #89aac0", +"be c #1a3635", +"bf c #160c0a", +"bg c #4f4c58", +"bh c #1a1713", +"bi c #161b32", +"bj c #d0bdbe", +"bk c #5179a4", +"bl c #e2e5e9", +"bm c #4f2d15", +"bn c #4e3b2a", +"bo c #78685d", +"bp c #858f68", +"bq c #4f462a", +"br c #a68e90", +"bs c #1a260f", +"bt c #182b49", +"bu c #a9abbf", +"bv c #4e5b80", +"bw c #516a96", +"bx c #173b68", +"by c #1a2731", +"bz c #616c93", +"bA c #8a9784", +"bB c #b1caf2", +"bC c #f8f8f8", +"bD c #304634", +"bE c #b2c7c7", +"bF c #997c67", +"bG c #a79581", +"bH c #c6c6c4", +"bI c #874c1b", +"bJ c #53655a", +"bK c #4f85bb", +"bL c #728482", +"bM c #8b6f44", +"bN c #318de7", +"bO c #969cb2", +"bP c #54702c", +"bQ c #877c6e", +"bR c #88400c", +"bS c #291d29", +"bT c #867d7e", +"bU c #4e3d36", +"bV c #885c2c", +"bW c #70879d", +"bX c #a6a37d", +"bY c #51333c", +"bZ c #855f41", +"b0 c #1a5a9f", +"b1 c #626b44", +"b2 c #faebcf", +"b3 c #7e7817", +"b4 c #bbbcc4", +"b5 c #cfada2", +"b6 c #214b66", +"b7 c #879fa7", +"b8 c #bcdefc", +"b9 c #f0eceb", +/* pixels */ +"aDaDa0.t#W...2....#W....#Aa0aZaZak.J.0.0bv#q#C#i#sb0b0#x#sbdbu#Pazb9#o#z.1.k.7.7b3b3.Q#Q#G.P.zbo#G#Vbo#Tbj#3#Pblap#gaMaMaM#P#P#l.AbgaM#a.haRbT.P.PaR#kaR.AaM#l.PaM.z#GaSbUaM.z#o.GbCb9#m#t#o#J#G.z#ObCbla3.n#TaWa7.cb3b3an.zbTbObCbCaw.ma3#d#2#sbkbKbw#S#sa8akakakaZb0#5a0#5.0aY#CaY#C#n.t#5a0.JaDaDbNasas.#", +"aD#x#x.t#W......#W..#A#A#W#W#5#xaZak#6#S.l#dbv#s.p#Sa0#xaHa3azazbl#8.E#V.kbM.7.cb3b3an.I#k.5bTbU#VbXao.h#RbH.Gb4bjbO#gbub##ebCaRbO.nbO#8#8b4blblb9#P#e#e#e#eap#ebobQ#V#9#8.zbT#Xbl#3#Y#P#R.4av.z#lbLb9awb4ap.B##aW.7aWana7.z.5.5bCbCb9bl#NbB#I.0#s#2aY#S#2bKak.JakaZab.ya0#S#d.0#daJ#n.t.0#s#6aZ.yaD.#asasas", +".J#x.y#W#A....#W#W..#W#W#W#W#W.t.0#6#s#s#S#6.Ybw.0.0#ia8a3.V#P.G#ebJbq.1.1.k.k.k.kb1.f.3#k#k#Q#G#lbQ.z#J#o.u#Y#Pbj#e.5.G#O#Pbl#T#jb9bCbl#8azbCbCbCbC#eapbCbCb9#gbo#obo.z#R.Ebo#o#3b9#b#R#X.4.4#VaMbJ#gapblbl#e#j##anb1aW.z#8#TbO#EbCbCbCawbB#M.0#2#d#u#sbKakaZaZabab#xa0#5#5#C#A#A.taJ#dacac#S#xakaD.JbNasas", +".y.y.y#W#W....#W..#W#W#W#W#W#W#W#Abx.0#2#2#6#s#S.0bxb#bubj#P.G#eaX.L.3bp.1bG.c.c.8.I#T#kaX#Q.l.B#Xb5#J.rbTbjbj#obTbobT#X#P#P#P#gb#blawb9#e.GbCbCbCbC#e.Gb9bCbCb#.z#X.8.8aF#zaMbo#J.u#Y#H#B#9brbGaEbT#qaRblb9#P#eb4.8.h.8.nbEap.ZbL#EawbCb9bl#N.F#u#5#6#2#2bKaZaa#2a0#xa0#5#5.tbx#C.l.S#u#Sbt#2aKa5aDaDbNaiai", +".yaD#5#W#W#W......#W#W....#W#W#W..#A.t#SaZakak#i#d.5bObj.G.G.GaX.Sb7.d#8.8bQ#bbG##bQ#g#TaM#y#8.G#b.4#9#9.rbrax.r.rbo.PbT#3blbl#PapazbHblazb9bCbCbCbCblb9blapblaz#j#R#kbT#VaM.r.r#9#J#J#oaFbQao#g#X.P#l#ab#b4blaz#ebObO#Eb4a3.ZaH#a#l.5b9bCb9blb8.F.0#6akakakaG#x.0.0b6bt#A#W#n#n#nbt.t.t#dacaGaZb0.yaDaZaiai", +"b0.y#5.t#W#W..............#W......#W#W.t.y#6#2#d#ubObjbj.G#Y#l#Q#S#Na3.n#T.3aF.3bQ#o#j#4#p.PbT#P#H#JbGbGaoao#J.Ebo#JbTbT#l#qaX.A#k#a#aaR#aaRaR.PaR.P#4.P#a.A#4.E#y.K#p#z.E#9ao#9aobo.ra9#o#Rbo#Y#3#kaM.zb#bub9b9az#ebO.Vb8#Mb7bW#a.A.Ab#awb9b9azazac#saZa0.y#5#i#iaJ#n#Abt.0bv#C.tbt#i#daG#s.yb0.y#5b0aZa5aa", +"#6a0#x.y#5#A#W..........#W....#W..#W#W#W#A#5#s.v.F#e#P.G.GbTbU.S.p#S#Ma8.AbO##bQ.8#jbo#..E#X#ob9#h.4#H#b.r.E#zaoboboaF.P.z#yaS#q.A#q#a#l#l#a#a#4.P#a.P#4.P#k.A#pbSbS#y#V#9aoaMav.r.rbo.r#H#R#R#3#P#o#4aR#kaXa3awbCa3#Naz.Fb7bd#7aHbW.S.A.5bCbCb9#NbBbB#s.ya0#5aY.laJbtaJaY.S#nbiaJbwacbw#xa0b0a0a0a0.y.yabab", +"aHbx.y.ya0bxbt..bf....#Abyby........#W#W#W#A.laHa3ap.GazbT.lbgbv.0a8#daHb#.5##bXbX.3bUbUbT#X#X#J#m.T.u#HbGao.raxbobo#JaF.A#qbgazazbO.n.na3bHa1b4#8#eb4a3bO#8aR#cby#ybgbo.E#9bo#zboaxboaF#X.u#h#P.P.Pbu.n#8.q###ebEb9aza3#1.F#1.VbW#da..S#d#EbCb9b9azbBaH#5.t#naY.l#c#C.laYaJ.W#Cbzbwbw.0.0a0#s.0#5#s#s#x.Jab", +"a8.t.t.0#A.t.0aJ#A#Wbi#W#W#Wbf........#W..bib7buapazazb#bv#d#I.p#s#u#dbvbz##.B#jbp.1.IbG#Y#Ybr#o#k#P#mbGbo#zaoaMaobTbT.hbgaR#cbEb4b#b#bO#gbO#ea3a3#8.n#e#e#eaR.l#p#p#a#V#lbo#9.r.r.za9bo.Gb9#P#k.5.P#4b4#k#T#gaXa1.mb4.V.V#e.F#1#daYbk.v.p#0#EbCb9blaz#Na8#CaJaJaJ#naJaJ.WaJ#naJ#daJ.S#Ibv#d.0bx#Sbwaba0#xab", +"#n#A#W#nbx#A.taJ#ib6#A#A....bh#p#.bi.2.W.Wb#buap.GazbO#C.laH#uacbzbv#Ibv.5bA#j.3.ebq.8.3#Y#lbo.zbo.8#Pbj#zbc.E#J.r#J.h#obJ.5.A#ebE.5bCb9blbuawbCbCbC.nbCbCbC.A#qaJ#y.h.5bobo#lbo#J#VaMbqaMb9#k.PbOaR.PaRbH.n#g.naX.F#PbC.mbOb#.5bz#d#s#2.p.Ybv#EbCbCblap.GbW#y#CbtaC.2aJbtaJ.FaHaJaJbObOaH#I.0bxbw#u#u#s.0#2", +".2.2#WaC#i#A#WaCbibtbwbdbt#A#W..#Wbh..aS.P#8bHap.Gbu#qbvbwbkbk#ubz.5.P.5#g.n#g#G.e.z.U#Y.B###4#4.4#j.u#V.K#9#9aobobT.4apbubTaRa3apbOb4bOapa3b9bCbCawbuaz#gbOaMbgaSaM#c.h#3#j#lboaM#VaM#c#c.hbl#g#abOaR#eap#P#e#8.5.Aa3bCbub4apa3aH#I#sbk.0#i.SbJ#gbCbC#3apbjbO#q.S#q.S#7#CaJb4#Pbg.WbvbWbubwbx#C.A.5.5bOb#a8", +".W.2aJ#A#n#iaJ#Abi.2bWa3bv.Wbi#W....biaR#8b4#t.G#ebgbgbibx#IaZ#SbvaM.P#g#g.haM.laM#laE.daw#t#4.h#g.ObQbqbQbobo#zbr#YbC#3bT#caRa3b9bla3b4#PazawawbCblblblb4b4#gbgbg#c.K#Q#jbCbC#tbQ#lbU#kaM#cbubH#E.Pb4b9apbub4#8bO.Abvb#bCb9azb4a8#u#s#Sbx.tbt#qaM#obCbC#3apbH#g#y.S.A.l#q#ablbC.P#q.W.0#I.0#5bw.5.hbrbBbOaH", +".l.Ab7a.aJaJ#dbt.Wbi.h#P.5#C#ibtbi.WaM#8a3bE#O#e#l.E#.#W#W.t#Sbw.P.Par#obO#qbybgbz#e#e#g#t#Pa1#g.uba.IbM#m#Ja9#t#R#3.4#Gbg#G#kbTaM.A#q#qbvaMbvaM#q#q.lbgaM#q#y#yaM#kbg.EbUbU#k#o#k#kbU#g#g#Qbg#Razblblap.Gapbu#ebzb#bz.lb4bCblazbB#I#i.t#WaC.S#Cbg.A#jbCbCbl#8#8b#bT#ebl#4ap#Pb9aH.Abvbt#ia0a0bk#IaR.5aHbwbw", +"#y.l.AaR.Abe.laJ.W.E#8bHb4#7#A.WaJaMbO.nbHbHb4.PaM.W....#W..#Abv.A.h#8#g#laJaJ#C.5bua3#3bl#O#P#3.OavaWbQ.O#t#9#9bUbq.EbU#G.Ebo.P#8#P#e#8b4b4b4b4bEa3#g.nb4aRaS#caoaM#z.EbUaMbU#.#G#GaM.P#c.z#V#qa1blazap#3ap#ebu#e.5.l.A.Sa3bC#PbB#M#dby.Wbta.aJbebJ.A#8bCbC#Pb#b#bl#P#X#gbl#Pb9#ebv.l.lbxbxb0#s#ubwbw#d#5#x", +"biaS#q#k#a.WaJa.#c.l#8bubj#ebybt.h.Pbuapazaz#a#laJ.M........bi.A.h#obu#aaJ.A.l#Iapbub9bC#Y#m#mbj#9bM.ubM.c#H.4bFbnbU#G#G#z#z.r.haRbCbOb4bEb##8bE#ebO#e.nb4#k.A#caMao#GbUbU#G#V#F#y#laM.I#kbg#l#G#qbHbl#hb9blb9b4bBbubza.#q.la3.F.mbBbObv.W.W#q.Wbe#C#qaX.nbC.mbubu#P#e.5#Xap#o#8#e#gbvaYbxa0#S#6aHa8bz.t.t#5", +"aQbi#p#yaM#a#C.l.laMbu.h#obu.PbTb#apapaza3aR#qbgbibh......biaM.P#g.n#7bD.S.AbWazbBb9bCblbC#h#Dav.D.O.I#Jbran.Obo#J#F#zbc#.#zao.h.P#3.naR#k#E#Pblb9#Ob4#k.h#4.PbUao#z#zbU#z#GbU#l#QaM#l#g#j.haM#XbL#Q#ObCbCbCb9blaza3a3.S#7#7#qapblawap#o#l#..Sbt#C.SbJ#q#abOazb4.Gb4bH#Ob4.G#m#P#P#e.5btbw#da0#6.0#I#u#5#5#5", +".W#cbyaJaJ#p#y#C#q.h#H.ub5#R.u.h#o#o#o#eb#bg#q#Cby#y#cbfbh#q.zbT#l#4aJaJbv.Aap#ob9bCb9bC#h.T#9an.w.8a6bG.8bGbQ#G#lbcbUbU#z#z#zboaF.G#X#ea1bO#PblblbH#8#8#R#g#T#G#z#zbYbYaoaS#V#G.EaS#k#q.n.h#ka1#PaRaMapbCblb9bCb4a3b#bO#a#4aRa1.Fb9bl#ebu.A.A.lbJ#a#g#a#4#lbO.Gb4#e.G#P#m#3b9#m#P#P#ebvbzbk#s#Sa0.y.ybx.ybx", +"byaJbyaJ#y.2biaSaFbr#Xb5#H#X#Hbj.u#8.h.P#l#4#q#Q.lbD.AbD#G#4aR#g#4#.#y.2aJbE.P#e#XbCblbCbl.z.I.O#L.u#j.ubQbj.EaMbobUbU#zbcbcbcav#J###R#8#o#TbO#g.B#8#g#X#8#obo.EbcbcbcbmbU.E#z#V#X#lbg#kaR#8aRbObubH#aaM.GbCbCap#e#jbL#k#T#a.5b#bvb4bCaz#EbO.5b#.nbla3#l.PaMbTbj.G#mb9b9#m.G#m#mbjbjb4bWbw#dbxa0b0b0.y#5#S#s", +"bi#c.2.W.SaJbsaSbT.4.6#X#H#H#Y#Y#Hb5#Xbr.P.PaSbgaSaS.5#c#q#4bQ.PaS.2byaJ#8aRaM.EbT#8bCbl#a#9#Xba#bba#j.u#tbo#J#J.h.EbnbU#zbcbc#z.z#lbT.5bO#l#8b4bubHbo.z#o#PaM.E#zbYbU.Ebc#G.E#T.P#g#l#lb##kbub9az#e#k#q#qbEb9apa1#EbTb##8.n.z.A#c.AbuapazbO#gbE#e#T#8#g#8b4#P.G#3#3#m#m#m#Z#Hbrar#o#8.P#nbx#5.yb0#saZa0.0#S", +"#c.lbybt.W#paJbg.P.4bT#Bbrarb5#Hb5b5bj#Y#R#X.4buaMaS.PaSaM#4#a#4#.bfaSa1bO#EaM#cbo#e#P.5#la1#t.w#h#P#R#b.z#JbQ#JbQ#J#zbYbcbUbY.E.r.hb##jap#qb4bCbCb4aM.hbT#X.A.EbUbUbUbY#G#G#J#kbQ#k#k#4#q#R#eawblapbOaR#q#q.Gap#TbubL#g#kbuap.n.A#abJbO#e#ebHbO.h#8#P.Gb9#3.GbC#mb9#Y#Y#faray.9arbrbTbzbt#5a0.ya0#6.pbk.Y.p", +".l#qby#y#C.Wbi#cbo.zbQ#B.4#Jbrar#H#Xb5#H#Z#mbj#Hbr.P.4.E#qaM#Gbg#p#pb4bC.nb4bg#cbTbl#kaJ#R#t#jbCb2bC.T.3aF.4bobQbo#Jao#.bUbUbUbq#GaM.z.5bHb#.5#e#e.4#l#8bT.P.EbU.KbUbUbUbU#zbo#kaR.n#4#e#k#a#3bl#Pawbu.P.A#l.AbHa1#g#kb#b4#P#Pa3#kbO.PbgbObO#o#8apbl#3#3bCbCb9#Z.G#Z#Xararar#BaraFbo#laR#C#ibxbx.0bkbx.0#s.p", +"bE#7.W#C.laJ#cbgbU#z.zbMbFbrbraF.6ar#Z#D#D#m#m.Gbj.ububobgbgbgbo#G#8bOblbC#8.5bobj#g#q.z#T#TbG#Ob2#b.4#l.8bobQ.4aFbo#zbqbUbU#G.K.EaSbo#l#l###7.z#4.zaSaM#l#laSaSbU.KbU#G.E.zaMbTbT#l.P#Tb4.P#Tblaw#P.5#a#aaR.SaMap#O#g#eblblaR#gb4.G.5bgaMap#PbC#Pb2b9b9#m#3#mbjb5arb5#B.ubr.D#J.r#zb#b4.l.0bxbx#ibWa.bWbW.v", +"bE#8a.bJ.Abg.l.PbTaS#z#V#Jbo.D.4#Bag.6.u#D#m#Z#Z#D#D#m#Y#X.P.EbTb4ar#k.hb9blbHb9buaM#l.h#q.PbQ.8#bbX#lbo.4.8bo.4bQ#J.r.rbU#pbUbU.KaMbgaS#T#8###R#T#4#V#TaF#l#G#.bUaS.K#.#l#gbg#caM#4#4#o#k#l#qbTb4bObH#g#a#laR.lbg#Obl#PbC#g#g#k#ob4#8b4#3#3#Pb9bCb9b2bC#Z#Har#f.uayar#JaFbobo.E.zbobub9bW.l.l.S#Cbz.Fawawa3", +"#a.5.A.A.AbvaM#o#T#9.I.K#zaoboaxbobr#Bay#f#Zb5#mbj#m#m#Y#m#mbj#Xbj#o#Y#P#ob9b9#RbgaM.hbT#l#####j#TaMbQ#k#Rar.4bQ.r#J#J.zaM#F#.aSbU#G#l#q.PbAaRa1#TaMbU#l.z#laS#F.KaSbU#V.P.z#G#caM.Pb4bu#8.5.h.z.5a3#l.FaR#4.PbAbg#q#j#3#8.G.G#e#o.G#m#mb9bCbC#3bCb2b5bj#Xar#H#LbF.DaxavboaM#G#paSaMaM#eaz.l#q.A.AaR#7bLbWaV", +"aJ.lbeaJbg#paRb##GbU#paQ.Kbn#Vao.E.Dbo#Bbr.uaear#D#D#Z#D#D#mbj#m#Yb4#P#3#b.G#8#l#l#8#g#k#l#lbo#8#G.3.P.8#o#H.4bo.z.z.4.h#z#V#pbUaSaS#l.E.P.5aRbT.P#lbg#G.zaM.K#.#p#.#GaM#l#caMbg#G.A#T#8#k.PaM#aaS#ab#aMbJ.Aa1#Xb#.zbg.z#8#Y#t.u#P#mbCbC#mbC#3#D#H.ub5b5#H#BaraFaxbZav#9.r#laM#caS#p#c#l#o#8bTaRb4b4azb##a.S", +"bt#q.W#c#q#c#TaMbg.E.K.KbU#z#B#zbn.E#9#Jax#BaF#Bb5#f.u#f#D#D#m#m#Y#Ybjbjb5.h#J#l.Pbo#e#XbobQ.hbq#Qbo#9#9#X.3aM#J#JbQ.hbo.4.E#G#.bU#.bgaM.hb4#8bO#gbT#l.4#R.E#.#.aSaS#l#laM#4.zbJ#k#g#4.h.5#lbgaMaM#G#a#g#lbOb4.P#laRbQ.4#R#Hbj#X#3bC#3b9#m#Yb5.u.u#Hb5bra6boaFbZ#z#z#z#VaM#l#QaSaMaM#laFbTbT.h#g#8.FbCapb9az", +"aJbvaJ#p#c#y#y.C#p#pbf#..K#G.u#V#F#FbU#V#lboax#JbGbFaybr.9b5#maq#m#m#D#Ybj.O.u#T#lbTaFbH#X.uaMbo#Q#.#.#V#kaM.z#X#j.4bobT#X#JaMbY#.#.#..A#oaz.GbHb4#XbT#j#X#c#.#paS#Q#q.5###c#q#T#k.5#laR#k.P#c#qaM.P#p#4#g#R#####k#j#X#R#Y#H#R#D.TbC#D#Y#Har#f#Xayay.4bQ#J.rav#VaS#Vbo#l#VaM.r#lbq.K#zboaM.hbTaRb4#t#Pazblap", +"aJ.l#yby#cbhbh#.#y#.biaM.E#J#o#VbU#F#p#paM#9#GavbQbFaFaybGae#Zb5#Z.G#mah#m#Y#k.r.h.hbT#Jbo#V#V.zbo#F.CaM#z#9bQ#g.u.z.r#Rbj#JaFbo.K#.#.#l.5#ea1b4#R#8.hbT.zbU#p.K#.bT#kaMaM#q#G.P#8#kaMaRaM.h#qaM#k#XaM#.aMaR#l.h#o.z.4#H#bbj#H#Zb5#m#Yb5#Hbr.uay#JaFa9aobc#Vav#G#V.A#T.h#kbQ#J#9boaFbG#JaM#j#8.h.A#gbz.A.laR", +".W.lby#p#cbhbSbhbS.l....#.#kaF#z#VaS.CbhaS#F.CbU#z#la9.4bFbray.u#Xbr.ub5#D#H#R.zbobTbobo.D.raMaM.E#9.z#laMbg#l.z.z#..zbTbT.Gbr.rbU.KaSbg#k.h#g#g#j.8#j.z#l.K.C#c#l.P#k#laM#c#yaS.P#qaR.AaMaM#8bo#o.zaM#9.4.P#l#GbjbQ.u#Yb5.uay.4#B.ub5ar.u.4aFbo.r#zbqbU#F#VbgbS.C#q#g.n.z#l#9boax.4brbQbo#q#q.l#qaR#a.P.5bu", +"#CaM.lbgbo#cbgbg#c#lbibh#yaF#R#J#l#y#pbhbhbiaQ#y#paS#zao.r#J#Jaybr#o.Da6arbGb5bT#o#Jboaxarbo#9bnboboaM.K#V.zbT.PaMbg#..r.rbr.6#BaM#.#p#F#kb4#O#O#R.G#Y.O#V.K.C#Gbo#gbobgaS#..l#c#c#4aRaMaMaM#q.P#k#VaM#JbG.z#Vbo#b.4bG.u.4.D.DbFaFbFaFbTax.r.r.r#F.C.K#GbsaQ#y#y#cbJ.h#o.hbQ#9#l#9bq#G.E#4bgaSbJ.A.5aM#abOb4", +"aJ#q#y#pbgbSbh#.bgaM#yaSaS.z#ebobo#.#y#pbh#p#y#y#y#.#G#.bUavao.r.r#Jax.4.DbF#obo.G.4#J#B#B.u#J#l#z#V#G#G#caM#4#lbT#l.E.Kbo#J.6.haFaM.K#paR.GbCbl#O#h#3#t#G#y#GbT#8bO.5#.#.aMbg.5.P#c#l#qaM#aaM.E#lbo#B.4#k#J.r#9#m#Rbo.D#J.D#J.rav#9a9.r.r#z#z.EaM#V#G#y#p#c.l#G#V.z#j#X#R#g#Q#.aS#G.zbUaM#laSaJ.5a3#a.A.P#e", +"aJ.l.W.Wbg#pbU.K#c#l.CbSbUbTbr.P.zbgaS#p#y#caJ#c.l#c#Q#..K.E#G.Eao.Eao.Da9bFbQ#kbj.r#J.D.D#B.Dbo.raobq#z#.#c#Q.P#a#lbo.K.EbT.D.h.h.h.laS.A#e.Gbu#X#t#P#g.E#paR.G#e#j.5.5aM.A#l#lbg#cbgaM.PaM.E#9.r.rbQax#J#9#z#9brb2aFbo#J.rbZavao#z.r#z.r.K#G#z.z#4bg#Q#q#Gbe#yaS.z#R#R#R#8aM#Q#G#4.P#l#4.P#l#cbJb7.A#7#7.A", +"aJ.l.W.WbzbY.Ebc.EaxaI.MaI#Jarbr#JaS#ybhbibhbh#.#caSbg.Wbf#4#lbT#Jao#zao#9.rbo.O#j#9aoavax.DaxbZaxa9ao#zbU#GbgaMaM#q.AbobT#o#8#gbz.Ya..A#7.A##aR#k#aaR#gaR#qaR#gbO#8b4#kb#.PaM#l#qaMbUbg#G#zaMao.rao.rao#zbc#zao#l.T#o.zbo#zao#l.z.8bQ#lbT#pbg.E#g.z#laS#y.eaS#p.e##.O#t#Oa1.z#qaM#l.PbT.P#4aR.P.Ab7#7aH#E#I", +"bzbzbvbg.E.E.Ebc#zaobYbYbSaFararbTbU#paQbSbh.2#c.lbg#q#ybh#4aMbQbrbG#Gbn#V.I#G#oaM#z.r.rao.xaobZbZbZao.rao.E.EaMaSaMbTbO#gbOb4b9b8aH.v#NbE.laS#c#yaM#Q#8azbObuawblapb4.hbO.5.A#lbg.E.EbUbUaMao.Eao.xbcbY#w#zbc#zbqaM#R#VaM#z.C.4.4bo.E#lbT.KaM#q#8.zbJ#G.e#FaS#F#G.z#t#t#O#X#laMbgbgbvbg#c#c#l#caY.Y#CaY.Y#C", +"az#8.hbzaMbU.W#p#p.EbS.MbS.Ebr#o.P#GaS#p#p#pbybgaM.laMbgbh##.h#8#o.4#9.K#F#G.zbQ#GbU#Vaoao#zbc.xaoao#zao#V.E#z.E#laM.P#kbO.h#ea3acaHbW.Aby.C.C#c#Q#V#c#y#caXa3b9awbC#P#E#o#4#l#laMbUbU#zbc#zbY#zbUaobc#z#zbcbY#G#G#G#kb1#laS.Kbr#j#X#R#X#8#c#4#k.z.P###4#4#4.z#4##bTbH#O#P#taMaS.W#pbSaS#W#.bg#q.l.A.l.Sbzbv", +"#oaMaM#GaM#p.WbUbU#laSbU#..r#RbTbQ#lbqbU#y#FbSbg#Q#caMaM#y.8#8#X#R#R.h#p#Q#G#G#9aM#9#GbUbUbUbcao#z#z#z.Ebc#z#z.E.E#z#l#k.5#ea3bWbzbLaJ#CaM#4#Q#l#X#l#4#c#y#y#Gb4#PbCbC#g#8#l#lbU#.aSaSbUbUbUbcbnbn#GbUbU#zbcbUbo.z.zaX.z#l#GaS.u#j#8#j.8a1#VbJaM#4aX#4#Q#Q#4#k.z.zaR#tbH.G#eaM.WbU.WbSbgaSbg#qaMbgbz.5.5bTaM", +"aM.EaM#z.zbUaIbS#p#zaQaQaI#z#J#JbQ.zbQ#X#gbTaS#caM#4#q#.#p#l#9#lbo#l.4#Q#p#9#4###4.zaM#G#GbUbUaS#.bUbU#zbUbUbUbc#GbU.zaMaRb##gaR#aaJby#.#c#TaMbQ#X#4bQ.h#F#c#F#Q#X#X#e.z#lbg#GbU#.bUbn#Fbn.KbqbYbnbnbU.Eav#l#GaM#4.z#k.zaX#G#V#XaX.IaX.z#kbg.zbJ#g#k#k#j.Gbl#3#O.z#kbH#b#P#X#VbSbS#..WbgaSbgbg.AaMbo#lbr.5.5", +".E.zbc#V#9#zbY.Kbc#z.R.x.xao#Bay.4boaS#GaS#c#.aM.PbTbo#zaSbo#k.4#G#Q#j#4#F#G#Gbg#QaMaS#G#l#laM#.#.aSaSbU#FbUbmbnbnbn#FaSbg.P.5ap.laJaM.Pbg.z.4.zbQ.4#j.z#9.h#G.KaM#O#kaM#..K#paS#F.C.K#Fbnbn.x#9#QbU#V#l.r.z#z#G.zbp#4#l#QaS.z#j#G#k#j#T#R#j#8aMbT#g#8#gbTb1.z#G#l#TbH#b#ba1.3#l#G#g#o.5#qbg#caM#k#TbQ#e.Tb9", +"bo.hbTb5ar#LaxbZbcaTaxag.9afag.6.4.z#G#paQ#y#paSbg#l.P#l.KaM#J#VaM#9#j.z.z.zaMbUbo.z#Gbg#caS#GaS#FaS#.bU#.bnbUbqbn#F#F.K#c#..5bu.W#pbgbT.ubT.rbQ.zaM#R#j#jbQbn.KbU#P#k.K#y#.#.aS#G#V#z#G#zbU#9#9#9#9#V#V.E#l#kbo#gbH#o.8#k.h#l#j#G#l#l#Q#T#QaMaX#T#kbQ#k#k#j.G.8#Q#T#b#O#O#t#j#O#9#g.G#8bO#q#qaMaR#k#P#tbC#h", +".AbT.A#o.8ar.Dalalalal.D.NafbFay.8.z#G#c#yaS.e#qbg#l#laMbUbo.z#zbUaM#k.z#Vbo#laM.z.4#l#l#G#y#G#c#p#p.K#.#FaS#F.Kbq#G#z.z.AaM.P.WbSaM.r#o#R.h#obobo.h#j#o.3#V#9#VaQbT.G.z.h#T#l#Q#QaM#G#J.3#VbQ.8bTbQ#4.z#9.z.u#l.8bC#jaX.4#o#9#X#G#4#T#k#X.P#k.z#kbQ#k#8bj#Y#b#T#4###t#t#O.O#V#Q#9bJ#k#gbObJ.A#aaX.q#Oa1a1#h", +"#7bO.Abv#g.3bQ#JbFbF.D.D.4bMbF.4#kaR#q#4aX#aaM.AaM.PaR#l.zbTbTbrbobQ#R#J.EbQ#J.rbobTbT#J#l#GaM#Q#GbUbg#G#G#G#Q#V#G#l.z#RbjboaMbS.KbT.hbT.4bo#GbgbU#9#l#JbQbQbQan#Gbg#P#kbl#8.h#4aM#4aM#l#T#G.8#o.z.z#l#9bQ###jbQ#o#j.8.h.3##.z#t.4.3#X.B#j#l#k#l.z.zbo#3#R.T.TboaMaR#P#P.TaPbq#Q#g#baMa1b4bL.Aa.bLaV.m#ObL.m", +"aOa.bz#qbJ.h.z#Ga9bG.haFbQ.z.8#j#g.3bgaX#T.nbL##.L#lbT#l#z#l.8#X#X.u#Y.4#J#J.ravbT#Jao.z#l#V#G#lbqaS#z#Gbg#Qbg#c#Q#Q#qbobTaM.E#.bg.Wbo#JaM.EbU#G#V#VaS#lan.4av#G#VaSaR#4.h#T#laM#Q#GaMaM#4#V###J#l.8#9#lbo#l#Ran.4#J.z#J.4.ubQ#t#8#g#8#X#8#l.h#4bo.P#kbC.ubC#h#Q#qbp#Obl#P#R#9#4#jb9#8bLbEbOa.#abJa1awa1aV.m", +".S#ya.aR#q.A#CbD#qbL#q#qaM#a.B#8#TbLbJ#l#c#q#q#lbgbJ.zaMbg.r#kaF#k.4#H.4#Jbobo#J#J#J#lbQ#J#l#VbobUbqbU#G#G#Q#y.C#cbgaM#8#R#Jbo.MbY.P.P.rbTaMaIbSbh.M.K.I.4.8.4.3aM#cbH#gaz#8aR#qbg#c.e#laM#G###4boaFaM####an#jbQ#obGbX.4.z.z.z#Y.O#X#X#j#k.C#4aM#l.z.z#R.4#R.u#.aM#T#Obl#P#R#l#9#T#t#O#4#7bLbWbWa..n#N.Z#7#t", +".Abg.A#Ebza.bv.l#0bL#qbv.SaMbA#8#T#TaMbJ#QaR##aX#q.P#4#l.E.z.h.u.uar#Xbr#J.4bGbG#obG.z.zbQ.z.z#4#V#G#G#V#Q#q#ybibD#cbg#j#3.PaxbS#..AbobTbo.EbcbU#VbU#V#VbT.cbQ#JaS#pbH#gb4#g#4#Q#c#c#p#4bJ#QbQ.z.z.zbo#T.4.z.zbpbG#X.ubGbo#9###O#R#R#R.O#k#p#4.z#4##.zaM#G#paS#GbJ.5.d#O#ba1#l#l#8bH#8.n#qa.a.#7aRbzb##E#a.n", +"#q#abJ#a.A#aa..l.AbJbv#q.lbg#g.n###T#QaM#Q.A#QbJaM.z#4#l#QaM.4#X#X#o#XbG#V#V.z#J#kbQ#Q.eaM.I#l#9bq.e#F#caS#G#ybS.C#p#GbT#P.4.EbS#c#..Ebobo#J.Ebn#z#V#V.r#JaF.1bq#caSb##k.n.zbg#p#p#p#y#p#p#F#GaM#V#VaM.I#4.I.e#JbGbXbG.8a9#Q##.d#j.8.B#g.zaS#4#4aXbT##.z#Q.Ib1.zbJ#TbE#O#P#e#Q#la1apb7bLbWaJ.p.YbWbza..A.AaV", +"#qbvbg#c#q.l.WaJ#q.Lbg.l#caM#g#g#T.4bJ#4#4.I#Q#laX.z#4#4bU.E.4.u.O#o#t#j#Gbh.Q#y.I.X#9#4#9aM#Q#Q#G.e#yaS#.#c#c#yaM#QaMbT#gbT.E#p#p.AbTbT#o#B.r.xbnaobobM.3bF#J#J.C#p#k#c#g#kaM#yaS#caS#cbq#ybU#Q#G#V#G#V.I.X.I.3.8.cbG.3#Vbqan#O.B.B#Ra1#kaO#Q#q#cbD#c.L.L#c#c#y.LbLb4b4bHbuaMbTap#ha1b7bW#0aY#Ib#b7#7bJa.aV", +"#C.S.SaJaO#Q#yaS#QaM#4.I#Vb1###kbQ##.z#l#l#Q#Q#lb1.z#4#9bn#F#k#j.8.4#gbp#9.Q#G.fbAbA##bA##.q#4bJ#9#Q.e#Q#G#V.E.E#FbU#GbTbT.P.5bobS#Q.EbQarbr#B#Jaxa9.4bG.9a9.1#F.K.h#e##.h#8#c#y#y#G#GbQbQ#G#l#l#G#G#F.Lbq.fan##an#lan#9bq#Q.q.O#kbA#taP#gb1#qaO#p#K#y#K.L#y#Q.XaXbp.s.n.n#8#g#R#8.BbL.Z.Zam.S.YaVb7bA.YaAaV", +"aYb6.S.SaO#Q#QbJ#Q.f#Q#Q.f.f#QaMaMb1#4b1.XaXaXb1###T.z.z.3#la9#9aM#4.z.z#Q.b#Qb1bJb1aX.X#Q#c.I#Q.e#c#y#Q#Gbgbcbq#zbq.EaM#kaMbgbO#y#QboaF.u#L#Bay#B.4#B#H#H#J.1#9#p#Y#l#V#c#GaS#F#p#p.K.K.C.K#z#9#Q#V#4#Q.Q#c.I.I#V#zbqbq.b.QbJb1aX#QaOaMbJaX###Q.L#q#QbJbJbJbJ.XaA.Xb1.qaX.X#4.X#4.q.XaXaXaA#0#0#0#0#0#0#0bL", +"bebDbDbDbD.bbD.ebDbDaO.b.Q.L.e.e.e.e.ebD#c.LbD.L.L.Lbq.L.I.e.ebJbJ#9.L#cbq#G#F#c#laM#QbJ#Q.L#Q#l.e#c#c#zbUbq#Vao#z#z#z#z#GbU#4.PaS.K#p#g#zar.u.D#JbM#BbF#V.4#z#Fbq#Y#g.K#FaSbq#GbU#G#G#p.K.K.C#z.K#y#9.Q#p#9.I#V.I.z#G#F#F.Q.e#K#q#Q##b1#cbD#Q.LbJ#Q.L#QbJ.LbJbJ#Qb1bJ#4b1#qbJbJ#4#0bJaAbJaA.f#0aA#0#0#0.Y#0", +"b6b6#0aObe#K#K#Kbe.QbDaObDaObJ.I.fb1.bbDbDbDaObD.b.e.e.L.e.b.3bJ.L#c.I##aM#9bU#Gbq#c#G#c#G#c#9#caS.e#Q#zbq#zao#Vaoao#zbn.KaM#k.zbUbU#p#.ao#RbGao.uaoav.4#zbqaIbn.r.8ba.4#F.K#z#G#9#9#zbq#zbU.Kbq#F.Q#c#G#V#G#p#za9.I#G#G.Ibq#Q#T#Q#Q#c#####y.Q.L#GbD#y.bbebs#K#KbD#Q.nbAbLaXbDbDbDaObD.jbe.j.j.jb6aAam.Y.Ybk", +"#i#iaY#CbDaJaJbebebebyby#K.C#l.z.z#4#ybsbybebe#QaO#Q#4#FaS#y.5#Q.eby#Q.8#9#G#Qbq#F#V#l#G#4.zan#c#F#G#9#9#9a9boavav#zbU.K#GaM#V.z#4bU.MbU.KbYbnbU#Jao#Fbm#Fbn.C#F#Jbn#9.Ibn.C.C#F#z.Ebo.r#V#VaoaMbU#pbn#G#l#9bn#9#VaSbq#c#Q.ebJ#j.I.L#p.I.3bJ.C#9#T.qbJaM#Q#pbybs#y#Q#Ra1bLaXbtbe#i#n#5#ib6b6a0#iaY.Y#ubk#ubk", +".pbx#n#i#naCaJbebyaJbyby#pby#laR#laXaSbJ#7#qbL#ebJaM###F#c#GaR#q.CbsaS.BaM#G#J#l.z#4#QbU#cbqbU#z.r#JbQ#J.r.r.r#z#zaSaI.K#G.r#l#g#g#VaS.K.CaQ.MaQ.M.M.M.MaQaI.Kao.3#V#VbUbq#F.C#FbU#z#V#lboaFaF#JaM#V#GbUbnbU#p#V.h.8#g.4#l#F#4.8#yaS#c#k.8#9.C.I#gbQan#l#4#Q#caS.Ka9.O#R.h#4.S#C#Abe.t#n#5bx.y.y#i#i#i.0#2bk", +"#Sbx#5bxbt.tbtbe.l#a#T.hbTbT#JbT.zbTaS.AaR.L.A.n#4#GaM#.bhbS.P#k#q#G#4#j#4an.hbX#g#gbQaMaM#J.4#o#H#R#Xbr#J#9#9#z#FaQ.C.EbU#Gbg.E#G#l.MbUaF#9bm.MaI.MaI#z#J#zbfbnbn#G#Gbq#.#z.KaQbUaSbU#Vbo.4ar#obGaraF.z.r#Gbn#k.4#k.4bp##bq.z#X#l#GbQbQ#l#F.C#VbX.4#k.z#kbQ.z#la9bG#H.O.4.4#j#j.l.5aR#7a.byaJaJ.W.laJ#d#sa5", +"#iaY#S.paY#sbWb7.mblbC#R#T#o#J#T.4#JaS#c.A#q.A#g#4bU#.#paMbU.5bT#T##.u#j#9#l#G#4bo#k#j#kar#X#Ybj#Hb5b5brbo#zbU#F#z.C#p#G#GaS#G#l#J#G.C#F.C.rao.C.KaQ#9#9aI.C.K.K.8bobUbU#F#GaS#F.K.K.K#G#z.r.h.ub5#H.uarbG.4#JbG#k.z.z#G#l#G#l#t#j#j.8#oaFbq#4#z.4#J.z#9bo.z#9.Kbq.4.w#H#B.4ararbobU.5brbT.E.E.E.h#g.5bvbw#d", +"aY#IaHac.HacbdbEazb9#h.O.4bX#kbG#k#g#caM###a#kaR.zbo#9aQavbU#X#RbH#R#t#g#9.I#V#k#g.8#Rb4#Y#Xb5#H#farbGaFaobUbU.K#pbU#GbUaM.E#G.r#m.z.KbU#G.CaQaQ.M.MaI.K.K.KbnbU#kbU#FbU#V.K#FaS.C#p.C.KbU#z.zbFarar#Hb5#Rbj#R.hbQ#k.8aM#9.Ebo#t#mbH#H#t.u#G#9a9bQ.z.r#Vbo#J.EaI.e.8#O#t.8.4#o#o#Hbc.r.6bTao.Eao#f.9b5#B.h#q", +"#7#E.vaHa#.H#1aV.mbl#h.8bQ.4#k.B.4.4#Q#G#4aR###T#k.zbobq#G.z.8.PbQ#k#obG.z.z#k#o#g#objbj#H#Y#f.uar#Bax#z#.bU#G#Q#paQaMaMbo.A#Jb4#PboaMaobq#z.Mbf.M.M.M.M.KbUbUbU#J#p#F#GaSaM#G#pbhbU#zbU.K.K#V.rbo.6.u#f#H#H#R#j#kbQ#o.8.h.rbTbT.8bG.3bQ#oa9.r.raF#Jbo#9#J.D#9.K#c.B#t#t#obQ#o.har#obcbr.6aobY#waLaL.9#f.uar", +".F#7#I.v.Y.pa##7awaPbl.3an#k.3.8.8.8#9#Q.3###k#k.3.z#Ja9#z#k#obo.8.8#o#o.hbQ#9#4#R#R.Gbj#Haray.6.D.rbYbY#F.K#p#laMbJ#laM.h#lbr.G#H.E#l.r#lbY.Mbf.M.Mbf.MbnbUbUbUbo.8#o#l#VaM#GaSbqaM#F#p#F.KaSbYaoao.D.4#o#Y#H#R.4.B#oaM.z#o.4#Xbj#t#o.h#Xbo#4#J.3aF#J#J.4aF.4aF.zbX.G#t.8#k.4aF#o.h#Jbgbo.EaM.E.6#Zaeae#Z#f", +"bOb##7bW.v.p.Yama3#O#8aX#4###k#j#obX#Q#Q###7####bG.I#BbQ#9bobX.h.u#o.4ar.O#Y#HbQ#R#t#Xar#8ar#J#J.rbcbc.CbYaS.C#c##.5.zbg#l.P#YbC#J#9bQ.r#G.K.C.M.C.M..bf.K#z#V.r#Gbj#bbQaM#z#Gbobo.EaQaQ.r.C#FbqbYbcaoax#J.h#X#j#o#R#k#X#bb5br.u.h#8.ubX.Oan#J.3bQbo#JaFaFaF#Jbo#J.B#Y#O.u.4.hbrbr.4bTbU.E.Abo.raoae#f.6#fb5", +"bO.FbWbW.v#7.pbW#N#N.n#l#4aRbL#jbX#8.I#q#####T#k.4bqaF#Ja9#9bG.h.8#oarbj#b#baq#X#k#Y#e#o.h#J#J#zbS.M.Ebo.EaSaMaM#l#k.zbgaM#XbC.G.r#JbTbo#V.K#p.M.Mbhbfbfbq.EavaM#z.4#Y#o#GbU#Qbo#4#VaSaS#p#V#lbY.M.K#z.Eav#JbQ#T#j#X.4bH#mbjbG#H#R.u#g.4#g.zbQ#kbQbn.I#z#J#J#J#z#zar#D.O#Baxa9#J#JaFboaMbSbUbgbzbo.E.6brarbj", +"bJ#aa.a.#7.v.Y#7#M#EaV#4#7#k#k#g#o.u#9#Q#l#Q#l#l#oa9#B#BaF.4#8aF.hbjaq#baqbj#H#taFbj#obT.z.r.MbY.MbYbY.E.4bg#l.PaRaR.5#oaSaMbT.4bobo#J.zbo#V#GbUbq.K.Mbf#G#z.r#9bo#Gbr#k#VboaMbT#l#V#l#G#G.z#F#pbmbfbYaI#VbQ#9bQ#R.4#j#H#X#Y.4#X#b#t#j#8.O#k.8bQbQ#V#Vbq#9.4.rbqbn.u#Yar#JbZboax#JaFbT.EbgaJbzaM.h.Abg.5bObr", +"bzbLbW#a#7#I.Y.S.Y#7#7#aaX###T.8#X#j#l#lbo#G.K#.bo.D.4#Bayarbj#o.u#m#m#H#Z#R.uaraF.8.hboaM#GbU#pbU#cbU#k##.h#q#k#8aR##.z#q#G#zaMbTaF.h#J#l.E#G#4#GaS.C.M#z#z#9.r#z#9#V.4.zaMbQ#l.z.h#Q#V.z#9aM.C#9bn.K#G#G#9#k.r.u#l.4#oar#R#B#X#X#j#o.O#t#o#R#j.8.z.r#9aoaF#zao.r#X#X#oaFbo.r.PboaF.P.E.EbSbv.P.P.P.E.5#X#e", +".A.Y#7a.bJ.p#7#7.S.Y.Y#a.A##.zbQ.4ay.zbU.KaS.r.4#Barb5#L#HbG#H.8#o.u#Z#XbGay#B#J#l.E#o#QbU#l##.z.C#c.z#kaR#k#g.A#o#T.P#caM.K#.bo#JaF.4aMaMbo#l#l.z#9.KaQ#F#F#z.r.r#z#9aF#JaM#V#V.8aM#l###l#Q#4#4.KaQ#l.3##bo.r#kbQ#Van.z.4bGaF#H#Y#R#j.u#X#o#t#Y#X#X#o.4.4bGbo#l#4#R#j#gaF.PaoaM.raMaS#.#.aJbtaY.PaR.AaS#k.h", +"a.a..A.p.S.Sa..v.paYa.a.bJ#4.z#J.4bG#J#V.z#X.u.u.uah#Zah#Hag#H.4aFaFbGar.DbZboboao#9#.#V#Q#Q#QbX#g.CbJ#g#g#Tb#.h.A.h#laM#G.E#VboaFbrbT.rbobT#l#GaSaS.CaQ#p.KbqbobQ#J#z#zbQ#9#G.P#Q#9#TbQ##.zb1#GaQ##.8#l#9bQ#9bq#z#Vbo#9a9.ra9.hbG.h.4#g#j#o#t#Y#j#Y.u#Rbrar#Jbn#G#k.z#4aM#9#GbUbg#lbv.WaJ.WaJaJbzbz.5bzbvaR", +".p.Y.pa.#da..pbw#1#S#C.S#c#p#obG#LbGbF#Jbr#H.u#H#Hb5.wae#BbFb5#B#J.4bobo.r#z#zbcbUaQbUaXaM#y#p#c.B#k#p.z#O#8#k#g#o#laM#J#kaS#JbT.hbrbobo.PbTbT.z#laM#F.K#F.K#VbQ#BaFa9#Va9aM#zbq#4.4aR.B#g#R#Q.C##bp#G.C.e.z.z#V.C#F.K#z#Gbn#Ja9bQ.4.har#o#T.u#X.u#Y#Rbj#oar#R.4.zbp#9.I#l.r.EaMaM.EaS.A.SbtbxaJ.lbvbz.5.S#a", +"bk#6#s#s.0.0#n.Ya3bdbJ#laS.K#J.4a6bGb5ahah#Zb5.9.9b5ae#BbMbo.9bG#9ao#V#zbcbU#zbUbo.P#lbo#4#F#p.C.P#8##bD#k.G#O#k.z#4aM.zbraM#JaF#XbrbT#l.h#lbT.h###kbQ#G#9bU#GbQ.u.4#Jbo#9.r#V#Gbo#4#k#Rb4.Ibh#T.B.zbh.K#F.z#V#F.IbQ.I.z#9#GaMbqao.z.4#X#j.z.8#k#j#j#objbXarar#o#X#R.B.hbQ#J.4bo#J.zbu.GaR#C.WbxaJaJ#C.0#C.0", +"#6#6#x.0a0.0bx#C#7#ObH#X#8bGbG#L#Za4#Zb5b5#D#Lag#B#BayaF.Dbo.9.4avbn#z#F#V#z#G#9.P#b#R#4#4#4#QbJ#g#g#X.4#y.8#8.z.EaMbU.raM.4aF#obj#g#J.Pbu#o#8#j#o#o.8.z#9aM.z#J#o#RaFaFbo#zbo#Gbg#V#4#j#4#y.h#T#k.zbq#G.I.Ibh#Q#R.8#kbQ#V.zbobU#.#z.3.u#o#o#k.4.8.4.3.u.4.u.O.uba#R.wbj#o#J.r.rbQ.Tb9#O.l#Cbg#C#C.0bw.p.Y#d", +"a0.y#Sb6b6#S#C#Cbgb4#t#tbG#H#m#Y.9.9b5ae#L.9#BbobF.DaF#Jav#9.4aF.IbqboaS#F.z#VaMaM#gbHb4#yaMbl#8.B#g.h#8#TbU#k.z#G#GaMaMaI.zaFar#X.4bo.PbTaM#a.h#o#o.P#GbUaMaM.EbGbjbGaF.raI#9ao#QaSaR#lbJbQ.8#T.4.8bQ.3#caQ#V.O#RbQ.z#k#k#G##aM#9.K#l.8.4.8bQ#k#o.8.8#o.8.u#H#j.w#Y#Y#Y#D#H.u.ub5#h#hb4#cbg.l.lbv#i#C.0#i#S", +"#6#S.0b6aY.lbJbL#O#bbabF#baqb5#Zb5ae.9ayagbF#BbF.4bQ#Janbo#9.3.ObQ#Gbn#9#l#kbQ#Q#G#c#j#O.n#c.z#t#P#e#j#g#R#g#paM#G#z.E.K.rbTaF#R#XbT.h#eb4b4#O.Gaz.G#Y#t#X#o.h#g#o.uar.4#JbU#z#l#VaMaM#ybT#T#k#g#o.8#T#V#F.z#t#O.4#Fbq.I#obQ#l#G#V#G.4#j.8#k#g#o#g#j.u#o#jar#o#o.u.w#H#H#Z#Y#D#Z#B.u#H#H#g.hbubO#IaY#d#d#S#S", +"#S.p#i#ibw#abubH#X#tbG#Haha4b5.9aybF#B.DaF.D#Ja9ao#9bq#Fbq.K#G.8.O#GaQ.e.8bQ#4#QaS#p#c#8.G#8.L.nbl#PbH#j#j#j#4bg#Vbg#9#zaFbr#H#earbo#8bCb9b9bCbC#3b9bCb9b9bC#h.haFbr.uaraF#Jbq.raM#Vbg#4#g#g#j#j#8#R.zaS#k#b#tbQ.C#p#F#l.z#gbobqbUbQ#g.8#o#T#k.3#j#X#R#j.O.u#oarbGb5.ub5#H.9#Zbj#Z.ubr#8.h.P.5blawaw.FbW.p#0", +".la.#a#C#q#7.5.n.8#jbGb5#L#Zag.Dax.Dal#BbFa9.r#9bq#G.Qbf#V#cbq.I#o#t#Q#l#QaM#4.z#c.C#c##a1#O#O.h.Bbl#P#R#abT#l#G.EaMbUboaF.h#Hbj#mb4.GbCbCbCbCbCbC#hbCbCbCbCbC#P.4#oarbGaFaFaobU#l#l#c#G#4bJ#g#X#b#kbU.8#h#Y#j#VaQaQ#y.8.z#9#G.C#l##.4.z#4.4.z#k#T.z.z.zbo.zbQ#JbFbG.Da6ayar#Zb5b5.ubr.h.hbTbzaz#Paw#NawaV#M", +"#a.Ab#.A.l.AbL#8bOaEboarayagalalaxbF.Dax.rav#z#9#FbqaQbh#G#Vbq#G.z#j.u.I#y.C.z.PaM#paX.h#kbHaw#Obg#T#t#T#laM#Qbg#V.EbSbT.4brbj#X#X.G#3#PblbCbCbCbC#hbC#hbCbCbC#PaFararar.4aF.zbU.E#VaR.LbgaM.z#R#TaSbGbC#P#j#k.3.e.C.I.h#9aQaM#gaE#l.z#G#y.I#caS#4#F#F.ebU#V#9#Va9bFaFaF#Bayb5ar#Zb5ao.4bu.5.4bu#8b9#O.mbCbC", +"bo.raM.5#laJ.5aV#T#e.8aFbF.DalaTaxaxaobo#Ja9#V.r#9.3#G#Vbq#z#F#V.4#Q#k.G.zbU#Q#l#TbH.haR#TbA#R#3#8#G.P#Rbg#G#GaMbgbTao.P#obrb5#X.4#l#o#Pbl.Gbl#P#3#3b2bCb9b9bC#O.rbT#oarbGaF.4#G#G#c#G#Q#GaS#X##bU.8b9#P#X#o#k#k#g#R.8#Gbh.Q#j#Obo#G##aM.eaM#G.e.z#QbU#G#z#Qbn#z#Ja9#J.D#JbFbrbGar#o#laMbo.Pb#aMbHbC#O#hawbC", +".r#J.Ebo.5bJ.lbL#E.n#g#4bFaxbZaxao#zbqbZbr#V#9#V#z#9#Vbqbnbn#9#zbo#V#kbX#P#k.KaS#k#j.n#X#j.h.h.d#Yb##c.zaMaMbg#Vbgbo.h.4br#ear#o.PbT#ebH#8bl#P#b#R#j#P.T#b#R#PbH.rboar#Xay#BbQaF#G#GaM#caSaM###G#k.G#b#o#8#jbX#o.8bp#lbs#Fb4#t.z#y.e#4#Q#F#y.Q#F#l.C#F.C#y#zbUbQ.4#z#Ga9.r#Jax.4.4bo#k#..5aRbObu.5b9#eb9b9aw", +".EaFaMbg#kaR.L.lbLb##4bo#9#9av.x#z.Cbn#9bQa9.KavbQ#JbF#Ja9.4aFaF.4#k#9#G###3bT#G#G.PbH#Pb4#X#T.h#jbH.haM#GaMaM#QbUaMbTbr#ob5#X.hbo.5#j.h#k#8#R#eaM#l#g#R#e#k#g#RaMao.4ay#X.4br.z#VaSaM#Q#GaS#c.8.G#t#R#8#o#R#R.G#j#4#p#G.O#O#l#G.Q#G#T###l##.z.z.8#l.z#l.8bQ.3#j.h#V#FbU#9.I#9bo#laM#l.A.l#ab#a3b#bOb4bl#eb4", +"bT.PboaMbg#k.5#Q#q#gaR.PbTbTboaMbq.Mbf#9a9#9aobo#JbFaFbrbF#B#BbQbQ#G.zbUaS.z#P.8aM#VbQ#P#P#R#X#o#k.8.h#4#l#VaM#GaQ.zbT#o.G.G#Xbrbo.PbTaR.h#4aR#j#G#VbQ#R#X#o.5bT.4.E.4ar#H.ubrbrbo.CaSaM#Q#9#9bQ#t#g.h.u#t#R#3#tb1aS#G#tbH#G.L#Q.Q#G.q.I#c.I#caS.z#y#V.zbo#9#R#J#4bh.C#G.I#9bo#l.z.z#qaM.lbzbW.VbObzbO.5aJbg", +"bTbT.5aRaM#q#q#a#paRbH.5###o#R.I.ebhaQ#VbobF.4bQ#BbG#BaraFaFaFbQ#J.z#l#9#G#G#J#P#gbgaSbo#P#h#RbQ#z#laM#z#Q#V.E#y#V#kbr#ebjbjar.z.h.h.P#4#k##.8#T#V#G#V#k.z#k#g#g.h.rbo#objb5.ubG#k#V.C#GaM#V#VaM.4bo.z#j#b#ha1#4#F#G#ta1#c#y.eaS.e#GaX#9#GaX#9#Q#l.z.8.8.4.8#k#9.z#K#p.e.I.8#j#l#T.P.A#q.A.AbLb#.FbO.5bvbS.W", +".5.5.P.5bL#4#q#4bJ#q#kaM#4#T.O#G.Q#F.C.Q.rbQa9avar.D#J#Vbn#z#VbQbp#l#9aM#QaMbJbQ.T#X#p#ybQ.G#k#l#l#R#R#Y.G#kbqaQ#l###jbj#R#X#gbobUaM#Q.z#8#t#8#VaS#V#FbT.zaMbgbo#k.rbTaFb5.Obj#X#j.zaQ.I.8bX#R#H.I#c#G#k#t#R#G.eaM#b.d#9.QaQ#Q#p.e.L.I#Q.e#Q#G#F#4.4#o#XbQ.z#J.C#c#c.Q.C.e#T.8aMaMaRaR.5.F#g.A.Y#1bdbzbibibf", +"bz#7#7#7.A#7#7aRaR.AaM##bQ.zbp#Q#V#Q#G#Fa9bQ.Dbo#BbF#J.r.I#Vbq#4.z.z.I##.z.z#4.e#4#P#X.QaM.PbX.h.u#Y#b#P#b#l#F#FaMbQ.h.B#X#R.4#lbgaM#l#g#o#j#j#k#G#z#.bQ.z#V#q.PbobU#J#o#Hbj#obGbQ#9#p#9#t#m#b#Y#X#Vbq#b.zbobq#Q#P#Xbq#y#Q#G#Q#c.Q#canaX#4b1.z.z.3#kbX.4bQ.4.3bo#l###4###lbX.8#4#gbT#kaR.5#8bE#e.H#Eb#aJ#pbi", +".AaR#q#qbLbW#qbva.#qaJaM#l.8ahbq#Qbhbq.Qbqboaxbo.DbQ#V#9#9#9.Lb1##.f#4###k###QaM#k###O#8.e#ybQ#T.z#J#Jan#l#G#F#Q#o#b#h#P.h.z#kbobo#l#lbT#T#o#o#k.rbobobo.E#QaM.z.P.zboar.4bX#H.T#bbG#9#FbqbQ.8.c#4#QbQ#g#V.e.z#baE#Q#yaSaS#QbJ.I.e.e###Q#Q#Gbqbq#V.z#l#9.z.zaF.I#GaM#y.e#F.8.4aM#k#laMbg#l.5b##E.A.YbWaM.E.E", +"bz#a.YbWbz.S.S.AaJ#qaM#T#taqba.kbq.e#V#V.r.rbFbo.rboav.I.zbp.e#Q.X#4#l.3#kbL.z.n#g#Q#4#O.u#c.C#V#F#9bq#V#z#9.C.z#R#hb2#h#Y.z#G#Q#l.z#k#TbQ.PbQbQ.z.zbo#Qbo#k.P#kbQaM#9#9aF#bb2b2.T.O#9aQbn.xbq#z#V#Q#V#V.e.I.GaE#GaM#Gb1#G#Q#4aMaM.e.3#G#Q.I#Q#V#V.I#9bobo.4#g#9.z##.Q#F.e#Q#G#4bQ.P#l#qaM.5#4aV#abW.AbzbY.P", +"#7.H.pbva..Y.A#4##.4#j#j#H#ObXbX#jbG.4.4aFaF#Ja9bo#JbQ.z#4#4aM.IbobQbpbQ.nbQa1#e#4.e#9an#t.O#F.I.za9#JbMa9#zbnbF#tb2#hb2#b.4aMbg#l.hbQ.z####.z#l.z.z#kbQ#JbT#kbQ#l#V.rbM#oaq.Tb2.T.wbQbq.Cao#9#9bo.zan#Q#J#O.8#GaS.C.ebU.Q#p#V#G#Qb1#k#4.z#T#k#4#Vbo#Jbo#kbGaE#g#g#j.B#T.3##bX#j#R#t#X.h.5bAbLb#am#7aR.5bv.E", +".S#S.l#da.#qbgaX#4#Van#JbQ.O#b#b#H#R#oarbG.3an#9.z.h#gbX.8bp.zbQ.3an#JbQaRbTb##4#Q#9#Q#9.I.uboa9#9an.Iao.rav#JbG.waqaqaqahbQ#Q.A.z#o##.z#k#Jan##.zanbQbQbQ#kbQbQ#k.r#9#waFb5#Daqaqah.4an#wav#z#Vbob1#9an.U.4bU.K.C.CbhbhaQbf#laQbh.K.z#G#q###4boaM#9bobo.z.8#T.O#RbHb4#tb4a1#t#j.G#O.Gb4#k#a#7#E#qb#az.5#lbT", +"#q#q.Abvbg.A#lan#J.1#za9.u#b.G#O.w#R.u#R#o.8.4##.3.4.4bp.4##an#l.3an#G#l#Q#caMaM#G#9#G#9a9#9.I#9.I#9avbVaoaI#V#o#Haqb2a4bG#JaMaM#l.z#4bQ.z.z##.r#G#l#9.zbQ#kaF#k.zaM#z#V.r.4.9aLa4ahar#9aIbcbn#V#zavanana9.3bpbQ.z.zbQbQ.3#k#k.8.8.zbp##.3bL#kbA#k.4.8.4#k.Obp#ea1#OapapbH#O.Gb4#Xb4b4.Gap.n#ab#bLbL#8.Pbo.P", +".Pbz.P.5aR##a9.3an.1bQar#R.G#b#t.O.ubX.u.uaEbXbX.8.8.8.4bpanbp.8bQ##an#4#laR.zaXanbQana9a9av.r#9.I#VbZ.xaobq#VaFa4a4#D#Ba9#G.E#l#4bQ.zbQbQbQbQbQ.IboaM.z#J#kbQ#k#k.z#VbobUbMbFaea4.9#Baobm.1aI.xava9a9an.I#Jan#F#F#4bp.e#c.O#T#X.B#jaE.B.q.q#TbA#g.8.4.3bpaE#8.d#RbHb4#tbH#ObH#t#O#R#8bEapbE#8.naX##.5#o#obr", +"###kbT#k.h.3#TbXbXbGbXbX.4bXbXaEbaaE#T.U.8bXbX.BbX.UbX.BaE.BbXbXaE.U.n.B.z#c#g#X.B#Van#Janan.ra9boa9bZ.xavava9a9a6agaL#LbF#FaM.zbobTbT.h#kbQ.z#J.z#J#l.z#J#kaF.4bQ.z#l.z#p#Va6b.aeag.Da9.xaxbnbc.xavavbM#JbM#9.C.Qbq.Q#c#Q.fbA#8.n.B#Oa1.U.U.3.s.O.BaE#t.d.d.Oa1a1.daE.O#t.O.OaEaE.ZaEa1.na1aE.U#8bA##aR#kbT", +"###TbL#q.3.q.B.U.8.8.4.8an.BaEaE.BaE.4.U.BaEbXaE.U.c.3.B.BbG.U.Bbp.3aE##.faS#Q#9#V#F#F.1.rbMbQa9.I.raU#w.x.K#zavaUaf.Na6.1#p.r#JbT#J.8.u.4.4.4.z#J##bo.zbQaF#k#T.h#k.z#lbUbYaf#v#vafaf#9bmbnau.x.xbM.Da9an#J.3.1#F.e#Q#G.L#Q.L.3aEbp.UaEaE.ZaE.d.s.3.BaE.Ba1a1.d.UaE.waP#b.daE.B.U.Z.Z.s.ZaE.Bbp.s.A#a#ab#aR", +"#a.S.S.L.SbebDbD#Q###q#G#4.3.f.f.Lb1#9#Qan.Xb1b1.I#lbp.4aWanan.8.q.q####aM.Q#F#9bX.4.QbMan.I#9bo#9avau#waobc#9aoaN.N.N.D.Kbn.zbQ#H.G#Y.G#b#bbj#P#m#b#b#b#P#b#b#b#Y#RbGboaM.M#wa2.N#UaobZauaI.R.x.x.xavax#JaW.4aW.b.I.e#c.e#c#Qb1bpbp.U.s.BbpaE.U.B.q.UaEbA.U.U.q.q.B.B.XanaW.8.U.XaAaAam.SaO.L#c#0.pama.bWbz", +"bd.v.Y.p#nbeaCbe#qbOaR#Q.C#F.e.ebh#G#K#p#y.Qbhbh.e#p#Qb1bq.L#p.eaO.Q.Q.L#G#9bq#zbQ#9#V#9#9a9#9avaobc.xaUavavaoavbV.NalbV.MbqbQbG#X#Hbjbj#H#Y.w#Y#b#t#b#b#b#Y.G#Y#b#b.u#kbo.M.R#v.gaBbMavao.xaoauaI.1bZa9.D#JaW.8anbq#Q#F#c.I#9.f.ebh.e.L.L.b.L.f.q#QbDbJ##bDb1.L.q.Ubp.C#F#Gb1.fbD#0ambdam#naCbeb6#6.p.Y#2.p", +".v.va..paYbe#0#0bebJ#a#qbJaX.Qbsbsb1.l#ybD#ybs.e.bbg.L#G.B.q#Fb1bf.Q.C.I#J.I.r.I#9.1#V#9#V#V#9#V.x.xau#wbc.xbc.R#r.N#vbM.x#J.8.zaF.Ibnbn.8bG#obX#o#o#o#o#o#o.e.Cbn.4.zaF.hbcaN#rbb#vaN.xbcbmbnauaI.x.1aoavan#Janan.f.K#G#l#l#4.I.Lbs#K.Q.e.LbPbp.f.fbDbD.L#K#Q.fbp.U.3bs#F.C.b.LaV.Ha#.Hac#1.paCa0ak#2ak#2#2", +"#7#IbkaAb6b6.SaA.Lby.l.A#q#l.L#Qbs#QbLbg#K.e.e.bbA#Q#QaEbA.3.La1.L.e.C#9.r#J#J#J#l.I#9.f#V#Q.1#z#wauau.x.xau.x#w#v#vafafao#J.4anaFbobq#z.4#o#jar#obXar#jbX.8bq#F.x.4#J.P.4bcbVa2ad.NaNaubmau.RauaIaubcaoav#V.1.Ia9#J.Ibo#JbQbQan#Fbs.Q.b.1.L.X.saX.faX.l.L#q#4bJbp.B.BaQ#F#yb1amamam#6#6ak.H.Ha##x#6#2#2#2bK", +"bO.5#7#aaO.S#0.S#0#Cbe#Q#q#Qb1.L.Q.L.f.e#y.Q.e.e#Q.L##.saEbp.eaE.I#Q.Q.x.I.4bGbFbo#9#9#V#Q.x#Gau.xajauauan#w#w#r.Nb.#raTbZ#J#J#o#t.u#o#obj.w#b#b#P#b#b#b#b#b.u.4b5ahbG.r.zbcbV.o#v.NaBbMaUbV.xbmaIaIau.x.1av.x.I#9.I.zbQaF.h#J.z.Qbsbq.L#Qbq.X.B.ZbJ#qbJbJbJ.baXbJ#4.3#K#Q#V.qaX.Y.Ya##2#6#6aGa#b6aY.p.H#M#M", +"#T##aR.5#C.S#7bDbD.SaSby#c#4.fbP.Q.Q.e.L.b.b.X.f#QaOb1aE.BaE.faE.X.1.Q#9#B#JaF.4#l#9#Q.1#G.1.xbcaUajau.xbMbM#raT.N.gaTafaFaF#k#X.O#X#R.O#H#X.O#t.w#H#t#H#Hbj#X#j#ob5.ubT#J#GbI#ra2a2#vbV#UbIaU.Rajbm.xbn.xao.1.1a9ava9bQ.8.4bM.r.Q.C.f.I.f.e#QbAbEbLaXaAaX.L.l#cbJb1#QaQ.Lb1#TaVam#1ama#a##2a#a##iaAbW#1bWaH", +".z#4aRbL#Cbvbz#n.laJ.l#y.lb1.I.I.Q.Q#V.e#yb1bJ.e.L.L#4.saP.d.f.B.q.X#F.1an#z#JanaM#V#Q#V.1#z#w#w#U.RaubVbM#Bb.b..gaB#vag#B#o#X#8#Rbj#Y#Y#t#t#Y#Y#Y#b#P#b#b#b#b#Y#b#tbjbjbjarbFa2a2a2ata2a2aB#raN.ibmaUaNau.x.1#9.1#V.Iav.3#JbQbo.Q.C.fb1bqaO.LbpbE#7#0aV#Q.A.qbD#y.5bP#KbPb1.U.s.n#I.Y#1a#.va##6.0#6.YbWa8a8", +".z#4aRbW.l.l#n.Sbz.l.WaS#QaManb1.e#FaM#Q.LaM.eaX#T#q.La1.daPaX.Z.q.X.1.8anbq#9#l#9#V#V.1#z#w#w#w#Uaj.Ra6aW#LaLaLat#vaB#wbn#F#..C.C.C.C.C.K#p.K#p.K.CaI.K#pbU#paI.C.C.KbU.KbnbmaUaBad.Na2bbbb#r#r.iajaUaN.1.x.1#z.1#9.I.1.I#F#G#G#F.Q.fb1.e#Q.LaXaVaAb7a3aV.LbL#8.L.A.f#KbP.faE.n.naV#Eamac#1bk#6b6bka8bkbkbk", +"#abLaH#I#dbx#C#I#CbDbg#q#kbQ#Vb1bq#F.3#g#Q.e##a1bAbpbJ.f.saPaXaV.qaW.bb1.C.xan.I#9#Q#V#V#w.xaUbV#r.a.aalbFba#Latada2alaN.Kbhbf..bfbfbh.MaQaQbh.MaQ.Mbh.MbSbUbS#pbfbf..aQbh.CaIaUaBa2adadadbbbbaBaj.RbI#waN.xaoav.1#V#9ana9.1.Q#F.b.Q.f.f.b.f#QbJaX#7b7.ZbdaX.LbL#abJaO#KbPbP.UbA#g.5b#b7am#1a##6b6#6#6#s#2.p", +"#7bWbW.t#i.0a.aJbDbJ#laXbQ#F#Qanbq.e.B###GbJ.X##b7aV#7.s.f.Z.X.U.qaW.b.ebqaW.r#9#9#9#9#9.x#w#U#r#r#r#rb.a6baa4aLa2.oaTaIbh...MbfbfbS#p#.#p.K#p.K#p.K#.#paIbgaI#z.2.Mbf.Mbfbf.MaNbVbbadadadbbbbaBbR.abI#UbIaua6.w#D.w.w.w#t#ta9.e.Q#K.I.f.Q#Q.faAb7#0b7#M#1#0.q#QbJbL.f#KbPbP.L#k.n.5bObAb7aV.v.0.0.Y.v#I#I.p", +"b7#CbtaJa0#i#C.lbJ#l###4#c#G.fan#Q.e.b#Q.LaM#7b7#Mb7.YbE.s.X.L.X.q.q.bbq.I#9#9.1ao#V.I.1.xbI#U.o#U#U#vaTafa6aLata2aB#waQbfbhaQbf.M.M#p#p.C#p#p.KaS#..K#..K.K#.#pbS.Mbh.C..bfbfaIbV.oadadada2.oa2#UbIbR.obIaN.x.waq.waqaqb2aq.wbq.Q.bbP.L.Q.Lb1aVb7.pbdac#1#7b7#7#QbJ.Q.Q.f.X###q#7#a#j#g#E#EaV#S#S#1#7#a.p.p", +"#aaJ.S#d#S.0.l#l#4#4#l#G#G#G#Q.X.L.b.Q#Q#cbJ#7.Z.Vbd#s.V.d.U.fbPbpaW.bbq.I.1#9ao#9ao#9.1aNbI#U.o#U#Ual#va6b.aL.Na2aB#w.CbfbhaQbhbhaQ#p.C.C#p.C#p#F.K#p.K.C.K.KaQ.MbhbfaQbf.Mbf.CaUbIadbb.o.o#UaB#rbRbR.o#UaNaua6a4a4#D.w.w.waqb..Q.QbP.f.bbJaX#kb7a.bdaKaH#EbE.s.X#Q.Q.Q.f.fb1bL#4.A#g#g#gb7aHaAaY.vaR#a#a.Y" +}; +#endif diff --git a/rce/rcecalib/server/bootloader.cc b/rce/rcecalib/server/bootloader.cc new file mode 100644 index 0000000000000000000000000000000000000000..b26b471d852f8fabb8f620dee1005e7941449199 --- /dev/null +++ b/rce/rcecalib/server/bootloader.cc @@ -0,0 +1,201 @@ +/// @file core.cc +/// @brief As the last part of the initialization of the system after +/// a reboot, load from flash, relocate and run the application module +/// selected by the RCE front panel. + + +#include "rce/debug/Debug.hh" +#include "rce/debug/Print.hh" +#include "rce/shell/ShellCommon.hh" +#include "rce/gdbstub/rtems-gdb-stub.h" + + +#include "rce/service/Thread.hh" +#include "rceusr/init/NetworkConfig.hh" +#include "rceusr/tool/DebugHandler.hh" +#include "rcecalib/server/EthPrimitive.hh" +#include "rcecalib/server/CmdDecoder.hh" +#include "rce/dynalink/Linker.hh" + +#include "rce/pgp/DriverList.hh" + +#include "rcecalib/server/BootLoaderPort.hh" + +extern "C"{ + #include <librtemsNfs.h> + #include <rtems/malloc.h> +} + +//#include <omnithread.h> +#include <pthread.h> + +#include <exception> +#include <stdio.h> +#include <string> + +#include <iostream> + + +// We need to include <iostream> so that symbolic references to +// std::cout et al. are made. The weak definitions will therefore be +// picked up from libstdc++. Modules are not linked against libstdc++ +// so they rely on the definitions in the core. +#include <iostream> + +/* +// for speed test +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +*/ + +using std::exception; +using std::string; + +using RCE::Shell::startShell; + +using RceDebug::printv; + +using RceInit::configure_network_from_dhcp; + +using RceSvc::Exception; + +using RCE::Dynalink::Linker; +using RCE::Dynalink::LinkingError; + +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; + + +namespace { + int majorVersion=1; + int minorVersion=4; + string branch("devel"); +} +extern "C" { + + // This symbol is set by the static linker (ld) to the start if the + // "dynamic section" which the linker uses to find the system symbol + // table. + extern const char _DYNAMIC; + + void *posix_init( void *argument ); +#if RCE_INTERFACE == 1 +#warning RCE_INTERFACE=1 +#elif RCE_INTERFACE == 0 +#warning RCE_INTERFACE=0 +#else +#error invalid RCE_INTERFACE +#endif + + + unsigned interface = RCE_INTERFACE; + void init_executive() + { + try { + RceInit::configure_network_from_dhcp(interface); + RcePgp::init_pgp(); + + (void)Linker::instance(&_DYNAMIC, majorVersion, minorVersion, branch); + + printf("starting shell\n"); + startShell(); + // Start a debugger daemon + // First arg = 0 --> use socket IO over TCP. + // Second arg = 0 --> Priority is chosen by the debugger daemon + rtems_gdb_start(0, 0); + //rpcUdpInit(); + // nfsInit( 0, 0 ); + // printf("BOOTP server is %s. Use as NFS server.\n",inet_ntoa( rtems_bsdnet_bootp_server_address)); + // nfsMount(inet_ntoa( rtems_bsdnet_bootp_server_address), NFSDIR ,"/nfs"); //NFSDIR comes from constituents.mk + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + rtems_malloc_statistics_t stats; + malloc_get_statistics(&stats); + printf("*** malloc statistics\n"); + printf("space available: %uk\n",(unsigned int)stats.space_available/1024); + printf("space allocated: %uk\n",(unsigned int)(stats.lifetime_allocated-stats.lifetime_freed)/1024); + + } catch (Exception& e) { + printv("*** RCE exception %s", e.what()); + } catch (exception& e) { + printv("*** C++ exception %s", e.what()); + } + printf("Done with init_executive"); + } +void *posix_init( void *argument ){ + std::cout<<"ATLAS Pixel RCE boot loader (built on " << BUILDDATE << " by " << BUILDUSER <<")" << std::endl; + // std::cout<<"ATLAS Pixel RCE boot loader." << std::endl; + EthPrimitive eth(BootloaderPort); + CmdDecoder cd(ð); + cd.run(); + + //this is for speed testing + /* + EthPrimitive eth(3434); + int length=1000000; + char *buffer=new char[1000000]; + eth.receiveCommand(); + sleep(7); + std::cout<<"Start"<<std::endl; + eth.reply(buffer, 270256); + std::cout<<"Stop"<<std::endl; + */ + +// more speed testing +/* + int sockfd, portno, n; + struct sockaddr_in serv_addr; + struct hostent *server; + + char *buffer=new char[251000]; + portno = 3434; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + printf("ERROR opening socket\n"); + server = gethostbyname("172.21.6.45"); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + exit(0); + } + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy((char *)server->h_addr, + (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) + printf("ERROR connecting\n"); + int flag = 1; + + int ret = setsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) ); + for(int i=0;i<100;i++)n = write(sockfd,buffer,100); + usleep(50000); + n = write(sockfd,buffer,212); + n = write(sockfd,buffer,10000); + + if (n < 0) + printf("Scheisse\n"); + close(sockfd); +*/ + return 0; +} + +} diff --git a/rce/rcecalib/server/bootloader_2.2.cc b/rce/rcecalib/server/bootloader_2.2.cc new file mode 100644 index 0000000000000000000000000000000000000000..3c826cc3210814c3a557e035b7c08f76c7ad4e43 --- /dev/null +++ b/rce/rcecalib/server/bootloader_2.2.cc @@ -0,0 +1,130 @@ +// -*-Mode: C++;-*- +/*! +* +* @brief Functions for bootstrapping the RCE system +* +* @author R. Claus -- REG/DRD - (claus@slac.stanford.edu) +* +* @date March 17, 2012 -- Created +* +* $Revision: 966 $ +* +* @verbatim +* Copyright 2012 +* by +* The Board of Trustees of the +* Leland Stanford Junior University. +* All rights reserved. +* @endverbatim +*/ + +#include <cstring> +#include <pthread.h> +#include <iostream> +#include <memory> +#include "rcecalib/server/EthPrimitive.hh" +#include "rcecalib/server/CmdDecoder.hh" +#include "rcecalib/server/BootLoaderPort.hh" +using std::auto_ptr; + +#include "datCode.hh" +//#include DAT_PUBLIC( configuration, rtems, prod.hh) +#include DAT_PRIVATE(platform, startup, Init.hh) +#include DAT_PRIVATE(platform, startup, TaskThread.hh) + +#if !tgt_board_rce440 +#include DAT_PUBLIC( service, shell, ShellCommon.hh) +#include DAT_PUBLIC( service, dynalink, Linker.hh) +#include DAT_PUBLIC( oldPpi, pgp, DriverList.hh) +using service::dynalink::Linker; + +#include DAT_PUBLIC( service, fci, Task.hh) +using service::fci::Task; + +// The address of the dynamic section created by ld. +extern "C" char _DYNAMIC[0]; +#endif +extern "C"{ + #include <rtems/malloc.h> +} + +void *posix_init( void *argument ); + +// GDB stub is compiled with C bindings +extern "C" int rtems_gdb_start(int pri, char *ttyName); + + +namespace platform { + + namespace startup { + + void initialize() + { + // Output some identification information + splash("prod"); + +#if !tgt_board_rce440 + // Add our custom commands first + service::shell::addCommands(); +#endif + + // Do the board-common initialization of the core + brdInitialize(); + // Initialize PGP + oldPpi::pgp::init_pgp(); +#if !tgt_board_rce440 + // Allow users to log in via telnet and execute interactive commands. + service::shell::initialize(); + + // Start a debugger daemon + // First arg = 0 --> Use socket IO over TCP. + // Second arg = 0 --> Priority is chosen by the debugger daemon + rtems_gdb_start(0, 0); + + // Establish the system image version for use by following code. + const uint majorVersion(rtems_majorv_macro); + const uint minorVersion(rtems_minorv_macro); + + // We must use the 4-argument form of Linker::instance() to + // create the linker instance that will be fetched by the + // no-argument form. + Linker::instance(_DYNAMIC, majorVersion, minorVersion, "prod"); + + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + rtems_malloc_statistics_t stats; + malloc_get_statistics(&stats); + printf("*** malloc statistics\n"); + printf("space available: %uk\n",(unsigned int)stats.space_available/1024); + printf("space allocated: %uk\n",(unsigned int)(stats.lifetime_allocated-stats.lifetime_freed)/1024); + + printf("Done with initialize\n"); + + +#endif + } + + } // startup + +} // platform + +void *posix_init( void *argument ){ + std::cout<<"ATLAS Pixel RCE boot loader (built on " << BUILDDATE << " by " << BUILDUSER <<")" << std::endl; + // std::cout<<"ATLAS Pixel RCE boot loader." << std::endl; + EthPrimitive eth(BootloaderPort); + CmdDecoder cd(ð); + cd.run(); + return 0; +} + diff --git a/rce/rcecalib/server/calibGui_Linkdef.hh b/rce/rcecalib/server/calibGui_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..68ff853be644d4d3300ef659f7c1cc2527a2ae71 --- /dev/null +++ b/rce/rcecalib/server/calibGui_Linkdef.hh @@ -0,0 +1,5 @@ +#pragma link C++ class CalibGui; +#pragma link C++ class ScanGui; +#pragma link C++ class PrimListGui; +#pragma link C++ class ConfigGui; +#pragma link C++ class GlobalConfigGui; diff --git a/rce/rcecalib/server/calibclient.cc b/rce/rcecalib/server/calibclient.cc new file mode 100644 index 0000000000000000000000000000000000000000..cea069ce5770b43b721e6dbdd708297e6cbc8796 --- /dev/null +++ b/rce/rcecalib/server/calibclient.cc @@ -0,0 +1,321 @@ +#include <stdio.h> + +#include <ers/ers.h> + +#include <ipc/partition.h> +#include <ipc/server.h> +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <cmdl/cmdargs.h> +#include <unistd.h> + +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/IPCHistoController.hh" +#include "rcecalib/server/PixScan.hh" + +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCFEI3Adapter.hh" +#include "ScanOptions.hh" +#include "PixelModuleConfig.hh" + +#include <TApplication.h> +#include <TROOT.h> +#include <TStyle.h> +#include <TCanvas.h> +#include <TH2F.h> + +using namespace RCE; + +void create_1d_hist(TH2F *h,const char *title) +{ + int max_val=(int) h->GetBinContent(h->GetMaximumBin())+1; + std::cout << "max " << max_val; + TH1F *h1d=new TH1F(title,title,max_val,0,max_val); + TCanvas *c=new TCanvas(title,title,600,600); + int nx=h->GetNbinsX(); + int ny=h->GetNbinsY(); + for(int x=0;x<nx;x++) { + for(int y=0;y<ny;y++) { + h1d->Fill(h->GetBinContent(x+1,y+1)); + } + } + c->Draw(); + h1d->Draw(); +} + + +int main( int argc, char ** argv ) +{ + + TApplication *tapp; + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdArgInt channel ('c', "channel", "channel-number", "channel modules is connected too."); + CmdArgStr config_name ('m', "configuration", "module-configuration", "module configuation file."); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdLine cmd(*argv, &partition_name,&channel,&config_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + IPCController controller(p); + IPCHistoController hcontroller(p); + std::cout << "Partition : " <<(const char*)partition_name <<std::endl; + std::cout << "Channel : " <<channel <<std::endl; + std::cout << "Configuration: " <<(const char*)config_name <<std::endl; + tapp=new TApplication("bla", &argc, argv); + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + TH2F* occ=new TH2F("occ","occ", 8*18,0,8*18,2*160,0,2*160); + occ->SetMinimum(0); + TCanvas *c1=new TCanvas("occupancy","occupancy",600,600); + c1->Draw(); + occ->Draw("colz"); + + TH2F* mean=new TH2F("threshold mean","threshold mean", 8*18,0,8*18,2*160,0,2*160); + mean->SetMinimum(0); + TCanvas *c2=new TCanvas("threshold mean","threshold mean",600,600); + c2->Draw(); + mean->Draw("colz"); + + TH2F* sigma=new TH2F("threshold sigma","threshold sigma", 8*18,0,8*18,2*160,0,2*160); + sigma->SetMinimum(0); + TCanvas *c3=new TCanvas("threshold sigma","threshold sigma",600,600); + c3->Draw(); + sigma->Draw("colz"); + + TH2F* chi2=new TH2F("threshold chi2","threshold chi2", 8*18,0,8*18,2*160,0,2*160); + chi2->SetMinimum(0); + TCanvas *c4=new TCanvas("threshold chi2","threshold chi2",600,600); + c4->Draw(); + chi2->Draw("colz"); + + + TH2F* iter=new TH2F("threshold iter","thrshold iter", 8*18,0,8*18,2*160,0,2*160); + iter->SetMinimum(0); + TCanvas *c5=new TCanvas("threshold iter","threshold iter",600,600); + c5->Draw(); + iter->Draw("colz"); + + TH2F* totmean=new TH2F("tot mean","tot mean", 8*18,0,8*18,2*160,0,2*160); + totmean->SetMinimum(0); + TCanvas *c6=new TCanvas("tot mean","tot mean",600,600); + c6->Draw(); + totmean->Draw("colz"); + + TH2F* totsigma=new TH2F("tot sigma","tot sigma", 8*18,0,8*18,2*160,0,2*160); + totsigma->SetMinimum(0); + TCanvas *c7=new TCanvas("tot sigma","tot sigma",600,600); + c7->Draw(); + totsigma->Draw("colz"); + + TH2F* bcidmean=new TH2F("bcid mean","bcid mean", 8*18,0,8*18,2*160,0,2*160); + bcidmean->SetMinimum(0); + TCanvas *c8=new TCanvas("bcid mean","bcid mean",600,600); + c8->Draw(); + bcidmean->Draw("colz"); + + TH2F* bcidsigma=new TH2F("bcid sigma","bcid sigma", 8*18,0,8*18,2*160,0,2*160); + bcidsigma->SetMinimum(0); + TCanvas *c9=new TCanvas("bcid sigma","bcid sigma",600,600); + c9->Draw(); + bcidsigma->Draw("colz"); + + + ipc::PixelModuleConfig cfg; + TurboDaqFile turbo; + turbo.readModuleConfig(&cfg,(const char*)config_name); + // turbo.dump(cfg); + + controller.removeAllRces(); + controller.addRce(0); + controller.removeAllModules(); + controller.addModule("module 0","FEI3",0,channel, channel, 0, "JJ"); + controller.setupTrigger(); + controller.downloadModuleConfig(0, 0, cfg); + + PixScan* scn = new PixScan(PixScan::THRESHOLD_SCAN,PixLib::EnumFEflavour::PM_FE_I2 ); + + scn->resetScan(); + scn->setLoopVarValues(0, 0, 200, 101); + scn->setRepetitions(50); + scn-> setHistogramFilled(PixScan::TOT_MEAN,true); + scn-> setHistogramFilled(PixScan::TOT_SIGMA,true); + scn-> setHistogramFilled(PixScan::BCID_MEAN,true); + scn-> setHistogramFilled(PixScan::BCID_SIGMA,true); + + ipc::ScanOptions options; + scn->convertScanConfig(options); + //scn->dump(options); + + controller.downloadScanConfig(options); + + controller.runScan(ipc::LOW); + + //std::vector<TH1*> his=controller.getHistosByName("Mod_0_Occupancy_Point_075"); + std::vector<TH1*> his=hcontroller.getHistosFromIS("Mod_0_Occupancy_Point_075"); + assert(his.size()==1); + TH1* histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + occ->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)); + } + } + delete histo; + std::cout<<"Updated Mod_0_Occupancy_Point_075"<<std::endl; + //his=controller.getHistosByName("Mod_0_ToTmean_Point_075"); + his=hcontroller.getHistosFromIS("Mod_0_ToTmean_Point_075"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + totmean->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)/128); + } + } + delete histo; + std::cout<<"Updated Mod_0_ToTmean_Point_075" <<std::endl; + his=hcontroller.getHistosFromIS("Mod_0_ToTsigma_Point_075"); + //his=controller.getHistosByName("Mod_0_ToTsigma_Point_075"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + totsigma->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)/128); + } + } + delete histo; + std::cout<<"Updated Mod_0_ToTsigma_Point_075" <<std::endl; + + his=hcontroller.getHistosFromIS("Mod_0_BCIDmean_Point_075"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + bcidmean->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)/128); + } + } + delete histo; + std::cout<<"Updated Mod_0_BCIDmean_Point_075" <<std::endl; + + his=hcontroller.getHistosFromIS("Mod_0_BCIDsigma_Point_075"); + //his=controller.getHistosByName("Mod_0_BCIDsigma_Point_075"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + bcidsigma->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)/128); + } + } + + delete histo; + std::cout<<"Updated Mod_0_BCIDsigma_Point_075" <<std::endl; + + his=hcontroller.getHistosFromIS("Mod_0_Mean"); + //his=controller.getHistosByName("Mod_0_Mean"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + mean->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)); + } + } + delete histo; + + std::cout<<"Updated Mod_0_Mean"<<std::endl; + his=hcontroller.getHistosFromIS("Mod_0_Sigma"); + //his=controller.getHistosByName("Mod_0_Sigma"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + sigma->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)); + } + } + delete histo; + std::cout<<"Updated Mod_0_Sigma"<<std::endl; + his=hcontroller.getHistosFromIS("Mod_0_ChiSquare"); + //his=controller.getHistosByName("Mod_0_ChiSquare"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + chi2->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)); + } + } + delete histo; + std::cout<<"Updated Mod_0_ChiSquare"<<std::endl; + his=hcontroller.getHistosFromIS("Mod_0_Iter"); + //his=controller.getHistosByName("Mod_0_Iter"); + assert(his.size()==1); + histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + for(int j=0;j<histo->GetNbinsY();j++){ + int chip=i/18; + int col=i%18; + int row=j; + iter->Fill((chip%8)*18+col,chip/8*160+row,histo->GetBinContent(i+1,j+1)); + } + } + delete histo; + std::cout<<"Updated Mod_0_Iter"<<std::endl; + + + create_1d_hist(mean,"threshold mean 1d"); + create_1d_hist(sigma,"threshold sigma 1d"); + create_1d_hist(chi2,"thresshold chi2 1d"); + create_1d_hist(iter,"threshold iter 1d"); + create_1d_hist(totsigma,"tot sigma 1d"); + create_1d_hist(totmean,"tot mean 1d"); + create_1d_hist(bcidsigma,"bcid sigma 1d"); + create_1d_hist(bcidmean,"bcid mean 1d"); + + controller.resetFE(); + tapp->Run(); +} diff --git a/rce/rcecalib/server/calibserver.cc b/rce/rcecalib/server/calibserver.cc new file mode 100644 index 0000000000000000000000000000000000000000..3a7f191a99ad1ccd2e9e8ad559f6b4fcdc823841 --- /dev/null +++ b/rce/rcecalib/server/calibserver.cc @@ -0,0 +1,146 @@ +#include <stdio.h> +#include <unistd.h> + +#include <ers/ers.h> + +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> +#include <ipc/server.h> + +#include <owl/timer.h> +#include <owl/semaphore.h> + +#include <boost/regex.hpp> +#include <fstream> + +#include "rcecalib/scanctrl/IPCScan.cc" +#include "rcecalib/scanctrl/IPCScanRoot.cc" +#include "rcecalib/config/IPCConfigIF.cc" +#include "rcecalib/HW/SerialHexdump.hh" +#include "rcecalib/HW/SerialPgp.hh" +#include "rcecalib/HW/SerialPgpBw.hh" +#include "rcecalib/HW/SerialPgpFei4.hh" +#include "rcecalib/config/IPCModuleFactory.hh" +#include "rcecalib/util/RceName.hh" + +#include "rcecalib/server/calibserver.hh" + +#include "rcecalib/profiler/Profiler.hh" + +#include <is/infoT.h> +#include <is/infodictionary.h> +#include <ipc/core.h> +#include <signal.h> + +static IPCServer ipcServer; + + + + +////////////////////////////////////////// +// +// Main function +// +////////////////////////////////////////// + + +void calibserver::run(bool ismodule, char* partition){ + +const char *cc_argv[] = +{ + "calibserver", /* always the name of the program */ + "-p", + "rcetest", + //"-ORBtraceLevel", /* trace level */ + //"25", + //"-ORBtraceInvocations", + //"1", + //"-ORBtraceTime", + //"1", + //"-ORBtraceThreadId", + //"1", + "-ORBgiopMaxMsgSize", + "33554422", /* max message size 32 MB */ + "-ORBmaxServerThreadPerConnection", "1" + // "-ORBendPoint", + //" giop:tcp:192.168.1.35:" +}; + + + if(partition)cc_argv[2]=partition; +int cc_argc = sizeof( cc_argv ) / sizeof( cc_argv[ 0 ] ); +// PROFILE_THREAD_SCOPED(); + + + try { + IPCCore::init( cc_argc, (char**)cc_argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return; + } + + // Declare command object and its argument-iterator + IPCPartition p((const char*)cc_argv[2]); + printf("Partition is %s\n",cc_argv[2]); + char name[128]; + sprintf(name, "configIF_RCE%d", RceName::getRceNumber()); + p.isObjectValid<ipc::IPCConfigIFAdapter>(name); + + //Serial IF + new SerialPgpFei4; + + // set big endianness for pgp 2 + unsigned value; + asm volatile("mfdcr %0, %1" : "=r"(value) : "i"(0x2e0)); + value|=1<<13; + asm volatile("mtdcr %0, %1" : : "i"(0x2e0), "r"(value)); + + + + + //Module Factory + + ModuleFactory *moduleFactory=new IPCModuleFactory(p); + + // Config IF + + IPCConfigIF<ipc::single_thread> *cif; + IPCScan<ipc::multi_thread> *scan; + IPCScanRoot<ipc::single_thread> * scanroot; + + try{ + cif=new IPCConfigIF<ipc::single_thread>(p, name, moduleFactory); + sprintf(name, "scanCtrl_RCE%d", RceName::getRceNumber()); + scan = new IPCScan<ipc::multi_thread>( p, name); + sprintf(name, "scanRoot_RCE%d", RceName::getRceNumber()); + scanroot = new IPCScanRoot<ipc::single_thread>( p, name, (ConfigIF*)cif, (Scan*)scan); + }catch(...){ + std::cout<<"Could not add IPC objects (ipc_server not running? Several servers in the same partition?)."<<std::endl; + assert(0); + } + IPCHistoManager *hm; + try{ + sprintf(name, "RCE%d",RceName::getRceNumber()); + hm=new IPCHistoManager(p,"RceIsServer", name); + }catch(...){ + std::cout<<"Could not start histogram manager (is_server not running? Another server running on the same partition?)."<<std::endl; + assert(0); + } + printf("ipc_test_server has been started.\n"); + + if(ismodule==true){ + kill(getpid(),SIGUSR1); + pause(); + }else{ + ipcServer.run(); + } + scan->_destroy(); + scanroot->_destroy(); + cif->_destroy(); + IPCCore::shutdown(); + delete hm; + + std::cout << "Test successfully completed." << std::endl; +} diff --git a/rce/rcecalib/server/calibserver.hh b/rce/rcecalib/server/calibserver.hh new file mode 100644 index 0000000000000000000000000000000000000000..e650b9ca5279ce32fabe35289662628b0639bbe6 --- /dev/null +++ b/rce/rcecalib/server/calibserver.hh @@ -0,0 +1,12 @@ +#ifndef CALIBSERVER_HH +#define CALIBSERVER_HH + + +class calibserver { + public: + calibserver(){}; + static void run(bool ismodule, char* partition=0); + +}; + +#endif diff --git a/rce/rcecalib/server/constituents.mk b/rce/rcecalib/server/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..060a3e88064f3030a2c59da09fc4f828cf3edafc --- /dev/null +++ b/rce/rcecalib/server/constituents.mk @@ -0,0 +1,820 @@ +build_date:=$(shell date +%Y/%m/%d-%H:%M:%S) +#ugly hack to link ers streams +ifeq ($(TDAQ_VERSION),4) +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +extract_archive:=$(shell cd $(RELEASE)/build/rcecalib/obj/$(tgt_arch)/server; $(AR) x $(TDAQC_INST_PATH)/$(tgt_arch)/lib/libErsBaseStreams.a) +endif +endif +CPPFLAGS+=-DBUILDDATE=\"$(build_date)\" -DBUILDUSER=\"$(USER)\" + +ifeq ($(RCE_CORE_VERSION),2.2) +bootloader_cc:=bootloader_2.2.cc +rtems_config_cc:=rtems_config_2.2.cc +rce_service:=tool/exception +rce_net:= oldPpi/ethernet oldPpi/bsdNet oldPpi/net +else +bootloader_cc:=bootloader.cc +rtems_config_cc:=rtems_config.cc +rce_service:=rce/rceservice +rce_net:=rce/rcenet +endif +CPPFLAGS+=-I$(RELEASE_DIR)/rcecalib + +ifdef RCE_INTERFACE +CPPFLAGS+= '-DRCE_INTERFACE=$(RCE_INTERFACE)' +else +CPPFLAGS+= '-DRCE_INTERFACE=0' +endif +ifdef ELOG +CPPFLAGS+= '-DELOG' +endif +ifdef SQLDB +CPPFLAGS+= '-DSQLDB' +endif +ifdef SQLDBDBG +CPPFLAGS+= '-DSQLDBDBG' +endif +ifeq ($(profiler),y) +CPPFLAGS+='-D__PROFILER_ENABLED__' +profiler_lib=rcecalib/profiler +endif + +ifneq ($(findstring linux,$(tgt_os)),) +libnames := ipcclient ipcrootclient rcecontrol +endif +libsrcs_ipcclient:= IPCController.cc \ + TurboDaqFile.cc \ + FEI4AConfigFile.cc \ + FEI4BConfigFile.cc \ + HitbusConfigFile.cc \ + AFPHPTDCConfigFile.cc \ + PixScan.cc \ + PrimList.cc \ + IPCRegularCallback.cc + +libincs_ipcclient := \ + rcecalib + + +libsrcs_rcecontrol := RceControl.cc +libincs_rcecontrol : = rcecalib +tgtslibs_rcecontrol: = $(rce_service) $(rce_net) + +libsrcs_ipcrootclient:= IPCHistoController.cc +libincs_ipcrootclient := \ + rcecalib + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) + + +tgtnames := bootloader #calibserver eudaqserver + +# need to fix this +ifneq ($(RCE_CORE_VERSION),2.2) +tgtnames += calibserver +endif + +CPPFLAGS += -DNFSDIR=\"/nfsexport/home/$(USER)\" +ifeq ($(TDAQ_VERSION),4) +LXFLAGS += $(RELEASE_DIR)/build/rcecalib/obj/$(tgt_arch)/server/ThrottleStream.o $(RELEASE_DIR)/build/rcecalib/obj/$(tgt_arch)/server/StandardStream.o +endif +LXFLAGS+=-L$(RELEASE_DIR)/build/rcecalib/modlib/$(tgt_arch) +ifeq ($(RCE_CORE_VERSION),2.2) +LXFLAGS += -u _ZTIN7service3fci9ExceptionE -u pthread_attr_destroy -u sem_trywait -u _ZTIi -u sem_getvalue -u pthread_getspecific -u __ltsf2 -u pthread_mutex_trylock -u clearerr -u _ZTIt -u pipe -u __mulsf3 -u toupper -u pthread_cond_wait -u __floatsisf -u _ZN5boost6thread4joinEv -u __floatundisf -u _ZN3ers11LocalStream5fatalERKNS_5IssueE -u pthread_cond_destroy -u tolower -u pthread_getschedparam -u _ZTIN5boost6detail16thread_data_baseE -u _ZN5boost11this_thread5sleepERKNS_10posix_time5ptimeE -u _ZN5boost6thread12start_threadEv -u sem_init -u isalnum -u pthread_cond_signal -u feof -u pthread_setspecific -u _ZTVN5boost6detail16thread_data_baseE -u sem_post -u sem_wait -u _ZN3ers11LocalStream7warningERKNS_5IssueE -u pthread_cond_broadcast -u _ZN5boost6thread9interruptEv -u _ZTIj -u ferror -u _ZN5boost6threadD1Ev -u sched_yield -u __gtsf2 -u sched_get_priority_min -u freeifaddrs -u _ZN3ers11LocalStream8instanceEv -u pthread_detach -u pthread_setschedparam -u sem_destroy -u _ZN5boost6detail16thread_data_baseD2Ev -u _ZN3ers11LocalStream5errorERKNS_5IssueE -u pthread_cond_init -u getifaddrs -u isspace -u pthread_attr_getstacksize -u pthread_cond_timedwait -u pthread_key_create -u pthread_mutexattr_init -u pthread_join -u sched_get_priority_max -u _ZNK5boost9gregorian10greg_month15as_short_stringEv +else +LXFLAGS += -u pthread_attr_destroy -u _ZN3ers13Configuration15verbosity_levelEi -u _ZN3ers5IssueD2Ev -u sem_trywait -u _ZTIi -u _ZN3ers5Issue15prepend_messageERKSs -u sem_getvalue -u pthread_getspecific -u sem_post -u sem_wait -u __lesf2 -u _ZN3ers11LocalStream7warningERKNS_5IssueE -u pthread_mutex_trylock -u clearerr -u pthread_cond_broadcast -u _ZN3ers13StreamManager3logERKNS_5IssueE -u _ZTIj -u ferror -u __eqsf2 -u _ZN3ers13StreamManager8instanceEv -u sched_yield -u pthread_mutex_destroy -u pthread_mutex_init -u _ZN3ers13Configuration8instanceEv -u sched_get_priority_min -u _ZTIt -u freeifaddrs -u pipe -u __mulsf3 -u _ZN3ers5IssueC2ERKNS_7ContextERKSs -u pthread_mutex_lock -u _ZN3ers11LocalStream8instanceEv -u _ZTIm -u pthread_detach -u _ZN3ers13StreamManager12report_issueENS_8severityERKNS_5IssueE -u _ZTIl -u _ZN3ers12IssueFactory14register_issueERKSsPFPNS_5IssueERKNS_7ContextEE -u _ZN3ers12LocalContext9c_processE -u sem_destroy -u pthread_setschedparam -u pthread_cond_wait -u __floatsisf -u pthread_mutex_unlock -u strtoll -u _ZN3ers11LocalStream5errorERKNS_5IssueE -u pthread_cond_init -u getifaddrs -u __floatundisf -u _ZN3ers11LocalStream5fatalERKNS_5IssueE -u isspace -u pthread_cond_destroy -u __moddi3 -u pthread_attr_getstacksize -u tolower -u pthread_getschedparam -u _ZN3ers12IssueFactory8instanceEv -u __divdi3 -u _ZN3erslsERSoRKNS_5IssueE -u pthread_cond_timedwait -u _ZN3ers5IssueC2ERKNS_7ContextERKSt9exception -u _ZTIh -u _ZN3ers5IssueC2ERKS0_ -u select -u _ZN3ers13StreamManager5debugERKNS_5IssueEi -u _ZTIN3ers5IssueE -u pthread_key_create -u sem_init -u _ZN3ers12LocalContextC1EPKcS2_iS2_ -u pthread_mutexattr_init -u isalnum -u pthread_join -u pthread_cond_signal -u feof -u sched_get_priority_max -u pthread_setspecific -u malloc_report_statistics -L$(RELEASE_DIR)/build/rcecalib/modlib/$(tgt_arch) +endif + + + +tgtsrcs_bootloader := $(bootloader_cc) $(rtems_config_cc) EthPrimitive.cc CmdDecoder.cc + +tgtincs_bootloader := +ifeq ($(RCE_CORE_VERSION),2.2) +tgtlibs_bootloader := \ + oldPpi/bsdNet \ + oldPpi/net \ + service/fci \ + service/shell \ + service/dynalink \ + service/debug \ + service/logger \ + tool/concurrency \ + tool/exception \ + tool/io \ + tool/string \ + tool/time \ + oldPpi/ethernet \ + oldPpi/init \ + oldPpi/pic \ + oldPpi/pgp +else +tgtlibs_bootloader := rce/rceshell \ + $(rce_service) \ + $(rce_net) \ + rce/rcefci \ + rce/rcedebug \ + rce/rcepic \ + rce/rcepgp \ + rce/rceethernet \ + rce/rcebsdnet \ + rce/rceinit \ + rce/dynalink \ + rce/gdbstub \ + rceusr/rceusrinit \ + rceusr/rcezcpnet +endif +ifeq ($(RCE_CORE_VERSION),2.2) +tgtslib_bootloader:= $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(ers_lib) \ + $(RTEMS_DIR)/nfs \ + $(RTEMS_DIR)/rtemscpu \ + $(RTEMS_DIR)/telnetd \ + $(RTEMS_DIR)/rtemsbsp \ + $(RTEMS_DIR)/rtems-gdb-stub +else +tgtslib_bootloader:= $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(ers_lib) \ + $(RTEMS_DIR)/nfs \ + $(RTEMS_DIR)/rtemscpu \ + $(RTEMS_DIR)/telnetd +endif +managrs_bootloader := io event msg sem ext region +#=================================================================== + +tgtsrcs_calibserver := runserver.cc $(rtems_config_cc) calibserver.cc +tgtincs_calibserver := \ + rcecalib + +tgtlibs_calibserver := rce/rceshell \ + $(rce_service) \ + $(rce_net) \ + rce/rcefci \ + rce/rcedebug \ + rce/rcepic \ + rce/rcepgp \ + rce/rceethernet \ + rce/rcebsdnet \ + rce/rceinit \ + rce/dynalink \ + rce/gdbstub \ + rceusr/rceusrinit \ + rceusr/rcezcpnet + +tgtslib_calibserver += \ + $(RTEMS_DIR)/nfs \ + $(RTEMS_DIR)/rtemscpu \ + $(RTEMS_DIR)/telnetd \ + $(z_lib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(ipc_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(rdb_lib) \ + $(is_lib) \ + $(oh_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(boost_regex_lib) \ + rcecalib/eudaq \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig \ + $(profiler_lib) + + + +managrs_calibserver := io event msg sem ext region + +MLXFLAGS += -mlongcall +LXFLAGS += -mlongcall + +modnames := calibservermod # eudaqservermod +#========================================================================================= +ifeq ($(RCE_CORE_VERSION),2.2) +majorv_calibservermod := 2 +minorv_calibservermod := 2 +else +majorv_calibservermod := 1 +minorv_calibservermod := 0 +endif +branch_calibservermod := prod +modsrcs_calibservermod := runservermod.cc calibserver.cc +modincs_calibservermod := \ + rcecalib + +modlibs_calibservermod := \ + $(profiler_lib) \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig \ + rcecalib/eudaq + +TDAQ_DIR=$(RELEASE_DIR)/build/tdaq/lib/$(tgt_arch) +modslib_calibservermod := \ + $(z_lib) \ + $(omnithread_lib) \ + $(ipc_lib) \ + $(rdb_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(boost_regex_lib)\ + $(omniorb_lib) \ + $(z_lib) \ + $(oh_lib) \ + $(owl_lib) + + +#========================================================================================= +MLXFLAGS += -mlongcall +majorv_eudaqservermod := 1 +minorv_eudaqservermod := 0 +branch_eudaqservermod := prod +modsrcs_eudaqservermod := runeudaqservermod.cc eudaqserver.cc RceProducer.cc +modincs_eudaqservermod := \ + rcecalib + +modlibs_eudaqservermod := \ + $(profiler_lib) \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig \ + rcecalib/ipcclient \ + rcecalib/eudaq + +TDAQ_DIR=$(RELEASE_DIR)/build/tdaq/lib/$(tgt_arch) +modslib_eudaqservermod := \ + $(z_lib) \ + $(omnithread_lib) \ + $(ipc_lib) \ + $(rdb_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(boost_regex_lib)\ + $(omniorb_lib) \ + $(z_lib) \ + $(oh_lib) \ + $(owl_lib) + + + + + + +#-------------------------------------------- +tgtsrcs_eudaqserver := runeudaqserver.cc $(rtems_config_cc) eudaqserver.cc RceProducer.cc +tgtincs_eudaqserver := \ + rcecalib + +tgtlibs_eudaqserver := rce/rceshell \ + $(rce_service) \ + $(rce_net) \ + rce/rcefci \ + rce/rcedebug \ + rce/rcepic \ + rce/rcepgp \ + rce/rceethernet \ + rce/rcebsdnet \ + rce/rceinit \ + rce/dynalink \ + rce/gdbstub \ + rceusr/rceusrinit \ + rceusr/rcezcpnet \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig \ + rcecalib/eudaq \ + rcecalib/ipcclient \ + $(omniorb_lib) + +tgtslib_eudaqserver := \ + $(RTEMS_DIR)/nfs \ + $(RTEMS_DIR)/rtemscpu \ + $(RTEMS_DIR)/z \ + $(RTEMS_DIR)/telnetd \ + $(z_lib) \ + $(profiler_lib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omnithread_lib) \ + $(boost_regex_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) +managrs_eudaqserver := io event msg sem ext region + +endif + + +ifneq ($(findstring linux,$(tgt_os)),) + +LXFLAGS +=-pthread -lm -ldl -rdynamic +rootlibs:= \ + $(RELEASE_DIR)/build/root/lib/Gui \ + $(RELEASE_DIR)/build/root/lib/Thread \ + $(RELEASE_DIR)/build/root/lib/MathCore \ + $(RELEASE_DIR)/build/root/lib/Physics \ + $(RELEASE_DIR)/build/root/lib/Matrix \ + $(RELEASE_DIR)/build/root/lib/Postscript \ + $(RELEASE_DIR)/build/root/lib/Rint \ + $(RELEASE_DIR)/build/root/lib/Tree \ + $(RELEASE_DIR)/build/root/lib/Gpad \ + $(RELEASE_DIR)/build/root/lib/Graf3d \ + $(RELEASE_DIR)/build/root/lib/Graf \ + $(RELEASE_DIR)/build/root/lib/Hist \ + $(RELEASE_DIR)/build/root/lib/Net \ + $(RELEASE_DIR)/build/root/lib/RIO \ + $(RELEASE_DIR)/build/root/lib/Cint \ + $(RELEASE_DIR)/build/root/lib/Core + +tgtnames := host_bootloader \ + calibGui \ + cosmicGui \ + rebootHSIO \ + cosmicMonitoringGui \ + test_sctrl_server \ + rceOfflineProducer \ + sendBitStream \ + sendRandomPattern \ + calibclient \ + tdccalib \ + delaycalib \ + dumpRceMod dumpRceScan + +tgtsrcs_calibclient := calibclient.cc + +tgtincs_calibclient := \ + rcecalib + +tgtlibs_calibclient := \ + rcecalib/idl \ + rcecalib/ipcclient \ + rcecalib/ipcrootclient \ + + +tgtslib_calibclient := \ + dl \ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(rdb_lib) \ + $(is_lib) \ + $(oh_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) \ + $(oh_root_lib) + +#-------------------------------------------- + +tgtsrcs_tdccalib := tdccalib.cc + +tgtincs_tdccalib := \ + rcecalib + +tgtlibs_tdccalib := \ + rcecalib/idl \ + rcecalib/ipcclient + +tgtslib_tdccalib := \ + dl \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + rcecalib/idl \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) +#-------------------------------------------- +tgtsrcs_delaycalib := delaycalib.cc + +tgtincs_delaycalib := \ + rcecalib + +tgtlibs_delaycalib := \ + rcecalib/idl \ + rcecalib/ipcclient \ + rcecalib/ipcrootclient + +tgtslib_delaycalib := \ + dl \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) +#-------------------------------------------- + +GUIHEADERSDEP = CosmicGui.hh ConfigGui.hh CalibGui.hh ScanGui.hh PrimListGui.hh CosmicMonitoringGui.hh \ + CosmicDataReceiver.hh CosmicMonitoringGuiEmbedded.hh GlobalConfigGui.hh + +tgtsrcs_cosmicGui := CosmicGui.cc \ + ConfigGui.cc \ + GlobalConfigGui.cc \ + ScanLog.cc \ + cosmicGui_rootDict.cc \ + CosmicDataReceiver.cc \ + CosmicOfflineDataProc.cc \ + CosmicMonitoringGuiEmbedded.cc + +guiheaders_cosmicGui := CosmicGui.hh ConfigGui.hh CosmicMonitoringGuiEmbedded.hh GlobalConfigGui.hh + + + +tgtincs_cosmicGui := \ + rcecalib \ + rcecalib/server + +tgtlibs_cosmicGui := \ + rcecalib/idl \ + rcecalib/eudaq \ + rcecalib/rceconfig \ + rcecalib/dataproc \ + rcecalib/HW \ + rcecalib/util \ + rcecalib/ipcclient + +tgtslib_cosmicGui := \ + dl\ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib)\ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) + +ifdef SQLDB + tgtslib_cosmicGui +=$(mysql_lib) +endif +#-------------------------------------------- + +tgtsrcs_dumpRceMod := dumpRceMod.cc +tgtslib_dumpRceMod := dl\ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) +tgtincs_dumpRceMod := \ + rcecalib \ + rcecalib/server +tgtlibs_dumpRceMod := \ + rcecalib/idl \ + rcecalib/ipcclient + +tgtsrcs_dumpRceScan := dumpRceScan.cc +tgtslib_dumpRceScan := dl\ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) +tgtincs_dumpRceScan := \ + rcecalib \ + rcecalib/server +tgtlibs_dumpRceScan := \ + rcecalib/idl \ + rcecalib/ipcclient + +tgtsrcs_calibGui := CalibGui.cc \ + ConfigGui.cc \ + GlobalConfigGui.cc \ + ScanGui.cc \ + PrimListGui.cc \ + DataExporter.cc \ + ScanLog.cc \ + IPCGuiCallback.cc \ + CallbackInfo.cc \ + calibGui_rootDict.cc + +guiheaders_calibGui := CalibGui.hh ScanGui.hh PrimListGui.hh ConfigGui.hh GlobalConfigGui.hh + + + +tgtincs_calibGui := \ + rcecalib \ + rcecalib/server + +tgtlibs_calibGui := \ + rcecalib/idl \ + rcecalib/analysis \ + rcecalib/ipcrootclient \ + rcecalib/ipcclient + +tgtslib_calibGui := \ + dl\ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) + +ifdef SQLDB + tgtslib_calibGui +=$(mysql_lib) +endif +#-------------------------------------------- +tgtsrcs_cosmicMonitoringGui := CosmicMonitoringGui.cc cosmicMonitoringGui_rootDict.cc CosmicMonitoringGuiEmbedded.cc ConfigGui.cc + +guiheaders_cosmicMonitoringGui := CosmicMonitoringGui.hh CosmicMonitoringGuiEmbedded.hh ConfigGui.hh + + +tgtincs_cosmicMonitoringGui := \ + rcecalib \ + rcecalib/server + + + +tgtlibs_cosmicMonitoringGui := \ + rcecalib/idl \ + rcecalib/eudaq \ + rcecalib/rceconfig \ + rcecalib/dataproc \ + rcecalib/HW \ + rcecalib/util \ + rcecalib/ipcclient + + + +tgtslib_cosmicMonitoringGui := \ + dl\ + $(z_lib) \ + $(rootlibs) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(omniorb_lib)\ + $(omnithread_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(oh_root_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) + +#-------------------------------------------- + +tgtsrcs_test_sctrl_server := test_server.cc +tgtincs_test_sctrl_server := \ + rcecalib + +tgtlibs_test_sctrl_server := \ + rcecalib/eudaq \ + $(rce_service) \ + $(rce_net) \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig + + +tgtslib_test_sctrl_server := \ + dl \ + $(z_lib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(tdaq_cmdline_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(boost_regex_lib) +#-------------------------------------------- + +tgtsrcs_rceOfflineProducer := RceOfflineProducer.cc \ + CosmicDataReceiver.cc \ + rceOfflineProducer_rootDict.cc \ + CosmicMonitoringGuiEmbedded.cc \ + ConfigGui.cc \ + CosmicOfflineDataProc.cc + +guiheaders_rceOfflineProducer := ConfigGui.hh CosmicMonitoringGuiEmbedded.hh + +tgtincs_rceOfflineProducer := \ + rcecalib \ + rcecalib/server + +tgtlibs_rceOfflineProducer := \ + rcecalib/eudaq \ + rcecalib/ipcclient \ + $(rce_service) \ + $(rce_net) \ + rcecalib/util \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/scanctrl \ + rcecalib/idl \ + rcecalib/rceconfig + + +tgtslib_rceOfflineProducer := \ + dl \ + $(z_lib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(rootlibs) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(tdaq_cmdline_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(boost_regex_lib) +#-------------------------------------------- + +tgtsrcs_sendBitStream := sendBitStream.cc +tgtincs_sendBitStream := \ + rcecalib + +tgtlibs_sendBitStream := \ + $(rce_service) \ + $(rce_net) \ + rcecalib/idl \ + rcecalib/util \ + rcecalib/rceconfig \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/eudaq \ + rcecalib/ipcclient + + +tgtslib_sendBitStream := \ + dl \ + $(zlib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(ers_lib) \ + $(owl_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) +#-------------------------------------------- + +tgtsrcs_sendRandomPattern := sendRandomPattern.cc +tgtincs_sendRandomPattern := \ + rcecalib + +tgtlibs_sendRandomPattern := \ + $(rce_service) \ + $(rce_net) \ + rcecalib/idl \ + rcecalib/util \ + rcecalib/rceconfig \ + rcecalib/HW \ + rcecalib/dataproc \ + rcecalib/eudaq \ + rcecalib/ipcclient + + +tgtslib_sendRandomPattern := \ + dl \ + $(zlib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(ers_lib) \ + $(owl_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(tdaq_cmdline_lib) \ + $(boost_regex_lib) + +#-------------------------------------------- +tgtsrcs_rebootHSIO := rebootHSIO.cc +tgtincs_rebootHSIO := \ + rcecalib + +tgtlibs_rebootHSIO := \ + rcecalib/idl \ + rcecalib/ipcclient + + +tgtslib_rebootHSIO := \ + dl \ + $(z_lib) \ + $(boost_thread_lib) \ + $(boost_date_time_lib) \ + $(owl_lib) \ + $(ers_lib) \ + $(ipc_lib) \ + $(is_lib) \ + $(rdb_lib) \ + $(oh_lib) \ + $(tdaq_cmdline_lib) \ + $(omniorb_lib) \ + $(omnithread_lib) \ + $(boost_regex_lib) + +#========================================================= +tgtsrcs_host_bootloader := host_bootloader.cc +tgtincs_host_bootloader := boost +tgtlibs_host_bootloader := $(rce_service) $(rce_net) rcecalib/rcecontrol +tgtslib_host_bootloader := /usr/lib/rt + +#========================================================= +tgtsrcs_testspeed := testspeed.cc EthPrimitive.cc +tgtincs_testspeed := boost +tgtlibs_testspeed := $(rce_service) $(rce_net) +tgtslib_testspeed := /usr/lib/rt + + +endif + diff --git a/rce/rcecalib/server/cosmicGui_Linkdef.hh b/rce/rcecalib/server/cosmicGui_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..b7c0ee9bfdfd2c68bc84123029abda81707ed8c2 --- /dev/null +++ b/rce/rcecalib/server/cosmicGui_Linkdef.hh @@ -0,0 +1,4 @@ +#pragma link C++ class CosmicGui; +#pragma link C++ class ConfigGui; +#pragma link C++ class GlobalConfigGui; +#pragma link C++ class CosmicMonitoringGuiEmbedded; diff --git a/rce/rcecalib/server/cosmicMonitoringGui_Linkdef.hh b/rce/rcecalib/server/cosmicMonitoringGui_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..a05abc78dfc233de844ff60294e22aebe648a91b --- /dev/null +++ b/rce/rcecalib/server/cosmicMonitoringGui_Linkdef.hh @@ -0,0 +1,4 @@ +#pragma link C++ class CosmicMonitoringGui; +#pragma link C++ class CosmicMonitoringGuiEmbedded; +#pragma link C++ class ConfigGui; + diff --git a/rce/rcecalib/server/delaycalib.cc b/rce/rcecalib/server/delaycalib.cc new file mode 100644 index 0000000000000000000000000000000000000000..3978e6cd950634bb7ab8a7958104da17dda5773b --- /dev/null +++ b/rce/rcecalib/server/delaycalib.cc @@ -0,0 +1,132 @@ +#include <stdio.h> + +#include <ers/ers.h> + +#include <ipc/partition.h> +#include <ipc/server.h> +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <cmdl/cmdargs.h> +#include <unistd.h> + +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/IPCHistoController.hh" +#include "rcecalib/server/PixScan.hh" + +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCFEI3Adapter.hh" +#include "ScanOptions.hh" +#include "PixelModuleConfig.hh" + +#include <TApplication.h> +#include <TROOT.h> +#include <TStyle.h> +#include <TCanvas.h> +#include <TH2F.h> +#include <TF1.h> +#include <TFile.h> +#include "rcecalib/server/Mean.hh" + +int acquireDataPoint(IPCController& controller); + +using namespace RCE; + +int main( int argc, char ** argv ) +{ + + TApplication *tapp; + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + IPCController controller(p); + IPCHistoController hcontroller(p); + unsigned serstat; + int rce=0; + serstat=controller.writeHWregister(rce, 7,0); + assert(serstat==0); + //for(int i=0;i<60;i++)controller.writeHWregister(6,0); + //for (int i=0;i<60;i++)controller.writeHWregister(6,0); + tapp=new TApplication("bla", &argc, argv); + + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + gStyle->SetOptFit(111); + gStyle->SetErrorX(0); + gStyle->SetMarkerStyle(20); + + TH1F* del1=new TH1F("delay1","Delay Disc 1 wrt Disc 0",13,-65.,65 ); + del1->GetXaxis()->SetTitle("Delay (IDELAY counts)"); + TCanvas *c1=new TCanvas("c1","Canvas",600,600); + del1->SetMinimum(0); + c1->Draw(); + del1->Draw("ep"); + sleep(1); + + PixScan* scn = new PixScan(PixScan::SCINTDELAY_SCAN, PixLib::EnumFEflavour::PM_FE_I2); + //scn->resetScan(); + //scn->setLoopVarValues(0, 0, 200, 101); + //scn->setRepetitions(50); + ipc::ScanOptions options; + scn->convertScanConfig(options); + controller.setupTrigger(); + controller.downloadScanConfig(options); + serstat=controller.writeHWregister(rce,8,2); + assert(serstat==0); + controller.startScan(); + int status=-1; + do{ + sleep(5); + status = controller.getScanStatus(); + std::vector<TH1*> his=hcontroller.getHistosFromIS("delhisto"); + TH1* histo=his[0]; + for(int i=0;i<histo->GetNbinsX();i++){ + del1->SetBinContent(i+1,histo->GetBinContent(i+1)); + del1->SetBinError(i+1,sqrt((float)histo->GetBinContent(i+1))); + } + del1->Draw("ep"); + c1->Update(); + delete histo; + }while (status !=0); + std::cout<<"Loop done"<<std::endl; + if(del1->GetEntries()>10){ + del1->Fit("gaus"); + float fitpar=del1->GetFunction("gaus")->GetParameter(1); + std::cout<<"Fit result: "<<fitpar<<"IDELAY counts delay."<<std::endl; + } + std::cout<<"Fit done"<<std::endl; + serstat=controller.writeHWregister(rce, 3,0); //Return to normal mode + assert(serstat==0); + TFile *file=new TFile("histos.root","recreate"); + del1->Write(); + file->Close(); + + tapp->Run(); +} diff --git a/rce/rcecalib/server/dumpRceMod.cc b/rce/rcecalib/server/dumpRceMod.cc new file mode 100644 index 0000000000000000000000000000000000000000..5881ecb9f5721eb6fd85dfdeb579ff2d9caf3dc5 --- /dev/null +++ b/rce/rcecalib/server/dumpRceMod.cc @@ -0,0 +1,46 @@ + +#include "rcecalib/server/GlobalConfigGui.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" +#include "rcecalib/server/FEI4BConfigFile.hh" +#include "rcecalib/server/TurboDaqFile.hh" +#include "PixelFEI4AConfig.hh" +#include "PixelFEI4BConfig.hh" +#include "PixelModuleConfig.hh" +#include "rcecalib/server/CalibGui.hh" +#include <iostream> +#include <boost/regex.hpp> +#include <sys/stat.h> +#include <string> + +int main(int argc,char *argv[]) +{ + + +ipc::PixelFEI4AConfig confa; +ipc::PixelFEI4BConfig confb; + +FEI4AConfigFile fei4afile; +FEI4BConfigFile fei4bfile; + int flavour=-1; + std::string filename(argv[1]); + try { + fei4afile.readModuleConfig(&confa,filename); + flavour=0; + } catch (...) { flavour=-1;} + if(flavour==-1) { + try { + fei4bfile.readModuleConfig(&confb,filename); + flavour=1; + } catch(...) {flavour=-1;} + + } + if(flavour==0) fei4afile.dump(confa); + if(flavour==1) fei4bfile.dump(confb); + + + + + return 0; + + +} diff --git a/rce/rcecalib/server/dumpRceScan.cc b/rce/rcecalib/server/dumpRceScan.cc new file mode 100644 index 0000000000000000000000000000000000000000..6732e7582468ccaf8fb5f48becccc51be647d4ed --- /dev/null +++ b/rce/rcecalib/server/dumpRceScan.cc @@ -0,0 +1,53 @@ +#include <iostream> +#include <boost/regex.hpp> +#include <sys/stat.h> +#include <string> +#include "rcecalib/server/PixScan.hh" +#include "ScanOptions.hh" +#include <cmdl/cmdargs.h> +#include "PixScanBase.h" +#include "PixEnumBase.h" +int main(int argc,char *argv[]) +{ + + + CmdArgBool list ('l', "list", "list all scans"); + CmdArgStr flavor ('f',"flavor", "module-flavor","specify module flavor"); + CmdArgStr name("[name]","name of scan"); + CmdLine cmd(*argv, &list,&flavor,&name, NULL); + + + CmdArgvIter arg_iter(--argc, ++argv); + int scanindex=-1; + cmd.parse(arg_iter); + PixLib::EnumFEflavour::FEflavour f; + f = PixLib::EnumFEflavour::PM_FE_I4A; + if(!list) { + if(!strcmp(flavor,"PM_FE_I4A")) f = PixLib::EnumFEflavour::PM_FE_I4A; + else if(!strcmp(flavor,"PM_FE_I4B")) f = PixLib::EnumFEflavour::PM_FE_I4B ; + else if(!strcmp(flavor,"PM_FE_I2")) f = PixLib::EnumFEflavour::PM_FE_I2 ; + else if(!list) {std::cout << "unkown flavor " << flavor << std::endl;return 1;} + } + PixLib::EnumScanType scantype; + std::map<std::string, int> scannames=scantype.EnumScanTypeMap(); + for (std::map <std::string, int>::const_iterator it = scannames.begin(); it != scannames.end(); ++it){ + std::string scanname=it->first; + scanindex=it->second; + if(!name.isNULL()) if(std::string((const char*)name)==scanname) break; + if(list) std::cout << scanname << std::endl; + } + if(list) return 0; + std::cout <<"Flavor: " <<flavor << std::endl; + std::cout <<"ScanName: " <<name << std::endl; + std::cout <<"ScanIndex: "<< scanindex<< std::endl; + ipc::ScanOptions scanopts; + RCE::PixScan scan((RCE::PixScan::ScanType) scanindex, f); + if(scan.presetRCE((RCE::PixScan::ScanType) scanindex, f)==true) { + + scan.convertScanConfig(scanopts); + scan.dump(std::cout,scanopts); + } + return 0; + + +} diff --git a/rce/rcecalib/server/ettcp.c b/rce/rcecalib/server/ettcp.c new file mode 100644 index 0000000000000000000000000000000000000000..b0401f1ed13267fe2db6802cc50e9ca5c3b8c9c7 --- /dev/null +++ b/rce/rcecalib/server/ettcp.c @@ -0,0 +1,922 @@ +/* + * N T T C P . C + * + * Test TCP connection. Makes a connection on port 5001 + * and transfers fabricated buffers or data copied from stdin. + * + * Usable on 4.2, 4.3, and 4.1a systems by defining one of + * BSD42 BSD43 (BSD41a) + * Machines using System V with BSD sockets should define SYSV. + * + * Modified for operation under 4.2BSD, 18 Dec 84 + * T.C. Slattery, USNA + * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85. + * Modified in 1989 at Silicon Graphics, Inc. + * catch SIGPIPE to be able to print stats when receiver has died + * for tcp, don't look for sentinel during reads to allow small transfers + * increased default buffer size to 8K, nbuf to 2K to transfer 16MB + * moved default port to 5001, beyond IPPORT_USERRESERVED + * make sinkmode default because it is more popular, + * -s now means don't sink/source + * count number of read/write system calls to see effects of + * blocking from full socket buffers + * for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt) + * buffer alignment options, -A and -O + * print stats in a format that's a bit easier to use with grep & awk + * for SYSV, mimic BSD routines to use most of the existing timing code + * Modified by Steve Miller of the University of Maryland, College Park + * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF) + * Modified Sept. 1989 at Silicon Graphics, Inc. + * restored -s sense at request of tcs@brl + * Modified Oct. 1991 at Silicon Graphics, Inc. + * use getopt(3) for option processing, add -f and -T options. + * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV. + * + * Modified by David Boreham <david@bozemanpass.com> + * to support call back mode + * + * Distribution Status - + * Public Domain. Distribution Unlimited. + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision: 1.12 $"; +#endif + +#define BSD43 +/* #define BSD42 */ +/* #define BSD41a */ +/* #define SYSV */ /* required on SGI IRIX releases before 3.3 */ + +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/time.h> /* struct timeval */ + +#if defined(SYSV) || defined(__rtems__) +#include <sys/times.h> +#include <sys/param.h> +struct rusage { + struct timeval ru_utime, ru_stime; +}; +#define RUSAGE_SELF 0 +#else +#include <sys/resource.h> +#endif + +#define SA( p ) ( (struct sockaddr *) (p) ) + +struct sockaddr_in sinme; +struct sockaddr_in sinhim; +struct sockaddr_in frominet; + +int domain, fromlen; +int fd; /* fd of network socket */ + +int buflen = 8 * 1024; /* length of buffer */ +char *buf; /* ptr to dynamic buffer */ +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16*1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ +int c_flag = 0; /* collect call mode */ +int q_flag = 0; /* keep quiet */ +int interval = 0; /* time interval to test over */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; + +char Usage[] = "\ +Usage: nttcp -t [-options] host [ < in ]\n\ + nttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -i ## \"interval\": number of seconds to run the test, rather than number of buffers\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: b,B = {bit,byte}; k,K = kilo{bit,byte}; m,M = mega; g,G = giga; r,R = raw {bit,byte}\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ + -c \"collect call\": initiate the TCP connection but then expect data sent from the other end\n\ + -q \"quiet\": only print the measured throughput, emit no other chatty output.\n\ +"; + +char stats[128]; +double nbytes; /* bytes on net */ +unsigned long numCalls; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +int err(); +void mes(); +int pattern(); +void prep_timer(); +double read_timer(); +double elapsed_time(); +int Nread(); +int Nwrite(); +void delay(); +int mread(); +char *outfmt(); + +void +sigpipe() +{ +} + +#ifdef __rtems__ +int ttcp_main(int argc,char *argv[]) +#else +int main(int argc,char **argv) +#endif +{ + unsigned long addr_tmp; + int c; + printf("in main\n"); + + if (argc < 2) goto usage; + printf("in main\n"); + while ((c = getopt(argc, argv, "cdrstuvBDTqb:f:l:n:p:A:O:i:")) != -1) { + switch (c) { + + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf(stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi(optarg); + break; + case 'l': + buflen = atoi(optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi(optarg); + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi(optarg); + break; + case 'O': + bufoffset = atoi(optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi(optarg); +#else + fprintf(stderr, +"ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + case 'c': + c_flag = 1; + break; + case 'q': + q_flag = 1; + break; + case 'i': + interval = atoi(optarg); + break; + + default: + goto usage; + } + } + if(trans || c_flag) { + /* xmitr */ + if (optind == argc) + goto usage; + bzero((char *)&sinhim, sizeof(sinhim)); + host = argv[optind]; + if (atoi(host) > 0 ) { + /* Numeric */ + sinhim.sin_family = AF_INET; +#if defined(cray) + addr_tmp = inet_addr(host); + sinhim.sin_addr = addr_tmp; +#else + sinhim.sin_addr.s_addr = inet_addr(host); +#endif + } else { + if ((addr=gethostbyname(host)) == NULL) + err("bad hostname"); + sinhim.sin_family = addr->h_addrtype; + bcopy(addr->h_addr,(char*)&addr_tmp, addr->h_length); +#if defined(cray) + sinhim.sin_addr = addr_tmp; +#else + sinhim.sin_addr.s_addr = addr_tmp; +#endif /* cray */ + } + sinhim.sin_port = htons(port); + sinme.sin_port = 0; /* free choice */ + } else { + /* rcvr */ + sinme.sin_port = htons(port); + } + + + if (udp && buflen < 5) { + buflen = 5; /* send more than the sentinel size */ + } + + if ( (buf = (char *)malloc(buflen+bufalign)) == (char *)NULL) + err("malloc"); + if (bufalign != 0) + buf +=(bufalign - ((int)buf % bufalign) + bufoffset) % bufalign; + + if (!q_flag) { + if (trans) { + fprintf(stdout, + "ttcp-t: buflen=%d, nbuf=%d, align=%d/%d, port=%d", + buflen, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf(stdout, ", sockbufsize=%d", sockbufsize); + fprintf(stdout, " %s -> %s\n", udp?"udp":"tcp", host); + } else { + fprintf(stdout, + "ttcp-r: buflen=%d, nbuf=%d, align=%d/%d, port=%d", + buflen, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf(stdout, ", sockbufsize=%d", sockbufsize); + fprintf(stdout, " %s\n", udp?"udp":"tcp"); + } + } /* !q_flag */ + + if ((fd = socket(AF_INET, udp?SOCK_DGRAM:SOCK_STREAM, 0)) < 0) + err("socket"); + if (!q_flag) mes("socket"); + + if (bind(fd, SA(&sinme), sizeof(sinme)) < 0) + err("bind"); + +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + if (sockbufsize) { + if (trans) { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, + sizeof sockbufsize) < 0) + err("setsockopt: sndbuf"); + mes("sndbuf"); + } else { + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sockbufsize, + sizeof sockbufsize) < 0) + err("setsockopt: rcvbuf"); + mes("rcvbuf"); + } + } +#endif + + if (!udp) { + signal(SIGPIPE, sigpipe); + if (trans || c_flag) { + /* We are the client if transmitting */ + if (options) { +#if defined(BSD42) + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) +#else /* BSD43 */ + if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) +#endif + err("setsockopt"); + } +#ifdef TCP_NODELAY + if (nodelay) { + struct protoent *p; + p = getprotobyname("tcp"); + if( p && setsockopt(fd, p->p_proto, TCP_NODELAY, + &one, sizeof(one)) < 0) + err("setsockopt: nodelay"); + mes("nodelay"); + } +#endif + if(connect(fd, SA(&sinhim), sizeof(sinhim) ) < 0) + err("connect"); + if (!q_flag) mes("connect"); + } else { + /* otherwise, we are the server and + * should listen for the connections + */ +#if defined(ultrix) || defined(sgi) + listen(fd,1); /* workaround for alleged u4.2 bug */ +#else + listen(fd,0); /* allow a queue of 0 */ +#endif + if(options) { +#if defined(BSD42) + if( setsockopt(fd, SOL_SOCKET, options, 0, 0) < 0) +#else /* BSD43 */ + if( setsockopt(fd, SOL_SOCKET, options, &one, sizeof(one)) < 0) +#endif + err("setsockopt"); + } + fromlen = sizeof(frominet); + domain = AF_INET; + if((fd=accept(fd, SA(&frominet), &fromlen) ) < 0) + err("accept"); + { struct sockaddr_in peer; + int peerlen = sizeof(peer); + if (getpeername(fd, SA(&peer), + &peerlen) < 0) { + err("getpeername"); + } + if (!q_flag) fprintf(stderr,"ttcp-r: accept from %s\n", + inet_ntoa(peer.sin_addr)); + } + } + } + prep_timer(); + errno = 0; + if (sinkmode) { + register int cnt; + if (trans) { + pattern( buf, buflen ); + if(udp) (void)Nwrite( fd, buf, 4 ); /* rcvr start */ + if (0 == interval) { + while (nbuf-- && Nwrite(fd,buf,buflen) == buflen) + nbytes += buflen; + } else { + while (Nwrite(fd,buf,buflen) == buflen) { + nbytes += buflen; + if (elapsed_time() > interval) { + break; + } + } + } + if(udp) (void)Nwrite( fd, buf, 4 ); /* rcvr end */ + } else { + if (udp) { + while ((cnt=Nread(fd,buf,buflen)) > 0) { + static int going = 0; + if( cnt <= 4 ) { + if( going ) + break; /* "EOF" */ + going = 1; + prep_timer(); + } else { + nbytes += cnt; + } + } + } else { + int total_bytes = nbuf * buflen; + while ((cnt=Nread(fd,buf,buflen)) > 0) { + nbytes += cnt; + if (c_flag && (0 == interval) ) { + total_bytes -= cnt; + if (total_bytes <= 0) { + break; + } + } + if (0 != interval) { + if (elapsed_time() > interval) { + break; + } + } + } + } + } + } else { + register int cnt; + if (trans) { + while((cnt=read(0,buf,buflen)) > 0 && + Nwrite(fd,buf,cnt) == cnt) + nbytes += cnt; + } else { + while((cnt=Nread(fd,buf,buflen)) > 0 && + write(1,buf,cnt) == cnt) + nbytes += cnt; + } + } + if(errno) err("IO"); + (void)read_timer(stats,sizeof(stats)); + if(udp&&trans) { + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ + (void)Nwrite( fd, buf, 4 ); /* rcvr end */ + } + if( cput <= 0.0 ) cput = 0.001; + if( realt <= 0.0 ) realt = 0.001; + if (q_flag) { + fprintf(stdout, + "%s\n", + outfmt(nbytes/realt)); + } else + { + fprintf(stdout, + "nttcp%s: %.0f bytes in %.2f real seconds = %s/sec +++\n", + trans?"-t":"-r", + nbytes, realt, outfmt(nbytes/realt)); + if (verbose) { + fprintf(stdout, + "nttcp%s: %.0f bytes in %.2f CPU seconds = %s/cpu sec\n", + trans?"-t":"-r", + nbytes, cput, outfmt(nbytes/cput)); + } + fprintf(stdout, + "nttcp%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans?"-t":"-r", + numCalls, + 1024.0 * realt/((double)numCalls), + ((double)numCalls)/realt); + fprintf(stdout,"nttcp%s: %s\n", trans?"-t":"-r", stats); + if (verbose) { + fprintf(stdout, + "nttcp%s: buffer address %#x\n", + trans?"-t":"-r", + buf); + } + } /* !q_flag */ + return(0); + +usage: + fprintf(stderr,Usage); + return(1); +} + +int +err(s) +char *s; +{ + fprintf(stderr,"nttcp%s: ", trans?"-t":"-r"); + perror(s); + fprintf(stderr,"errno=%d\n",errno); + return(1); +} + +void +mes(s) +char *s; +{ + fprintf(stderr,"nttcp%s: %s\n", trans?"-t":"-r", s); +} + +pattern( cp, cnt ) +register char *cp; +register int cnt; +{ + register char c; + c = 0; + while( cnt-- > 0 ) { + while( !isprint((c&0x7F)) ) c++; + *cp++ = (c++&0x7F); + } +} + +char * +outfmt(b) +double b; +{ + static char obuf[50]; + switch (fmt) { + case 'G': + sprintf(obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf(obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf(obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'B': + sprintf(obuf, "%.2f B", b ); + break; + case 'R': + sprintf(obuf, "%.2f", b ); + break; + case 'g': + sprintf(obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf(obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf(obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + case 'b': + sprintf(obuf, "%.2f bit", b * 8.0 ); + break; + case 'r': + sprintf(obuf, "%.2f", b * 8); + break; + } + return obuf; +} + +static struct timeval time0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +static void prusage(); +static void tvadd(); +static void tvsub(); +static void psecs(); + +#if defined(SYSV) || defined(__rtems__) +/*ARGSUSED*/ +static +getrusage(ignored, ru) + int ignored; + register struct rusage *ru; +{ + struct tms buf; + + times(&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} +#endif +#if defined(SYSV) && ! defined(__rtems__) +/*ARGSUSED*/ +static +gettimeofday(tp, zp) + struct timeval *tp; + struct timezone *zp; +{ + tp->tv_sec = time(0); + tp->tv_usec = 0; +} +#endif /* SYSV */ + +/* + * P R E P _ T I M E R + */ +void +prep_timer() +{ + gettimeofday(&time0, (struct timezone *)0); + getrusage(RUSAGE_SELF, &ru0); +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer(str,len) +char *str; +{ + struct timeval timedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage(RUSAGE_SELF, &ru1); + gettimeofday(&timedol, (struct timezone *)0); + prusage(&ru0, &ru1, &timedol, &time0, line); + (void)strncpy( str, line, len ); + + /* Get real time */ + tvsub( &td, &timedol, &time0 ); + realt = td.tv_sec + ((double)td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd( &tend, &ru1.ru_utime, &ru1.ru_stime ); + tvadd( &tstart, &ru0.ru_utime, &ru0.ru_stime ); + tvsub( &td, &tend, &tstart ); + cput = td.tv_sec + ((double)td.tv_usec) / 1000000; + if( cput < 0.00001 ) cput = 0.00001; + return( cput ); +} + +double +elapsed_time() +{ + struct timeval timedol; + struct timeval td; + double et = 0.0; + + gettimeofday(&timedol, (struct timezone *)0); + tvsub( &td, &timedol, &time0 ); + et = td.tv_sec + ((double)td.tv_usec) / 1000000; + + return( et ); +} + +static void +prusage(r0, r1, e, b, outp) + register struct rusage *r0, *r1; + struct timeval *e, *b; + char *outp; +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ + (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ + (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ + (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; + ms = (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) switch(*++cp) { + + case 'U': + tvsub(&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf(outp,"%d.%01d", tdiff.tv_sec, tdiff.tv_usec/100000); + END(outp); + break; + + case 'S': + tvsub(&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf(outp,"%d.%01d", tdiff.tv_sec, tdiff.tv_usec/100000); + END(outp); + break; + + case 'E': + psecs(ms / 100, outp); + END(outp); + break; + + case 'P': + sprintf(outp,"%d%%", (int) (t*100 / ((ms ? ms : 1)))); + END(outp); + break; + +#if !defined(SYSV) && !defined(__rtems__) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf(outp,"%d", i); + END(outp); + break; + + case 'X': + sprintf(outp,"%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t); + END(outp); + break; + + case 'D': + sprintf(outp,"%d", t == 0 ? 0 : + (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); + END(outp); + break; + + case 'K': + sprintf(outp,"%d", t == 0 ? 0 : + ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - + (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); + END(outp); + break; + + case 'M': + sprintf(outp,"%d", r1->ru_maxrss/2); + END(outp); + break; + + case 'F': + sprintf(outp,"%d", r1->ru_majflt-r0->ru_majflt); + END(outp); + break; + + case 'R': + sprintf(outp,"%d", r1->ru_minflt-r0->ru_minflt); + END(outp); + break; + + case 'I': + sprintf(outp,"%d", r1->ru_inblock-r0->ru_inblock); + END(outp); + break; + + case 'O': + sprintf(outp,"%d", r1->ru_oublock-r0->ru_oublock); + END(outp); + break; + case 'C': + sprintf(outp,"%d+%d", r1->ru_nvcsw-r0->ru_nvcsw, + r1->ru_nivcsw-r0->ru_nivcsw ); + END(outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd(tsum, t0, t1) + struct timeval *tsum, *t0, *t1; +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub(tdiff, t1, t0) + struct timeval *tdiff, *t1, *t0; +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs(l,cp) +long l; +register char *cp; +{ + register int i; + + i = l / 3600; + if (i) { + sprintf(cp,"%d:", i); + END(cp); + i = l % 3600; + sprintf(cp,"%d%d", (i/60) / 10, (i/60) % 10); + END(cp); + } else { + i = l; + sprintf(cp,"%d", i / 60); + END(cp); + } + i %= 60; + *cp++ = ':'; + sprintf(cp,"%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +Nread( fd, buf, count ) +int fd; +void *buf; +int count; +{ + struct sockaddr_in from; + int len = sizeof(from); + register int cnt; + if( udp ) { + cnt = recvfrom( fd, buf, count, 0, SA(&from), &len ); + numCalls++; + } else { + if( b_flag ) + cnt = mread( fd, buf, count ); /* fill buf */ + else { + cnt = read( fd, buf, count ); + numCalls++; + } + if (touchdata && cnt > 0) { + register int c = cnt, sum; + register char *b = buf; + while (c--) + sum += *b++; + } + } + return(cnt); +} + +/* + * N W R I T E + */ +Nwrite( fd, buf, count ) +int fd; +void *buf; +int count; +{ + register int cnt; + if( udp ) { +again: + cnt = sendto( fd, buf, count, 0, SA(&sinhim), sizeof(sinhim) ); + numCalls++; + if( cnt<0 && errno == ENOBUFS ) { + delay(18000); + errno = 0; + goto again; + } + } else { + cnt = write( fd, buf, count ); + numCalls++; + } + return(cnt); +} + +void +delay(us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void)select( 1, (fd_set*)0, (fd_set *)0, (fd_set *)0, &tv ); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread(fd, bufp, n) +int fd; +register char *bufp; +unsigned n; +{ + register unsigned count = 0; + register int nread; + + do { + nread = read(fd, bufp, n-count); + numCalls++; + if(nread < 0) { + perror("ttcp_mread"); + return(-1); + } + if(nread == 0) + return((int)count); + count += (unsigned)nread; + bufp += nread; + } while(count < n); + + return((int)count); +} diff --git a/rce/rcecalib/server/eudaqserver.cc b/rce/rcecalib/server/eudaqserver.cc new file mode 100644 index 0000000000000000000000000000000000000000..013f888493bf626b5868d0d493ed91bc5fee3213 --- /dev/null +++ b/rce/rcecalib/server/eudaqserver.cc @@ -0,0 +1,124 @@ +#include <stdio.h> +#include <unistd.h> + +#include <ers/ers.h> + +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> +#include <ipc/server.h> + +#include <owl/timer.h> +#include <owl/semaphore.h> + +#include <boost/regex.hpp> + +#include "rcecalib/scanctrl/IPCScan.cc" +#include "rcecalib/scanctrl/IPCScanRoot.cc" +#include "rcecalib/config/IPCConfigIF.cc" +#include "rcecalib/HW/SerialHexdump.hh" +#include "rcecalib/HW/SerialPgp.hh" +#include "rcecalib/HW/SerialPgpFei4.hh" +#include "rcecalib/config/IPCModuleFactory.hh" +#include "rcecalib/util/RceName.hh" + +#include "rcecalib/server/eudaqserver.hh" +#include "rcecalib/server/RceProducer.hh" + +#include <is/infoT.h> +#include <is/infodictionary.h> +#include <ipc/core.h> + +static IPCServer ipcServer; + +////////////////////////////////////////// +// +// Main function +// +////////////////////////////////////////// + + +void eudaqserver::run(bool ismodule, char* partition){ + +const char *cc_argv[] = +{ + "eudaqserver", /* always the name of the program */ + "-p", + "rcetest", + // "-ORBtraceLevel", /* trace level */ + //"1", + "-ORBgiopMaxMsgSize", + "33554422", /* max message size 32 MB */ + "-ORBmaxServerThreadPerConnection", "1" +// "-ORBendPoint", +// " giop:tcp:192.168.1.35:" + //"-ORBtraceInvocations", + //"1" +}; + if(partition)cc_argv[2]=partition; +int cc_argc = sizeof( cc_argv ) / sizeof( cc_argv[ 0 ] ); + try { + IPCCore::init( cc_argc, (char**)cc_argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return; + } + + // Declare command object and its argument-iterator + + IPCPartition p((const char*)cc_argv[2]); + printf("Partition is %s\n",cc_argv[2]); + char name[128]; + sprintf(name, "configIF_RCE%d", RceName::getRceNumber()); + p.isObjectValid<ipc::IPCConfigIFAdapter>(name); + + //Serial IF + new SerialPgpFei4; + + //Module Factory + + ModuleFactory *moduleFactory=new IPCModuleFactory(p); + + // Config IF + + IPCConfigIF<ipc::single_thread> *cif; + IPCScan<ipc::multi_thread> *scan; + IPCScanRoot<ipc::single_thread> * scanroot; + + try{ + cif=new IPCConfigIF<ipc::single_thread>(p, name, moduleFactory); + sprintf(name, "scanCtrl_RCE%d", RceName::getRceNumber()); + scan = new IPCScan<ipc::multi_thread>( p, name); + sprintf(name, "scanRoot_RCE%d", RceName::getRceNumber()); + scanroot = new IPCScanRoot<ipc::single_thread>( p, name, (ConfigIF*)cif, (Scan*)scan); + }catch(...){ + std::cout<<"Could not add IPC objects (ipc_server not running? Several servers in the same partition?)."<<std::endl; + assert(0); + } + + IPCHistoManager *hm; + try{ + sprintf(name, "RCE%d",RceName::getRceNumber()); + hm=new IPCHistoManager(p,"RceIsServer", name); + }catch(...){ + std::cout<<"Could not start histogram manager (is_server not running? Another server running on the same partition?)."<<std::endl; + assert(0); + } + printf("ipc_test_server has been started.\n"); + + + RceProducer producer("RceProducer", "tcp://172.21.7.146:44000", p); + //RceProducer producer("RceProducer", "tcp://rdcds105:44000", p); + if(ismodule==true){ + kill(getpid(),SIGUSR1); + pause(); + }else{ + ipcServer.run(); + } + + scan->_destroy(); + scanroot->_destroy(); + + std::cout << "Test successfully completed." << std::endl; +} diff --git a/rce/rcecalib/server/eudaqserver.hh b/rce/rcecalib/server/eudaqserver.hh new file mode 100644 index 0000000000000000000000000000000000000000..416633f46401bf7f6655355b540fce52fb01d3b5 --- /dev/null +++ b/rce/rcecalib/server/eudaqserver.hh @@ -0,0 +1,11 @@ +#ifndef EUDAQSERVER_HH +#define EUDAQSERVER_HH + +class eudaqserver { + public: + eudaqserver(){}; + static void run(bool ismodule, char* partition); + +}; + +#endif diff --git a/rce/rcecalib/server/host_bootloader.cc b/rce/rcecalib/server/host_bootloader.cc new file mode 100644 index 0000000000000000000000000000000000000000..87a5b21c69bc5bdfa141050c5d9921fb6de6063b --- /dev/null +++ b/rce/rcecalib/server/host_bootloader.cc @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <iostream> +#include <fstream> +#include <string.h> +#include "rcecalib/server/BootLoaderPort.hh" +#include <boost/algorithm/string.hpp> +#include "RceControl.hh" +#include <termios.h> + +#include <arpa/inet.h> // for htonl + + +int main(int argc, char** argv) +{ + extern char* optarg; + int c; + const char* scriptname=0; + const char* filename=0; + + const char* rce=0; + const char *iorfile=0; + while ( (c=getopt( argc, argv, "r:s:l:i:")) != EOF ) { + switch(c) { + case 'r': + rce=optarg; + break; + case 's': + scriptname = optarg; + break; + case 'l': + filename = optarg; + break; + case 'i': + iorfile = optarg; + break; + } + } + RCE::RceControl rcecontrol; + try { + rcecontrol =RCE::RceControl(rce); + } catch(...) { + std::cout<<"Usage: host_bootloader -r IP_address [-s config_file] [-l sharedlib.so] [-i ior_file]"<<std::endl; + return 0; + } + std::string inpline; + std::istream *inp; + if(scriptname){ + std::ifstream* inpf= new std::ifstream (scriptname); + if (!inpf->is_open()){ + std::cout<<"File "<<scriptname<<" not found. Exiting."<<std::endl; + exit(1); + } + inp=(std::istream*)inpf; + }else{ + inp = &std::cin; + struct termios tios; + // Make sure backspace works in the terminal window. + tcgetattr(STDIN_FILENO, &tios); + if(tios.c_cc[VERASE]!=0x7f){ + tios.c_cc[VERASE]=0x7f; // set backspace as erase + tcsetattr(STDIN_FILENO,TCSANOW, &tios); + } + } + while (true){ //main loop + getline (*inp,inpline); + if(inp->eof())break; + boost::trim(inpline); + if(inpline.size()!=0 && inpline[0]!='#'){ + rcecontrol.sendCommand(inpline); + } + } + // option -i: read iorfile and set TDAQ_IPC_INIT_REF + rcecontrol.setIorFromFile(iorfile); + + + //option -l: download shared library. + if(filename){ + if(rcecontrol.loadModule(filename)) exit(-1); + } +} + diff --git a/rce/rcecalib/server/rceOfflineProducer_Linkdef.hh b/rce/rcecalib/server/rceOfflineProducer_Linkdef.hh new file mode 100644 index 0000000000000000000000000000000000000000..fe7635f724dfa7994cd111fbcba3e4f7e9164b3c --- /dev/null +++ b/rce/rcecalib/server/rceOfflineProducer_Linkdef.hh @@ -0,0 +1,2 @@ +#pragma link C++ class ConfigGui; +#pragma link C++ class CosmicMonitoringGuiEmbedded; diff --git a/rce/rcecalib/server/rebootHSIO.cc b/rce/rcecalib/server/rebootHSIO.cc new file mode 100644 index 0000000000000000000000000000000000000000..fd015e03b6dcaeffade9a40335b6be3b785a3e1a --- /dev/null +++ b/rce/rcecalib/server/rebootHSIO.cc @@ -0,0 +1,82 @@ + +#include <ipc/partition.h> +#include <ipc/core.h> +//#include <ipc/server.h> +#include <ipc/object.h> +#include <boost/regex.hpp> +#include "rcecalib/server/IPCController.hh" +#include "IPCConfigIFAdapter.hh" + +#include <cmdl/cmdargs.h> +#include <iostream> +#include <stdlib.h> + +int main( int argc, char ** argv ){ + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + //CmdArgInt rce ('r', "rce","rce-number", "number of the RCE that has the HSIO attached"); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + //CmdLine cmd(*argv, &partition_name, &rce, NULL); + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + //std::cout << partition_name.isNULL() << std::endl; + + const char *p_name=getenv("TDAQ_PARTITION"); + if(p_name==NULL) p_name="rcetest"; + if(! partition_name.isNULL()) p_name= (const char*)partition_name; + IPCPartition p(p_name ); + IPCController controller(p); + // How many RCEs are in the partition? + std::map< std::string, ipc::IPCConfigIFAdapter_var > objects; + std::vector<int> rces; + p.getObjects<ipc::IPCConfigIFAdapter>( objects ); + std::map< std::string, ipc::IPCConfigIFAdapter_var >::iterator it; + for ( it = objects.begin(); it != objects.end(); it++ ){ + boost::regex re("configIF_RCE(\\d+)"); + boost::cmatch matches; + if(boost::regex_search(it->first.c_str(), matches, re)){ + assert(matches.size()>1); + std::string match(matches[1].first, matches[1].second); + rces.push_back(strtol(match.c_str(),0,10)); + } + } + if(rces.size()==0){ + std::cout<<"No RCE in your partition. Exiting."<<std::endl; + exit(0); + } + int rce=rces[0]; + if(rces.size()>1){ + std::cout<<"There are multiple RCEs in your partition:"<<std::endl; + while(1){ + for(size_t i=0;i<rces.size();i++)std::cout<<rces[i]<<std::endl; + std::cout<<"Which one has the HSIO attached that you would like to reboot (99 = all)?"<<std::endl; + std::cin>>rce; + bool valid=false; + for(size_t i=0;i<rces.size();i++)if(rce==99 || rce==rces[i])valid=true; + if(valid)break; + std::cout<<"This RCE is not on the list. Try again."<<std::endl; + } + } + for(size_t i=0;i<rces.size();i++){ + if(rce==99||rce==rces[i]){ + controller.addRce(rces[i]); + std::cout<<"Rebooting HSIO on RCE "<<rces[i]<<std::endl; + controller.sendHWcommand(rces[i],8); //reboot + } + } +} diff --git a/rce/rcecalib/server/rtems_config.cc b/rce/rcecalib/server/rtems_config.cc new file mode 100644 index 0000000000000000000000000000000000000000..d72b02f0a6a37cd3237103463bba916626305cda --- /dev/null +++ b/rce/rcecalib/server/rtems_config.cc @@ -0,0 +1,68 @@ +//#define CONFIGURE_STACK_CHECKER_ENABLED +//#define STACK_CHECKER_ON +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER + +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20 +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_SEMAPHORES 100 +#define CONFIGURE_MAXIMUM_PARTITIONS 10 +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 +#define CONFIGURE_MAXIMUM_DRIVERS 10 + + +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 + +#define CONFIGURE_EXECUTIVE_RAM_SIZE (4096*1024) +//#define CONFIGURE_EXTRA_TASK_STACKS (256*1024) +// for telnetd and shell and IMFS +#define RTEMS_NETWORKING +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 50 +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK +#define CONFIGURE_MAXIMUM_PTYS 4 + +#define CONFIGURE_SHELL_COMMANDS_INIT +#define CONFIGURE_SHELL_COMMANDS_ALL +#define CONFIGURE_SHELL_MOUNT_TFTP +#define CONFIGURE_SHELL_MOUNT_FTP +#define CONFIGURE_SHELL_MOUNT_NFS + +#include <rtems/shellconfig.h> + +#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM +#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK 256 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE +#define CONFIGURE_INIT + +/* POSIX API resources */ +#define CONFIGURE_MAXIMUM_POSIX_THREADS 100 +#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 100 +#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 100 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1024 +#define CONFIGURE_MAXIMUM_POSIX_TIMERS 100 +#define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 100 +#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 100 +#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 100 +#define CONFIGURE_MINIMUM_TASK_STACK_SIZE 16384 + + +//extern "C" void *POSIX_Init( void *argument ); +//#define CONFIGURE_INIT_TASK_STACK_SIZE (64*1024) + +//#define CONFIGURE_POSIX_INIT_THREAD_TABLE + + + +// to enable malloc statistics +#define CONFIGURE_MALLOC_STATISTICS + + +#include <rtems.h> + +extern "C" rtems_task Init(rtems_task_argument); + +#include <rtems/confdefs.h> +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (256*1024) diff --git a/rce/rcecalib/server/rtems_config_2.2.cc b/rce/rcecalib/server/rtems_config_2.2.cc new file mode 100644 index 0000000000000000000000000000000000000000..93090554dc076d9cad0659f78c33cd649b09df01 --- /dev/null +++ b/rce/rcecalib/server/rtems_config_2.2.cc @@ -0,0 +1,127 @@ +#ifndef CONFIGURATION_RTEMS_RCE_DEVEL_HH +#define CONFIGURATION_RTEMS_RCE_DEVEL_HH + +// See the RTEMS C USer's Guide Chanper 23, "Configuring a System" +// Modified for RTEMS 4.10.0. + +// The file configure_template.cc lists all the available options and +// gives a brief explanation of each. + +#include <rtems.h> + +#define CONFIGURE_INIT + +///////////////////////////// +// 23.2.1: Library support // +///////////////////////////// +//combine RTEMS workspace and C heap +#define CONFIGURE_UNIFIED_WORK_AREAS + +#define CONFIGURE_MALLOC_STATISTICS +#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS (20) +#define CONFIGURE_MAXIMUM_PTYS (4) +#define CONFIGURE_STACK_CHECKER_ENABLED +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK +#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK (256) +#define CONFIGURE_FILESYSTEM_FTPFS +#define CONFIGURE_FILESYSTEM_IMFS +#define CONFIGURE_FILESYSTEM_NFS + +////////////////////////////////////// +// 23.2.2: Basic system information // +////////////////////////////////////// + +// These RCE-specific definitions will be used both here and in the +// section setting limits on the numbers of classic RTEMS objects. We +// expect that most applications will use the queue types defined in +// the RCE core so our limits here are rather small. +namespace { + enum {RCE_MAX_RTEMS_MSG_QUEUES = 10, + RCE_MAX_BYTES_PER_MSG = 8, // Enough for a regular pointer or a std::tr1::smart_ptr. + RCE_MAX_MSGS_PER_QUEUE = 100 + }; +} + +#define CONFIGURE_MESSAGE_BUFFER_MEMORY \ + (RCE_MAX_RTEMS_MSG_QUEUES * \ + CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(RCE_MAX_MSGS_PER_QUEUE,RCE_MAX_BYTES_PER_MSG)\ + ) + +// Some applications are known to require extra stack space, e.g., +// Martin Kocian's PGP test. +#define CONFIGURE_MICROSECONDS_PER_TICK 10000 +//#define CONFIGURE_EXECUTIVE_RAM_SIZE (4096*1024) +#define CONFIGURE_EXTRA_TASK_STACKS (4096*1024*2) + +///////////////////////////////// +// 23.2.4: Device driver table // +///////////////////////////////// +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER +#define CONFIGURE_MAXIMUM_DRIVERS (11) + +///////////////////////// +// 23.2.6: Classic API // +///////////////////////// +#define CONFIGURE_MAXIMUM_TASKS (50) +#define CONFIGURE_MAXIMUM_TIMERS (20) +#define CONFIGURE_MAXIMUM_SEMAPHORES (100) +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES (RCE_MAX_RTEMS_MSG_QUEUES) +#define CONFIGURE_MAXIMUM_PARTITIONS (10) +#define CONFIGURE_MAXIMUM_REGIONS (10) +#define CONFIGURE_MAXIMUM_PORTS (10) +#define CONFIGURE_MAXIMUM_PERIODS (10) +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS (5) +// One of the user extensions is defined by the BSP to delete tasks +// that exit from their main functions (entry points). Normally RTEMS +// treats that as an error. + +////////////////////////////////////////// +// 23.2.7: Classic API Init-tasks table // +////////////////////////////////////////// +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +//#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (128*1024) +//#define CONFIGURE_POSIX_INIT_THREAD_TABLE +//extern "C" void *POSIX_Init( void *argument ); +////////////////////////////// +// 23.3 Configuration table // +////////////////////////////// +#define CONFIGURE_CONFDEFS_DEBUG + +///////////////////////////////////////////////////////////// +// Enable to print information about the work area and heap// +///////////////////////////////////////////////////////////// +//#define BSP_GET_WORK_AREA_DEBUG + +/* POSIX API resources */ +#define CONFIGURE_MAXIMUM_POSIX_THREADS 100 +#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 100 +#define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 100 +#define CONFIGURE_MAXIMUM_POSIX_KEYS 1024 +#define CONFIGURE_MAXIMUM_POSIX_TIMERS 100 +#define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 100 +#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 100 +#define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS 100 +#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 100 +#define CONFIGURE_MAXIMUM_POSIX_BARRIERS 100 +#define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS 100 +#define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 100 +#define CONFIGURE_MINIMUM_TASK_STACK_SIZE 16384 +#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (256*1024) +#include <rtems/confdefs.h> + +///////////////// +// RTEMS shell // +///////////////// +#define CONFIGURE_SHELL_COMMANDS_INIT +#define CONFIGURE_SHELL_COMMANDS_ALL +#define CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING +#define CONFIGURE_SHELL_MOUNT_NFS + +#include <rtems/shellconfig.h> + +#endif diff --git a/rce/rcecalib/server/runeudaqserver.cc b/rce/rcecalib/server/runeudaqserver.cc new file mode 100644 index 0000000000000000000000000000000000000000..a1fd37bc43aaa0e5446afa802df5201de0e54ef7 --- /dev/null +++ b/rce/rcecalib/server/runeudaqserver.cc @@ -0,0 +1,125 @@ +/// @file core.cc +/// @brief As the last part of the initialization of the system after +/// a reboot, load from flash, relocate and run the application module +/// selected by the RCE front panel. + + +#include "rce/debug/Debug.hh" +#include "rce/debug/Print.hh" +#include "rce/shell/ShellCommon.hh" +#include "rce/gdbstub/rtems-gdb-stub.h" + + +#include "rce/service/Thread.hh" +#include "rceusr/init/NetworkConfig.hh" +#include "rceusr/tool/DebugHandler.hh" + +#include "rce/pgp/DriverList.hh" + +extern "C"{ + #include <librtemsNfs.h> +} + +#include <omnithread.h> +#include <pthread.h> +#include "eudaqserver.hh" + +#include <exception> +#include <stdio.h> +#include <string> + +#include <iostream> + +// We need to include <iostream> so that symbolic references to +// std::cout et al. are made. The weak definitions will therefore be +// picked up from libstdc++. Modules are not linked against libstdc++ +// so they rely on the definitions in the core. +#include <iostream> + +using std::exception; +using std::string; + +using RCE::Shell::startShell; + +using RceDebug::printv; + +using RceInit::configure_network_from_dhcp; + +using RceSvc::Exception; + +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; + +extern "C" { + + // This symbol is set by the static linker (ld) to the start if the + // "dynamic section" which the linker uses to find the system symbol + // table. + extern const char _DYNAMIC; + + void *posix_init( void *argument ); +#if RCE_INTERFACE == 1 +#warning RCE_INTERFACE=1 +#elif RCE_INTERFACE == 0 +#warning RCE_INTERFACE=0 +#else +#error invalid RCE_INTERFACE +#endif + + + unsigned interface = RCE_INTERFACE; + void init_executive() + { + try { + RceInit::configure_network_from_dhcp(interface); + RcePgp::init_pgp(); + printf("starting shell\n"); + startShell(); + // Start a debugger daemon + // First arg = 0 --> use socket IO over TCP. + // Second arg = 0 --> Priority is chosen by the debugger daemon + rtems_gdb_start(0, 0); + + rpcUdpInit(); + nfsInit( 0, 0 ); + printf("BOOTP server is %s. Use as NFS server.\n",inet_ntoa( rtems_bsdnet_bootp_server_address)); + nfsMount(inet_ntoa( rtems_bsdnet_bootp_server_address), (char*)NFSDIR ,(char*)"/nfs"); //NFSDIR comes from constituents.mk + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + + + } catch (Exception& e) { + printv("*** RCE exception %s", e.what()); + } catch (exception& e) { + printv("*** C++ exception %s", e.what()); + } + printf("Done with init_executive"); + } +void *posix_init( void *argument ){ + printf("posixinit\n"); + std::cout<<"Init Exec called"<<std::endl; + omni_thread::init_t omni_thread_init; + pthread_attr_t attr; + size_t st = 0; + pthread_attr_init(&attr); + pthread_attr_getstacksize( &attr, &st ); + st = _Thread_Executing->Start.Initial_stack.size; + printf( "Init Task Stack Size is: %d\n", st ); + + // char* bla=new char[10000000]; + eudaqserver::run(); + printf("posixinit done\n"); + return 0; +} +} diff --git a/rce/rcecalib/server/runeudaqservermod.cc b/rce/rcecalib/server/runeudaqservermod.cc new file mode 100644 index 0000000000000000000000000000000000000000..9379f3fd126b5d14fb960deb8d48e1e12ea25961 --- /dev/null +++ b/rce/rcecalib/server/runeudaqservermod.cc @@ -0,0 +1,106 @@ +/// @file core.cc +/// @brief As the last part of the initialization of the system after +/// a reboot, load from flash, relocate and run the application module +/// selected by the RCE front panel. + + +#include "rce/debug/Debug.hh" +#include "rce/debug/Print.hh" +//#include "rce/shell/ShellCommon.hh" + + +#include "rce/service/Thread.hh" +#include "rce/service/Exception.hh" +//#include "rceusr/init/NetworkConfig.hh" +//#include "rceusr/tool/DebugHandler.hh" + +#include "rce/pgp/DriverList.hh" + +//extern "C"{ +// #include <librtemsNfs.h> +//} + +#include <omnithread.h> +#include "eudaqserver.hh" + +#include <exception> +#include <stdio.h> +#include <stdlib.h> +#include <string> + +#include <iostream> + +// We need to include <iostream> so that symbolic references to +// std::cout et al. are made. The weak definitions will therefore be +// picked up from libstdc++. Modules are not linked against libstdc++ +// so they rely on the definitions in the core. +#include <iostream> + +using std::exception; +using std::string; + +//using RCE::Shell::startShell; + +using RceDebug::printv; + +//using RceInit::configure_network_from_dhcp; + +using RceSvc::Exception; + +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; +//extern char **environ; + + +extern "C" { + + // This symbol is set by the static linker (ld) to the start if the + // "dynamic section" which the linker uses to find the system symbol + // table. + extern const char _DYNAMIC; + + void *posix_init( void *argument ); + + + rtems_task rce_appmain(rtems_task_argument arg) + { + try { + printf("rce_appmain\n"); + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + + + } catch (Exception& e) { + printv("*** RCE exception %s", e.what()); + } catch (exception& e) { + printv("*** C++ exception %s", e.what()); + } + printf("Done with init_executive"); + } +void *posix_init( void *argument ){ + printf("posixinit\n"); + std::cout<<"Init Exec called"<<std::endl; + omni_thread::init_t omni_thread_init; + pthread_attr_t attr; + size_t st = 0; + pthread_attr_init(&attr); + pthread_attr_getstacksize( &attr, &st ); + st = _Thread_Executing->Start.Initial_stack.size; + printf( "Init Task Stack Size is: %d\n", st ); + char* partition=getenv("TDAQ_PARTITION"); + eudaqserver::run(true, partition); // if 0 then the default partition will be rcetest + printf("posixinit done\n"); + return 0; +} +} diff --git a/rce/rcecalib/server/runserver.cc b/rce/rcecalib/server/runserver.cc new file mode 100644 index 0000000000000000000000000000000000000000..5dd3f99622968a619be8be7dfcc4e2265df29d72 --- /dev/null +++ b/rce/rcecalib/server/runserver.cc @@ -0,0 +1,127 @@ +/// @file core.cc +/// @brief As the last part of the initialization of the system after +/// a reboot, load from flash, relocate and run the application module +/// selected by the RCE front panel. + +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( service, fci, Exception.hh) +#else +#include "rce/debug/Debug.hh" +#include "rce/debug/Print.hh" +#include "rce/shell/ShellCommon.hh" +#include "rce/gdbstub/rtems-gdb-stub.h" + + +#include "rce/service/Thread.hh" +#include "rceusr/init/NetworkConfig.hh" +#include "rceusr/tool/DebugHandler.hh" + +#include "rce/pgp/DriverList.hh" + +extern "C"{ + #include <librtemsNfs.h> +} +#endif + +#include <omnithread.h> +#include <pthread.h> +#include "calibserver.hh" + +#include <exception> +#include <stdio.h> +#include <string> + +#include <iostream> + +// We need to include <iostream> so that symbolic references to +// std::cout et al. are made. The weak definitions will therefore be +// picked up from libstdc++. Modules are not linked against libstdc++ +// so they rely on the definitions in the core. +#include <iostream> + +using std::exception; +using std::string; + +using RCE::Shell::startShell; + +using RceDebug::printv; + +using RceInit::configure_network_from_dhcp; + +using RceSvc::Exception; + +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; + +extern "C" { + + // This symbol is set by the static linker (ld) to the start if the + // "dynamic section" which the linker uses to find the system symbol + // table. + extern const char _DYNAMIC; + + void *posix_init( void *argument ); +#if RCE_INTERFACE == 1 +#warning RCE_INTERFACE=1 +#elif RCE_INTERFACE == 0 +#warning RCE_INTERFACE=0 +#else +#error invalid RCE_INTERFACE +#endif + + + unsigned interface = RCE_INTERFACE; + void init_executive() + { + try { + RceInit::configure_network_from_dhcp(interface); + RcePgp::init_pgp(); + printf("starting shell\n"); + startShell(); + // Start a debugger daemon + // First arg = 0 --> use socket IO over TCP. + // Second arg = 0 --> Priority is chosen by the debugger daemon + rtems_gdb_start(0, 0); + + rpcUdpInit(); + nfsInit( 0, 0 ); + printf("BOOTP server is %s. Use as NFS server.\n",inet_ntoa( rtems_bsdnet_bootp_server_address)); + nfsMount(inet_ntoa( rtems_bsdnet_bootp_server_address),(char*) NFSDIR ,(char*)"/nfs"); //NFSDIR comes from constituents.mk + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + + + } catch (Exception& e) { + printv("*** RCE exception %s", e.what()); + } catch (exception& e) { + printv("*** C++ exception %s", e.what()); + } + printf("Done with init_executive"); + } +void *posix_init( void *argument ){ + printf("posixinit\n"); + std::cout<<"Init Exec called"<<std::endl; + omni_thread::init_t omni_thread_init; + pthread_attr_t attr; + size_t st = 0; + pthread_attr_init(&attr); + pthread_attr_getstacksize( &attr, &st ); + st = _Thread_Executing->Start.Initial_stack.size; + printf( "Init Task Stack Size is: %d\n", st ); + calibserver::run(false); + printf("posixinit done\n"); + return 0; +} +} diff --git a/rce/rcecalib/server/runservermod.cc b/rce/rcecalib/server/runservermod.cc new file mode 100644 index 0000000000000000000000000000000000000000..3187c18c7fe80f6331769e34bbdc2fb71003f93d --- /dev/null +++ b/rce/rcecalib/server/runservermod.cc @@ -0,0 +1,117 @@ +/// @file core.cc +/// @brief As the last part of the initialization of the system after +/// a reboot, load from flash, relocate and run the application module +/// selected by the RCE front panel. + +#ifdef RCE_V2 +#include "datCode.hh" +#include DAT_PUBLIC( service, fci, Exception.hh) +#include DAT_PUBLIC( service, debug, Print.hh) +#else +#include "rce/debug/Debug.hh" +#include "rce/debug/Print.hh" +//#include "rce/shell/ShellCommon.hh" +#include "rce/service/Thread.hh" +#include "rce/service/Exception.hh" +//#include "rceusr/init/NetworkConfig.hh" +//#include "rceusr/tool/DebugHandler.hh" + +#include "rce/pgp/DriverList.hh" +//extern "C"{ +// #include <librtemsNfs.h> +//} + +#endif +#include "namespace_aliases.hh" +#include <omnithread.h> +#include "calibserver.hh" +#include <limits.h> +#include <exception> +#include <stdio.h> +#include <stdlib.h> +#include <string> + +#include <iostream> + +// We need to include <iostream> so that symbolic references to +// std::cout et al. are made. The weak definitions will therefore be +// picked up from libstdc++. Modules are not linked against libstdc++ +// so they rely on the definitions in the core. +#include <iostream> + +using std::exception; +using std::string; + +//using RCE::Shell::startShell; + +using RceDebug::printv; + +//using RceInit::configure_network_from_dhcp; + +using RceSvc::Exception; + +// use global IP address of bootp server in RTEMS +extern struct in_addr rtems_bsdnet_bootp_server_address; +//extern char **environ; + + +extern "C" { + + // This symbol is set by the static linker (ld) to the start if the + // "dynamic section" which the linker uses to find the system symbol + // table. + extern const char _DYNAMIC; + + void *posix_init( void *argument ); + + +#ifdef RCE_V2 + void rce_appmain(void* arg) +#else + rtems_task rce_appmain(rtems_task_argument arg) +#endif + { + try { + printf("rce_appmain\n"); + pthread_t mthread; + pthread_attr_t attr; + int stacksize; + int ret; + // setting a new size + stacksize = (PTHREAD_STACK_MIN + 0x20000); + // void* stackbase = (void *) malloc(size); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, stacksize); + struct sched_param sparam; + sparam.sched_priority = 5; + pthread_attr_setschedparam(&attr, &sparam); + pthread_create( &mthread, &attr , posix_init, NULL); + + + } catch (Exception& e) { + printv("*** RCE exception %s", e.what()); + } catch (exception& e) { + printv("*** C++ exception %s", e.what()); + } + printf("Done with init_executive"); + } +void *posix_init( void *argument ){ + printf("posixinit\n"); + std::cout<<"Init Exec called"<<std::endl; + omni_thread::init_t omni_thread_init; + pthread_attr_t attr; + size_t st = 0; + pthread_attr_init(&attr); + pthread_attr_getstacksize( &attr, &st ); +#ifdef RCE_V2 + //st = _Per_CPU_Information_Executing->Start.Initial_stack.size; +#else + st = _Thread_Executing->Start.Initial_stack.size; +#endif + printf( "Init Task Stack Size is: %d\n", st ); + char* partition=getenv("TDAQ_PARTITION"); + calibserver::run(true, partition); // if 0 then the default partition will be rcetest + printf("posixinit done\n"); + return 0; +} +} diff --git a/rce/rcecalib/server/sendBitStream.cc b/rce/rcecalib/server/sendBitStream.cc new file mode 100644 index 0000000000000000000000000000000000000000..23a45625a7728b9901698ecdea78c0bd83864432 --- /dev/null +++ b/rce/rcecalib/server/sendBitStream.cc @@ -0,0 +1,604 @@ + +#include <ipc/partition.h> +#include <ipc/core.h> +#include <ipc/server.h> +#include <ipc/object.h> + +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/PixScan.hh" +#include "ScanOptions.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" + +#include <cmdl/cmdargs.h> +#include <iostream> +#include <stdio.h> + +typedef struct { + uint16_t DB0; // (bitmask, one bit set) + uint16_t DB1; // (bitmask, one bit set) + uint16_t DB2; // (bitmask, one bit set) + uint16_t DB3; // (bitmask, one bit set) + uint16_t DB4; // (bitmask, one bit set) + uint16_t DB5; // (bitmask, one bit set) + uint16_t DB6; // (bitmask, one bit set) + uint16_t DB7; // (bitmask, one bit set) + uint16_t RS; // (bitmask, one bit set) + uint16_t RW; // (bitmask, one bit set) + uint16_t EN; // (bitmask, one bit set) + IPCController* controller; + int rce; +} HD44780_t; +static HD44780_t lcd = { 1 << 8, + 1 << 9, + 1 << 10, + 1 << 11, + 1 << 12, + 1 << 13, + 1 << 14, + 1 << 15, + 1 << 0, + 1 << 1, + 1 << 2, + 0, + 0}; + +HD44780_t* lcdp = &lcd; + +#define PCA9535_REG_INPUT_0 0 +#define PCA9535_REG_INPUT_1 1 +#define PCA9535_REG_OUTPUT_0 2 +#define PCA9535_REG_OUTPUT_1 3 +#define PCA9535_REG_POLINV_0 4 +#define PCA9535_REG_POLINV_1 5 +#define PCA9535_REG_CFG_0 6 +#define PCA9535_REG_CFG_1 7 + +#define HD44780_COMMAND 0 +#define HD44780_DATA 1 + +#define HD44780_MINDELAY 43 // minimum delay between commands +#define HD44780_EN_UP 1 //Time for EN bit to be up (us) + //Spec has either 480 or 460 ns + +#define DEL_INIT_POWERON 40000 // Max poweron delay from [2] and [3] +#define DEL_INIT_1 5000 // From [2] -- larger than [3] +#define DEL_INIT_2 100 // from [2] +#define INIT_8_BIT 0x30 +#define INIT_4_BIT 0x20 + +// Specific LCD commands, their arguments and their required delays (in us) +#define CMD_CLEARDISPLAY (1 << 0) //0b00000001 +#define DEL_CLEARDISPLAY 1520 // 1.52ms + +#define CMD_RETURNHOME (1 << 1) //0b00000010 +#define DEL_RETURNHOME 1520 // 1.52ms +#define NWR_RETURNHOME HD44780_MINWRITE + +#define CMD_ENTRYMODESET (1 << 2) //0b00000100 +#define DEL_ENTRYMODESET HD44780_MINDELAY +#define EMS_INCREMENT (1 << 1) //0b00000010 +#define EMS_DECREMENT 0 +#define EMS_DISPLAYSHIFTON (1 << 0) //0b00000001 +#define EMS_DISPLAYSHIFTOFF 0 + + +#define CMD_DISPLAYCONTROL (1 << 3) //0b00001000 +#define DEL_DISPLAYCONTROL HD44780_MINDELAY +#define DSC_DISPLAYON (1 << 2) //0b00000100 +#define DSC_DISPLAYOFF 0 +#define DSC_CURSORON (1 << 1) //0b00000010 +#define DSC_CURSOROFF 0 +#define DSC_BLINKON (1 << 0) //0b00000001 +#define DSC_BLINKOFF 0 + +#define CMD_CURSORDISPSHIFT (1 << 4) //0b00010000 +#define DEL_CURSORDISPSHIFT HD44780_MINDELAY +#define CDS_DISPLAYSHIFT (1 << 3) //0b00001000 +#define CDS_CURSORMOVE 0 +#define CDS_SHIFTRIGHT (1 << 2) //0b00000100 +#define CDS_SHIFTLEFT 0 + +#define CMD_FUNCTIONSET (1 << 5) //0b00100000 +#define DEL_FUNCTIONSET HD44780_MINDELAY +#define FNS_DATAWIDTH8 (1 << 4) //0b00010000 +#define FNS_DATAWIDTH4 0 +#define FNS_DISPLAYLINES2 (1 << 3) //0b00001000 +#define FNS_DISPLAYLINES1 0 +#define FNS_FONT5X10 (1 << 2) //0b00000100 +#define FNS_FONT5X7 0 + +#define CMD_SETCGRAMADDR (1 << 6) //0b01000000 +#define DEL_SETCGRAMADDR HD44780_MINDELAY +#define CGR_ADDRESSMASK 0x3F + +#define CMD_SETDDRAMADDR (1 << 7) //0b10000000 +#define DEL_SETDDRAMADDR HD44780_MINDELAY +#define DDR_ADDRESSMASK 0x7F + +#define DEL_ROTATEDISPLAY HD44780_MINDELAY // rotation rate controlled externally + +#define GPIO_ALL_LINES_OUTPUT 0x0000 +#define GPIO_ALL_LINES_INPUT 0xFFFF + +//Display +void HD44780_init(const HD44780_t *device, uint8_t lines); +void HD44780_reset(const HD44780_t *device); +int HD44780_WriteDelay(const HD44780_t* device, const uint16_t data, const uint32_t delayAfter); +int HD44780_WriteSync(const HD44780_t* device, const uint16_t data, const uint32_t delayAfter); +void HD44780_Command(const HD44780_t*, const uint8_t command, const uint32_t delayafter); +void HD44780_Data(const HD44780_t*, const uint8_t); +void HD44780_WriteByteDDRAM(const HD44780_t*, const uint8_t, const uint8_t); +void HD44780_WriteByte(const HD44780_t*, const uint8_t reg, const uint8_t data, const uint32_t delayafter); +void HD44780_GpioWrite(const HD44780_t* device, const uint16_t data); +int i2c_write_reg(const HD44780_t* device, uint8_t reg, uint8_t data); +void HD44780_clear(const HD44780_t* device); +void HD44780_home(const HD44780_t* device); +void HD44780_putChar(const HD44780_t* device, const uint8_t data); +void HD44780_putCharAt(const HD44780_t* device, const uint8_t data, const uint8_t address); +void HD44780_putStr(const HD44780_t* device, const char* str); +void HD44780_putStrN(const HD44780_t* device, const char* str, const uint8_t strlen); +void HD44780_rotate(const HD44780_t* device, const uint8_t direction); + +void encode8b10b(unsigned *patbuffer, int patlen, unsigned *encbuffer, int &enclen); +void addBits(unsigned *buffer, unsigned word, unsigned numbits, unsigned bitpos); +unsigned decode(std::vector<unsigned char> inpvec); + +int main( int argc, char ** argv ){ + + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + IPCController controller(p); + lcd.controller=&controller; + int rce=0; + std::cout<<"RCE number?"<<std::endl; + std::cin>>rce; + lcd.rce=rce; + unsigned serstat, val; + controller.removeAllRces(); + controller.addRce(rce); + //assert(controller.writeHWregister(3,0)==0); //emulator or loopback + //assert(controller.writeHWregister(rce, 16,1)==0); //channel mode, 1=framed + //assert(controller.writeHWregister(rce, 0,1)==0); //channel mask + //assert(controller.writeHWregister(rce, 13,1)==0); //channel out mask + //assert(controller.readHWregister(rce, 14,val)==0); //channel mask + std::cout<<"In Mask: "<<std::hex<<val<<std::dec<<std::endl; + //assert(controller.readHWregister(rce, 15,val)==0); //channel mask + //assert(controller.writeHWregister(10,2)==0); //clock + std::cout<<"Out Mask: "<<std::hex<<val<<std::dec<<std::endl; + //controller.removeAllModules(); + //controller.addModule("module", "FEI4A",0,0,0,rce, ""); + + //setup chip + //serstat=controller.writeHWglobalRegister("module", 16, 0x10); + //serstat=controller.writeHWregister(rce, 15,0x180); //setup mux + ////serstat=controller.writeHWglobalRegister("module", 4, 0xffff); + ////serstat=controller.writeHWglobalRegister("module", 14, 0x4b00); + //serstat=controller.writeHWglobalRegister("module", 15, 0xf3c); + //serstat=controller.writeHWglobalRegister("module", 27, 0x8000); + //serstat=controller.writeHWglobalRegister("module", 28, 0x8206); + ////serstat=controller.writeHWglobalRegister("module", 28, 0x8206); + //serstat=controller.writeHWglobalRegister("module", 29, 0x2007); + /* Raw bitstream test with printout + PixScan scn(PixScan::COSMIC_DATA); + ipc::ScanOptions options; + scn.setName("TCP_0000"); // send data over the network rather than to file + scn.convertScanConfig(options); + controller.downloadScanConfig("CosmicData", options); + unsigned encbuffer[1024]; + while(1){ + std::cout<<"Phase: "; + int phase; + std::cin >>phase; + controller.writeHWregister(10,phase); + for (int i=0;i<1024;i++)encbuffer[i]=0; + std::vector<unsigned> bitstream; + std::string inp; + bool eof=true; + do{ + std::cin>>inp; + if(inp=="s")break; + if(inp=="q")exit(0); + if(inp=="eof" || inp=="EOF"){ + bitstream.push_back(0x1bc); + eof=true; + } else if(inp=="sof" || inp=="SOF"){ + bitstream.push_back(0x1fc); + eof=false; + } else if(inp=="idle" || inp=="IDLE")bitstream.push_back(0x13c); + else bitstream.push_back(strtoul(inp.c_str(),0,16)); + }while (1); + if(eof==false){ + std::cout<<"SOF not followed by EOF. Send anyway?"<<std::endl; + std::cin>>inp; + if(inp!="y" && inp!="Y")continue; + } + int enclen; + encode8b10b(&bitstream[0],bitstream.size(),encbuffer,enclen); + std::vector<unsigned> bs8b10b; + for (int i=0;i<enclen;i++){ + std::cout<<std::hex<<encbuffer[i]<<std::endl; + bs8b10b.push_back(encbuffer[i]); + } + //serstat=controller.writeHWblockData(bs8b10b); + serstat=controller.writeHWblockData(bitstream); + assert(serstat==0); + } + */ + // Test of trigger command + int command; + unsigned short inp; + unsigned nbt; + int reg; + BitStream *bs; + std::vector<unsigned char> rep; + new IPCHistoManager(p,"RceIsServer", "dummy"); + FEI4AFormatter fmt(0); + FEI4::FECommands commands; + std::vector<unsigned> dcoldata; + std::vector<unsigned> retv; + unsigned dcol, bit, xval; + FEI4AConfigFile fei4file; + ipc::PixelFEI4AConfig* cfgfei4a; + bool good; + commands.setAddr(0); + bs=new BitStream; + commands.switchMode(bs, FEI4::FECommands::RUN); + bs->push_back(0); + for(size_t i=0;i<bs->size();i++)std::cout<<std::hex<<(*bs)[i]<<std::endl; + + while(true){ + std::cout<<"Choose a command"<<std::endl; + std::cout<<"================"<<std::endl; + std::cout<<" 1) Send command"<<std::endl; + std::cout<<" 2) Write register"<<std::endl; + std::cout<<" 3) Read register"<<std::endl; + std::cout<<" 4) Write block data"<<std::endl; + std::cout<<" 5) Initialize display"<<std::endl; + std::cout<<" 6) Write string to display"<<std::endl; + //std::cout<<" 5) Write block data with handshake"<<std::endl; + std::cin>>std::dec>>command; + switch (command){ + case 1: + std::cout<<"Opcode?"<<std::endl; + unsigned opcode; + std::cin>>opcode; + assert(controller.sendHWcommand(rce, opcode)==0); + break; + case 2: + unsigned address, data; + std::cout<<"Address?"<<std::endl; + std::cin>>std::hex>>address; + std::cout<<"Data?"<<std::endl; + std::cin>>std::hex>>data>>std::dec; + std::cout<<controller.writeHWregister(rce,address, data)<<std::endl;; + break; + case 3: + unsigned addressr, datar; + std::cout<<"Address?"<<std::endl; + std::cin>>addressr; + std::cout<<controller.readHWregister(rce,addressr, datar)<<std::endl; + std::cout<<"Data "<<std::hex<<datar<<std::dec<<std::endl; + break; + case 4: + bs=new BitStream; + commands.L1A(bs); + serstat=controller.writeHWblockData(rce, *bs); + if(serstat!=0)std::cout<<"Send Error "<<serstat<<std::endl; + delete bs; + break; + case 5: + HD44780_reset(lcdp); + break; + case 6: + char bla[128]; + std::cout<<"Enter string to display."<<std::endl; + std::cin>>bla; + HD44780_putStr(lcdp, bla); + break; + case 7: + unsigned short st; + std::cout<<"Enter Value."<<std::endl; + std::cin>>std::hex>>st; + std::cout<<std::hex<<st<<std::dec<<std::endl; + controller.writeHWregister(rce, 31, st); + break; + } + } +} + +void encode8b10b(unsigned *patbuffer, int patlen, unsigned *encbuffer, int &enclen){ + unsigned enc5b6b[2][32]={{39,29,45,49,53,41,25,56,57,37,21,52,13,44,28,23,27,35,19,50,11,42,26,58,51,38,22,54,14,46,30,43}, + {24,34,18,49,10,41,25,7,6,37,21,52,13,44,28,40,36,35,19,50,11,42,26,5,12,38,22,9,14,17,33,20}}; + unsigned disp5b6b[32]={1,1,1,0,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,0,1,1,1}; + unsigned enc3b4b[2][8]={{11,9,5,12,13,10,6,14},{4,9,5,3,2,10,6,1}}; + unsigned disp3b4b[8]={1,0,0,0,1,0,0,1}; + enclen=patlen*10/8/4; + if((patlen*10)%32!=0){ + enclen++; + std::cout<<"WARNING: last word not fully utilized... contains zeroes"<<std::endl; + } + unsigned char *sbuffer; + sbuffer=(unsigned char*)patbuffer; + unsigned bitpos=0; + int disparity=0; //1 is 1, 0 is -1 + for (int i=0;i<patlen;i++){ + unsigned char word=(unsigned char)patbuffer[i]&0xff; + std::cout<<"Word "<<(unsigned)word<<std::endl; + if(patbuffer[i]&0x100){ //K symbol + unsigned kword=0; + if(word==252){ + if(disparity==0){ + kword=0xf8; + disparity=1; + } else { + kword=0x307; + disparity=0; + } + }else if(word==188){ + if(disparity==0){ + kword=0xfa; + disparity=1; + } else { + kword=0x305; + disparity=0; + } + }else if(word==60){ + if(disparity==0){ + kword=0xf9; + disparity=1; + } else { + kword=0x306; + disparity=0; + } + } + addBits(encbuffer,kword,10,bitpos); + bitpos+=10; + }else{ + unsigned word5b=word&0x1f; + unsigned encword5b=enc5b6b[disparity][word5b]; + addBits(encbuffer,encword5b,6,bitpos); + bitpos+=6; + disparity=disparity ^ disp5b6b[word5b]; + unsigned word3b=word>>5; + unsigned encword3b=enc3b4b[disparity][word3b]; + addBits(encbuffer,encword3b,4,bitpos); + bitpos+=4; + disparity=disparity ^ disp3b4b[word3b]; + } + } +} + + void addBits(unsigned *buffer, unsigned word, unsigned numbits, unsigned bitpos){ + unsigned current = bitpos/32; + unsigned bits=bitpos%32; + if (numbits>32-bits){ // Split over 2 words + int bitsleft=32-bits; + buffer[current]|=word>>(numbits-bitsleft); + buffer[current+1]|=word<<(32-(numbits-bitsleft)); + }else{ // bits fit into same word; + buffer[current]|=word<<(32-bits-numbits); + } +} + +unsigned decode(std::vector<unsigned char> inpvec){ + if(inpvec.size()==0)return FEI4::FEI4ARecord::Empty; + unsigned char* bytepointer=&inpvec[0]; + size_t size=inpvec.size(); + unsigned char* last=bytepointer+size-3; + FEI4::FEI4ARecord rec; + bool header=false; + while(bytepointer<=last){ + rec.setRecord(bytepointer); + // std::cout<<"Record "<<std::hex<<rec.getUnsigned()<<" "<<rec.getHeader()<<std::endl; + if(rec.isAddressRecord()){ // address record + std::cout<<"Address record for "; + if(rec.isGlobal())std::cout<<" global register "; + else std::cout<<" shift register "; + std::cout<<rec.getAddress()<<std::endl; + header=false; + }else if(rec.isValueRecord()){ //val rec without addr rec + printf("Value record: %04x\n",rec.getValue()); + header=false; + }else if(rec.isServiceRecord()){ + printf("Service record. Error code: %d. Count: %d \n",rec.getErrorCode(), rec.getErrorCount()); + header=false; + }else if(rec.isEmptyRecord()){ + // do nothing + std::cout<<"Empty record"<<std::endl; + header=false; + }else if(rec.isDataHeader()){ + std::cout<<"Data Header Lv1ID = "<<std::dec<<rec.getL1id()<<" BXID = "<<rec.getBxid()<<std::endl; + header=true; + }else if(rec.isData()){ + // std::cout<<std::hex<<rec.getHeader()<<std::endl; + std::cout<<"Data = "<<std::hex<<rec.getUnsigned()<<std::dec<<"Data Col = "<<std::dec<<rec.getColumn()<<" Row = "<<rec.getRow()<<" TotTop = "<<rec.getTotTop()<<" TotBottom = "<<rec.getTotBottom()<<std::endl; + }else{ + std::cout<<"Unexpected record type: "<<std::hex<<rec.getUnsigned()<<std::dec<<std::endl; + } + bytepointer+=3; + } + return FEI4::FEI4ARecord::OK; + } + +void HD44780_reset(const HD44780_t *device){ + i2c_write_reg(device, PCA9535_REG_CFG_0, 0); + usleep(1000); + i2c_write_reg(device, PCA9535_REG_CFG_1, 0); + usleep(1000); + + i2c_write_reg(device, PCA9535_REG_OUTPUT_0, 0xff); + usleep(1000); + i2c_write_reg(device, PCA9535_REG_OUTPUT_1, 0xff); + usleep(1000); + + i2c_write_reg(device, PCA9535_REG_POLINV_0, 0); + usleep(1000); + i2c_write_reg(device, PCA9535_REG_POLINV_1, 0); + usleep(1000); + + HD44780_WriteByte(device, HD44780_COMMAND, INIT_8_BIT, DEL_INIT_1); + usleep(1000); + HD44780_WriteByte(device, HD44780_COMMAND, INIT_8_BIT, DEL_INIT_2); + usleep(1000); + HD44780_WriteByte(device, HD44780_COMMAND, INIT_8_BIT, DEL_FUNCTIONSET); + HD44780_init(device, 2); +} +void +HD44780_WriteByte(const HD44780_t* device, const uint8_t reg, const uint8_t data, const uint32_t delayafter) +{ + // Don't assume that the pins are in any order + uint16_t toWrite = (( (data & (1<<0)) ? device->DB0 : 0 ) | + ( (data & (1<<1)) ? device->DB1 : 0 ) | + ( (data & (1<<2)) ? device->DB2 : 0 ) | + ( (data & (1<<3)) ? device->DB3 : 0 ) | + ( (data & (1<<4)) ? device->DB4 : 0 ) | + ( (data & (1<<5)) ? device->DB5 : 0 ) | + ( (data & (1<<6)) ? device->DB6 : 0 ) | + ( (data & (1<<7)) ? device->DB7 : 0 )); + if (reg == HD44780_DATA) toWrite |= device->RS; + HD44780_WriteDelay(device, toWrite, delayafter); +} +void HD44780_Command(const HD44780_t* device, const uint8_t command, const uint32_t delayafter) +{ + HD44780_WriteByte(device, HD44780_COMMAND, command, delayafter); +} +void +HD44780_Data(const HD44780_t* device, const uint8_t data) +{ + HD44780_WriteByte(device, HD44780_DATA, data, HD44780_MINDELAY); +} +void +HD44780_WriteByteDDRAM(const HD44780_t* device, const uint8_t data, const uint8_t address) +{ + // Write a byte at a specific DDRAM address + HD44780_Command(device, CMD_SETDDRAMADDR | (address & DDR_ADDRESSMASK), + DEL_SETDDRAMADDR); + HD44780_Data(device, data); +} +int HD44780_WriteDelay(const HD44780_t* device, const uint16_t data, const uint32_t delayAfter) +{ + int usec = HD44780_WriteSync(device, data, delayAfter); + usleep(usec); + return usec; +} +int +HD44780_WriteSync(const HD44780_t* device, const uint16_t data, const uint32_t delayAfter) +{ + uint16_t ldata = data; + HD44780_GpioWrite(device, ldata); + usleep(1000); + ldata |= device->EN; + std::cout<<"Towrite "<<std::hex<<ldata<<std::dec<<std::endl; + HD44780_GpioWrite(device, ldata); + // one microsecond synchronous delay simply to allow risetime + usleep(HD44780_EN_UP); + usleep(1000); + ldata &= ~(device->EN); + HD44780_GpioWrite(device, ldata); + usleep(1000); + return delayAfter > HD44780_MINDELAY ? delayAfter : HD44780_MINDELAY; +} + +void HD44780_GpioWrite(const HD44780_t* device, const uint16_t data) +{ + uint8_t tmp0 = data & 0xFF; + uint8_t tmp1 = (data >> 8) & 0xFF; + i2c_write_reg(device, PCA9535_REG_OUTPUT_0, tmp0); + i2c_write_reg(device, PCA9535_REG_OUTPUT_1, tmp1); +} + +int i2c_write_reg(const HD44780_t* device, uint8_t reg, uint8_t data){ + device->controller->writeHWregister(device->rce, 31, (reg<<8)|data); + return 0; +} + +void +HD44780_clear(const HD44780_t *device) +{ + HD44780_Command(device, CMD_CLEARDISPLAY, DEL_CLEARDISPLAY); +} + +void +HD44780_home(const HD44780_t *device) +{ + HD44780_Command(device, CMD_RETURNHOME, DEL_RETURNHOME); +} + +void +HD44780_putChar(const HD44780_t *device, const uint8_t data) +{ + HD44780_Data(device, data); +} + +void +HD44780_putCharAt(const HD44780_t *device, const uint8_t data, const uint8_t address) +{ + HD44780_WriteByteDDRAM(device, data, address); +} + +void +HD44780_putStr(const HD44780_t *device, const char* str) +{ + while (*str) HD44780_putChar(device, *str++); +} + +void +HD44780_putStrN(const HD44780_t *device, const char* str, const uint8_t length) +{ + uint8_t toWrite = length; + while (toWrite--) HD44780_putChar(device, *str++); +} + +void +HD44780_rotate(const HD44780_t* device, const uint8_t direction) +{ + HD44780_Command(device, CMD_CURSORDISPSHIFT | CDS_DISPLAYSHIFT | + ((direction) ? CDS_SHIFTLEFT : CDS_SHIFTRIGHT), + DEL_ROTATEDISPLAY); +} +// Public interface +void +HD44780_init(const HD44780_t *device, const uint8_t lines) +{ + HD44780_Command(device, (CMD_FUNCTIONSET | + FNS_DATAWIDTH8 + | FNS_FONT5X7 | + (lines == 0 ? FNS_DISPLAYLINES1 : FNS_DISPLAYLINES2)), + DEL_FUNCTIONSET); + // Turn the display off + HD44780_Command(device, CMD_DISPLAYCONTROL | DSC_DISPLAYOFF | DSC_CURSOROFF | DSC_BLINKOFF, + DEL_FUNCTIONSET); + // Set the entry mode to increment, noshift + HD44780_Command(device, CMD_ENTRYMODESET | EMS_INCREMENT | EMS_DISPLAYSHIFTOFF, + DEL_ENTRYMODESET); + // Turn on display, turn on cursor and turn off blinking cursor + HD44780_Command(device, CMD_DISPLAYCONTROL | DSC_DISPLAYON | DSC_CURSORON | DSC_BLINKOFF, + DEL_DISPLAYCONTROL); + HD44780_clear(device); +} + + diff --git a/rce/rcecalib/server/sendRandomPattern.cc b/rce/rcecalib/server/sendRandomPattern.cc new file mode 100644 index 0000000000000000000000000000000000000000..6d1f0bc4dae4078b8c8289c58a6e05d7b5b1c66b --- /dev/null +++ b/rce/rcecalib/server/sendRandomPattern.cc @@ -0,0 +1,60 @@ +#include <ipc/partition.h> +#include <ipc/core.h> +#include <ipc/server.h> +#include <ipc/object.h> + +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/PixScan.hh" +#include "ScanOptions.hh" +#include "rcecalib/config/FEI4/FECommands.hh" +#include "rcecalib/config/FEI4/FEI4ARecord.hh" +#include "rcecalib/config/FEI4/FEI4AFormatter.hh" +#include "rcecalib/config/FormattedRecord.hh" +#include "rcecalib/server/FEI4AConfigFile.hh" + +#include <cmdl/cmdargs.h> +#include <iostream> +#include <stdio.h> +#include <stdlib.h> + + +int main( int argc, char ** argv ){ + + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdArgInt rce_name ('r', "rce", "rce-name", "rce to talk to."); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + CmdLine cmd(*argv, &partition_name, &rce_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + IPCController controller(p); + int rce=(int)rce_name; + controller.removeAllRces(); + controller.addRce(rce); + assert(controller.writeHWregister(rce, 0,0xff)==0); //channel mask + std::vector<unsigned int> rep; + srand(0); + std::string a; + while(1){ + for(int i=0;i<2048;i++)rep.push_back((unsigned int)rand()); + controller.writeHWblockData(rce, rep); + rep.clear(); + //std::cin>>a; + } +} diff --git a/rce/rcecalib/server/tdccalib.cc b/rce/rcecalib/server/tdccalib.cc new file mode 100644 index 0000000000000000000000000000000000000000..b7ae1ef872caae649295f58dc14882a3fa409a3a --- /dev/null +++ b/rce/rcecalib/server/tdccalib.cc @@ -0,0 +1,209 @@ +#include <stdio.h> + +#include <ers/ers.h> + +#include <ipc/partition.h> +#include <ipc/server.h> +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <cmdl/cmdargs.h> +#include <unistd.h> + +#include "rcecalib/server/TurboDaqFile.hh" +#include "rcecalib/server/IPCController.hh" +#include "rcecalib/server/PixScan.hh" + +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCFEI3Adapter.hh" +#include "ScanOptions.hh" +#include "PixelModuleConfig.hh" + +#include <TApplication.h> +#include <TROOT.h> +#include <TStyle.h> +#include <TCanvas.h> +#include <TH2F.h> +#include <TF1.h> +#include <TFile.h> +#include "rcecalib/server/Mean.hh" + +int acquireDataPoint(IPCController& controller, int rce); + +int main( int argc, char ** argv ) +{ + + TApplication *tapp; + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + +// +// Initialize command line parameters with default values +// + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + IPCController controller(p); + + tapp=new TApplication("bla", &argc, argv); + + gROOT->SetStyle("Plain"); + gStyle->SetOptStat(0); + gStyle->SetPalette(1); + gStyle->SetOptFit(111); + gStyle->SetErrorX(0); + + TH2F* occ2=new TH2F("tdc2","TDC Linearity",64,-.5,63.5,251,-.05,25.05); + //TCanvas *c2=new TCanvas("c2","Canvas",600,600); + //c2->Draw(); + //occ2->Draw(); + + unsigned serstat; + int rce=0; + serstat=controller.writeHWregister(rce, 3,1); //TDC calibration mode + assert(serstat==0); + std::cout<<"Part 1: Measurement of tap unit"<<std::endl; + Mean p2; + // Set Clock to 90 deg phase + serstat=controller.writeHWregister(rce, 2,1); + assert(serstat==0); + serstat=controller.writeHWregister(rce, 0x180,0); + assert(serstat==0); + serstat=controller.writeHWregister(rce, 0x190,0); + assert(serstat==0); + for (int i=0;i<100;i++){ + int bitpos=acquireDataPoint(controller, rce); + if(bitpos>-1)p2.accumulate((float)bitpos); + } + assert(p2.nEntries()>0); + std::cout<<"TDC at 90 deg is "<<p2.mean()<<" +- "<<p2.sigma()/(float)p2.nEntries()<<std::endl; + + Mean p0; + serstat=controller.writeHWregister(rce, 2,0); //0 deg + assert(serstat==0); + int index=0; + for (int i=500;i<800;i+=10){ + p0.clear(); + std::cout<<"Data point "<<i<<std::endl; + controller.writeHWregister(rce, 0x180,i); //set phase in DCM + controller.writeHWregister(rce, 0x190,0); // move DCM to new phase + for (int j=0;j<100;j++){ + int bitpos=acquireDataPoint(controller, rce); + if(bitpos>-1)p0.accumulate((float)bitpos); + } + if(p0.mean()>p2.mean()){ + index=i; + break; + } + } + assert(index>0); + int index2=index; + for (int i=index-9;i<index;i++){ + p0.clear(); + std::cout<<"Data point "<<i<<std::endl; + serstat=controller.writeHWregister(rce, 0x180,i); //set phase in DCM + assert(serstat==0); + serstat=controller.writeHWregister(rce, 0x190,0); // move DCM to new phase + assert(serstat==0); + for (int j=0;j<100;j++){ + int bitpos=acquireDataPoint(controller, rce); + if(bitpos>-1)p0.accumulate((float)bitpos); + } + if(p0.mean()>p2.mean()){ + index2=i-1; + break; + } + } + std::cout<<"Overlap at setting "<<index2<<std::endl; + float tunit=6400./(float)index2; + std::cout<<"1 tap delay is "<<tunit<<" ps."<<std::endl; + + int npoints=(int)(25000./tunit/10); + TH1F* occ=new TH1F("tdc","TDC Linearity",npoints+1,-5e-3*tunit,25.+5e-3*tunit ); + occ->GetXaxis()->SetTitle("Delay (ns)"); + occ->GetYaxis()->SetTitle("TDC value"); + occ->SetMaximum(70); + occ->SetMarkerStyle(20); + occ->SetMarkerSize(.5); + TCanvas *c1=new TCanvas("c1","Canvas",600,600); + c1->Draw(); + occ->Draw(); + + for (int k=0;k<npoints*10;k+=10){ + if(k%500==0)std::cout<<"Data point "<<k<<std::endl; + unsigned int phase=k/index2; // 6.4 ns clock divided by 9.8 ps tap delay + unsigned int setting=k%index2; + controller.writeHWregister(rce, 2,phase); + controller.writeHWregister(rce, 0x180,setting); //set phase in DCM + controller.writeHWregister(rce, 0x190,0); // move DCM to new phase + int nloops=100; + Mean mn; + for (int i=0;i<nloops;i++){ + int bitpos=acquireDataPoint(controller, rce); + if(bitpos>-1){ + mn.accumulate((float)bitpos); + occ2->Fill(bitpos,(float)tunit/1000.*k); + } + } + float mean=mn.mean(); + float sig=mn.sigma(); + occ->SetBinContent(k/10+1,mean); + if(sig<10)occ->SetBinError(k/10+1,sig); + occ->Draw("ep"); + c1->Update(); + //occ2->Draw(); + //c2->Update(); + usleep(100000); + } + occ->Fit("pol1"); + float fitpar=occ->GetFunction("pol1")->GetParameter(1); + // float fitparerr=occ->GetFunction("pol1")->GetParError(1); + float fact=1./fitpar; + std::cout<<"Fit result: "<<fact<<" nanoseconds per TDC count"<<std::endl; + serstat=controller.writeHWregister(rce, 3,0); //Return to normal mode + assert(serstat==0); + TFile *file=new TFile("histos.root","recreate"); + occ->Write(); + occ2->Write(); + file->Close(); + + tapp->Run(); + +} + +int acquireDataPoint(IPCController& controller, int rce){ + controller.writeHWregister(rce, 1,0); //start TDC measurement + unsigned counter1; + controller.readHWregister(rce, 0, counter1); + unsigned counter2; + controller.readHWregister(rce, 1, counter2); + unsigned long long counter=counter2; + counter=(counter<<32) | counter1; + int bitpos=-1; + for (int j=0;j<64;j++){ + if(((counter>>j)&1)==0){ + bitpos=j; + break; + } + } + return bitpos; +} diff --git a/rce/rcecalib/server/test_client.cc b/rce/rcecalib/server/test_client.cc new file mode 100644 index 0000000000000000000000000000000000000000..4765c14b0739e87fc5740586a1b2e0a1a6fc0352 --- /dev/null +++ b/rce/rcecalib/server/test_client.cc @@ -0,0 +1,756 @@ +// +// test-client.cc +// +// test application for IPC library +// +// Sergei Kolos January 2000 +// +// description: +// Shows how to access remote objects and call their methods +// Performs timing for the lookup and remote methods invocations +///////////////////////////////////////////////////////////////////////////////// +#include <stdio.h> + +#include <ers/ers.h> + +#include <ipc/partition.h> +#include <ipc/server.h> +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <cmdl/cmdargs.h> +#include <unistd.h> + + +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCFEI3Adapter.hh" +#include "ScanOptions.hh" + +using namespace std; + +static bool echo = true; +static int iter=1; +static int delay=0; +static int asynch=1; +static int synch=0; +static const char *object_name="scanCtrl"; + +static int s_error_num; +static int a_error_num; + +static void s_error(CORBA::Exception & ex) +{ + s_error_num++; + std::cerr << "ERROR [synch_ping] exception " << ex._name() << std::endl; +} + +static void a_error(CORBA::Exception & ex) +{ + a_error_num++; + std::cerr << "ERROR [asynch_ping] exception " << ex._name() << std::endl; +} + + +static void +TestIterators( IPCPartition p ) +{ + std::map< std::string, ipc::IPCScanAdapter_var > scanobjects; + std::map< std::string, ipc::IPCConfigIFAdapter_var > confobjects; + std::map< std::string, ipc::IPCFEI3Adapter_var > modobjects; + + + OWLTimer time; + + time.start(); + try { + p.getObjects<ipc::IPCScanAdapter>( scanobjects ); + p.getObjects<ipc::IPCConfigIFAdapter>( confobjects ); + p.getObjects<ipc::IPCFEI3Adapter>( modobjects ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + time.stop(); + + if ( echo ) + { + std::cout << "There are " << confobjects.size() << " objects of type \"ipc::IPCConfigIFAdapter\" registered with the \"" + << p.name() << "\" partition" << std::endl; + std::cout << "There are " << scanobjects.size() << " objects of type \"ipc::IPCScanAdapter\" registered with the \"" + << p.name() << "\" partition" << std::endl; + std::cout << "There are " << modobjects.size() << " objects of type \"ipc::IPCFEI3Adapter\" registered with the \"" + << p.name() << "\" partition" << std::endl; + std::cout << "getObjects operation took (in seconds): " << std::endl + << "\t" << time.userTime() << "(user time)" << std::endl + << "\t" << time.systemTime() << "(system time)" << std::endl + << "\t" << time.totalTime() << "(total time)" << std::endl; + } + + std::map< std::string, ipc::IPCScanAdapter_var >::iterator scanit; + std::map< std::string, ipc::IPCConfigIFAdapter_var >::iterator confit; + std::map< std::string, ipc::IPCFEI3Adapter_var >::iterator modit; + + if ( echo ) + std::cout << "Objects are:" << std::endl; + for ( scanit = scanobjects.begin(); scanit != scanobjects.end(); scanit++ ) + { + if ( echo ) + std::cout << "\"" << (*scanit).first << "\"" << std::endl; + } + for ( confit = confobjects.begin(); confit != confobjects.end(); confit++ ) + { + if ( echo ) + std::cout << "\"" << (*confit).first << "\"" << std::endl; + } + for ( modit = modobjects.begin(); modit != modobjects.end(); modit++ ) + { + if ( echo ) + std::cout << "\"" << (*modit).first << "\"" << std::endl; + } +} + + +static void TestLookupMethod( IPCPartition p ) +{ + char oname[32]; + int i; + OWLTimer time; + + time.start(); + for ( i = 0; i < 1 ; i++ ) + { + sprintf( oname, "scanCtrl", i ); + try { + ipc::IPCScanAdapter_var handle = p.lookup<ipc::IPCScanAdapter>( oname ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + } + time.stop(); + if ( echo ) + { + std::cout << "object resolution (first time) takes (in seconds): " << std::endl + << "\t" << time.userTime() << "(user time)" << std::endl + << "\t" << time.systemTime() << "(system time)" << std::endl + << "\t" << time.totalTime() << "(total time)" << std::endl; + } + + time.reset(); + time.start(); + for ( i = 0; i < 1 ; i++ ) + { + sprintf( oname, "scanCtrl", i ); + try { + ipc::IPCScanAdapter_var handle = p.lookup<ipc::IPCScanAdapter>( oname ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + } + time.stop(); + if ( echo ) + { + std::cout << "object resolution (second time) takes (in seconds): " << std::endl + << "\t" << time.userTime() << "(user time)" << std::endl + << "\t" << time.systemTime() << "(system time)" << std::endl + << "\t" << time.totalTime() << "(total time)" << std::endl; + } +} + +static void TestResolve( IPCPartition p ) +{ + char oname[32] = "scanCtrl"; + int i; + OWLTimer time; + + time.start(); + for ( i = 0; i < iter; i++ ) + { + try { + ipc::IPCScanAdapter_var handle = p.lookup<ipc::IPCScanAdapter,ipc::no_cache,ipc::narrow>( oname ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + } + time.stop(); + if ( echo ) + { + std::cout << "object resolution takes (in seconds): " << std::endl + << "\t" << time.userTime()/iter << "(user time)" << std::endl + << "\t" << time.systemTime()/iter << "(system time)" << std::endl + << "\t" << time.totalTime()/iter << "(total time)" << std::endl; + } +} + +static void TestIsObjectValid( IPCPartition p ) +{ + char oname[32]; + int i; + + for ( i = 0; i < iter ; i++ ) + { + if ( echo ) + std::cout << " p.isValid( ) = " << p.isValid( ) << std::endl; + } + + sprintf( oname, "scanCtrl" ); + for ( i = 0; i < iter ; i++ ) + { + try { + bool v = p.isObjectValid<ipc::IPCScanAdapter>( oname ); + if ( echo ) + std::cout << " p.isObjectValid( ) = " << v << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + } + + for ( i = 0; i < 1 ; i++ ) + { + sprintf( oname, "scanCtrl", i ); + try { + bool v = p.isObjectValid<ipc::IPCScanAdapter>( oname ); + if ( echo ) + std::cout << " p.isObjectValid( ) = " << v << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + } + +} + +static void TestRemoteInvocation( IPCPartition p ) +{ + char line[2]; + int i; + + memset( line, 55, 1 ); + line[1] = 0; + + OWLTimer time; + + ipc::ScanOptions options; + char* pointer=(char*)&options; + for (int i=0;i<sizeof(ipc::ScanOptions);i++){ + *pointer++=0; + } + options.nMaskStages=5; + if ( !synch ) + { + if ( echo ) + { + std::cout << "Asynchronous method test ..." << std::endl; + } + + time.start(); + + for ( i = 0; i < 1; i++ ) + { + sleep( delay ); + ipc::IPCScanAdapter_var handle; + try { + // std::clog << "calling lookup ... {" << std::endl; + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + //std::clog << "} done" << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + continue; + } + + try + { + //std::clog << "calling ping_a function ... {" << std::endl; + handle -> IPCabort( ); + //handle -> IPCconfigureScan( "Regular", options ); + handle -> IPCpause( ); + //std::clog << "} done" << std::endl; + + } + catch(CORBA::Exception & ex) + { + a_error( ex ); + } + } + time.stop(); + + if ( echo ) + { + std::cout << "passing 1024 bytes (asynchronously) takes (in seconds): " << std::endl + << "\t" << time.userTime()/iter << "(user time)" << std::endl + << "\t" << time.systemTime()/iter << "(system time)" << std::endl + << "\t" << time.totalTime()/iter << "(total time)" << std::endl; + } + } + + if ( !asynch ) + { + if ( echo ) + { + std::cout << "Synchronous method test ..." << std::endl; + } + + time.reset(); + time.start(); // Record starting time + + for ( i = 0; i < iter; i++ ) + { + sleep( delay ); + ipc::IPCScanAdapter_var handle; + try { + std::clog << "calling lookup ... {" << std::endl; + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + std::clog << "} done" << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + continue; + } + + try + { + std::clog << "calling ping_s function ... {" << std::endl; + handle -> IPCresume( ); + std::clog << "} done" << std::endl; + } + catch(CORBA::Exception & ex) + { + s_error( ex ); + } + } + time.stop(); + if ( echo ) + { + std::cout << "passing 1024 bytes (synchronously) takes (in seconds): " << std::endl + << "\t" << time.userTime()/iter << "(user time)" << std::endl + << "\t" << time.systemTime()/iter << "(system time)" << std::endl + << "\t" << time.totalTime()/iter << "(total time)" << std::endl; + } + } +} + +static void TestExceptions( IPCPartition p ) +{ + char line[1025]; + int i; + + memset( line, 55, 1024 ); + line[1024] = 0; + + for ( i = 0; i < iter; i++ ) + { + ipc::IPCScanAdapter_var handle; + try { + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + break; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + break; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + break; + } + + try + { + handle -> IPCabort( ); + } + catch(CORBA::SystemException & ex) + { + std::cerr << std::endl << "ERROR [ipc_IPCScanAdapter_client::TestExceptions] system exception " << ex._name() << std::endl; + } + } +} +/* +class IPCCallback : public IPCServer, + public IPCObject<POA_ipc::callback> +{ + public: + void notify( const char * name ) + { + std::cout << "Callback from employee \"" << name << "\" received" << std::endl; + } + + ~IPCCallback() + { + std::cout << "IPCCallback destructor is called" << std::endl; + } +}; + + +bool stop_test( void * param ) +{ + IPCCallback * cb = static_cast<IPCCallback*>( param ); + cb->stop(); + return false; +} + +void TestCallbacks( IPCPartition p ) +{ + IPCCallback * cb = new IPCCallback; + + std::map< std::string, ipc::person_var > persons; + try { + p.getObjects<ipc::person>( persons ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + + std::map< std::string, ipc::person_var >::iterator pit; + + std::cout << "Persons are:" << std::endl; + + for ( pit = persons.begin(); pit != persons.end(); pit++ ) + { + std::cout << "\"" << (*pit).first << "\"" << std::endl; + } + + std::map< std::string, ipc::employee_var > employees; + try { + p.getObjects<ipc::employee>( employees ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + + std::map< std::string, ipc::employee_var >::iterator eit; + + std::cout << "Employees are:" << std::endl; + + for ( eit = employees.begin(); eit != employees.end(); eit++ ) + { + std::cout << "\"" << (*eit).first << "\"" << std::endl; + (*eit).second->subscribe( cb->_this(), 1 ); + } + + IPCAlarm * alarm = new IPCAlarm( 10, 0, stop_test, cb ); + + cb->run(); + + delete alarm; + cb->_destroy(); + std::cout << "Callbacks test completed." << std::endl; +} +*/ +static void TestCache( IPCPartition p ) +{ + char line[2]; + int i; + + memset( line, 55, 1 ); + line[2] = 0; + + if ( echo ) + { + std::cout << "Cache test ..." << std::endl; + } + + ipc::IPCScanAdapter_var handle1; + ipc::IPCScanAdapter_var handle2; + try { + std::clog << "calling lookup for handle 1 ... {" << std::endl; + handle1 = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + std::clog << "} done" << std::endl; + + std::clog << "calling lookup for handle 2 ... {" << std::endl; + handle2 = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + std::clog << "} done" << std::endl; + } + catch( daq::ipc::Exception & ex ) { + ers::error( ex ); + return; + } + + for ( i = 0; i < iter; i++ ) + { + try + { + sleep( delay ); + std::clog << "calling ping_s function using handle 1 ... {" << std::endl; + handle1 -> IPCpause( ); + std::clog << "} done" << std::endl; + + sleep( delay ); + std::clog << "calling ping_s function using handle 2 ... {" << std::endl; + handle2 -> IPCresume( ); + std::clog << "} done" << std::endl; + } + catch(CORBA::Exception & ex) + { + s_error( ex ); + } + + try + { + sleep( delay ); + std::clog << "calling lookup for local handle ... {" << std::endl; + ipc::IPCScanAdapter_var handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + std::clog << "} done" << std::endl; + + sleep( delay ); + std::clog << "calling ping_s function using local handle ... {" << std::endl; + handle -> IPCpause( ); + std::clog << "} done" << std::endl; + } + catch(CORBA::Exception & ex) + { + s_error( ex ); + } + catch( daq::ipc::Exception & ex ) { + ers::error( ex ); + return; + } + } + + std::cout << "Cache test completed." << std::endl; +} + +static void TestPerformance( IPCPartition p, size_t size ) +{ + char * line = new char[size]; + + memset( line, 55, size ); + line[size-1] = 0; + + double total_time = 0; + double user_time = 0; + double system_time = 0; + if ( !synch ) + { + if ( echo ) + { + std::cout << "Asynchronous method test ..." << std::endl; + } + + for ( int i = 0; i < iter; i++ ) + { + if ( delay) usleep( delay ); + ipc::IPCScanAdapter_var handle; + try { + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + continue; + } + + try + { + OWLTimer one_time; + one_time.start(); + handle -> IPCpause( ); + one_time.stop(); + std::cout << one_time.totalTime()*1000 << std::endl; + total_time += one_time.totalTime(); + user_time += one_time.userTime(); + system_time += one_time.systemTime(); + } + catch(CORBA::Exception & ex) + { + a_error( ex ); + } + } + + if ( echo ) + { + std::cout << "passing " << size << " bytes (asynchronously) takes (in milliseconds): " << std::endl + << "\t" << user_time/iter*1000 << "(user time)" << std::endl + << "\t" << system_time/iter*1000 << "(system time)" << std::endl + << "\t" << total_time/iter*1000 << "(total time)" << std::endl; + } + } + + total_time = 0; + user_time = 0; + system_time = 0; + if ( !asynch ) + { + if ( echo ) + { + std::cout << "Synchronous method test ..." << std::endl; + } + + for ( int i = 0; i < iter; i++ ) + { + if ( delay) usleep( delay ); + ipc::IPCScanAdapter_var handle; + try { + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + continue; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + continue; + } + + try + { + OWLTimer one_time; + one_time.start(); + handle -> IPCpause( ); + one_time.stop(); + std::cout << one_time.totalTime()*1000 << std::endl; + total_time += one_time.totalTime(); + user_time += one_time.userTime(); + system_time += one_time.systemTime(); + } + catch(CORBA::Exception & ex) + { + s_error( ex ); + } + } + + if ( echo ) + { + std::cout << "passing " << size << " bytes (asynchronously) takes (in milliseconds): " << std::endl + << "\t" << user_time/iter*1000 << "(user time)" << std::endl + << "\t" << system_time/iter*1000 << "(system time)" << std::endl + << "\t" << total_time/iter*1000 << "(total time)" << std::endl; + } + } + + delete line; +} + +int main( int argc, char ** argv ) +{ + + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + CmdArgInt length ('l', "length", "data-length", "size of data for timing test (1024 by default)."); + +// +// Initialize command line parameters with default values +// + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition p( (const char*)partition_name ); + + std::cout<<"***********TestIterators"<<std::endl; + TestIterators(p); + std::cout<<"***********TestLookupMethod"<<std::endl; + TestLookupMethod(p); + std::cout<<"***********TestIsObjectValid"<<std::endl; + TestIsObjectValid(p); + std::cout<<"***********TestRemoteInvocation"<<std::endl; + TestRemoteInvocation(p); + //TestExceptions(p); + // TestCallbacks(p); + // TestCache(p); + //TestPerformance( p, length ); + //TestResolve(p); + + return 0; + + std::cout << "# of failed methods invocations: " << std::endl + << "\tasynchronous - " << a_error_num << std::endl + << "\tsynchronous - " << s_error_num << std::endl; + + ipc::IPCScanAdapter_var handle; + try { + handle = p.lookup<ipc::IPCScanAdapter>( (const char*)object_name ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + return 1; + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + return 1; + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + return 1; + } + + try + { + handle -> shutdown( ); + } + catch(CORBA::SystemException & ex) + { + std::cerr << "ERROR [ipc_test_client::main] Call to method shutdown failed " << ex._name() << std::endl; + return 1; + } + + return 0; +} diff --git a/rce/rcecalib/server/test_scan_client.cc b/rce/rcecalib/server/test_scan_client.cc new file mode 100644 index 0000000000000000000000000000000000000000..e477dadf7a2fa2150cc006a72411c9b8070101a5 --- /dev/null +++ b/rce/rcecalib/server/test_scan_client.cc @@ -0,0 +1,244 @@ +// +// test-client.cc +// +// test application for IPC library +// +// Sergei Kolos January 2000 +// +// description: +// Shows how to access remote objects and call their methods +// Performs timing for the lookup and remote methods invocations +///////////////////////////////////////////////////////////////////////////////// +#include <stdio.h> + +#include <ers/ers.h> + +#include <ipc/partition.h> +#include <ipc/server.h> +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <cmdl/cmdargs.h> +#include <unistd.h> + + +#include "IPCScanAdapter.hh" +#include "IPCConfigIFAdapter.hh" +#include "IPCFEI3Adapter.hh" +#include "ScanOptions.hh" +#include "IPCScanAdapter.hh" +#include "IPCScanRootAdapter.hh" + +using namespace std; + + + +int main( int argc, char ** argv ) +{ + + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work in."); + + +// +// Initialize command line parameters with default values +// + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + +// +// Declare command object and its argument-iterator +// + CmdLine cmd(*argv, &partition_name, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + +// +// Parse arguments +// + cmd.parse(arg_iter); + + IPCPartition m_partition( (const char*)partition_name ); + + // write scan config + + ipc::ScanOptions m_scanPar; + ipc::PixelModuleConfig cfg; + char* pointer=(char*)&m_scanPar; + for (int i=0;i<sizeof(ipc::ScanOptions);i++){ + *pointer++=0; + } + pointer=(char *)&cfg; + for (int i=0;i<sizeof(ipc::PixelModuleConfig);i++){ + *pointer++=0; + } + // send minimal module configuration + + // some random vcal gradients for one FEC + cfg.FEConfig[0].FECalib.cinjLo=8.; + cfg.FEConfig[0].FECalib.cinjHi=40; + cfg.FEConfig[0].FECalib.vcalCoeff[0]=0.; + cfg.FEConfig[0].FECalib.vcalCoeff[1]=0.003; + cfg.FEConfig[0].FECalib.vcalCoeff[2]=0.000006; + cfg.FEConfig[0].FECalib.vcalCoeff[3]=0.000000043; + + // integer scaled version for FE calib + cfg.FEConfig[0].FECalibInt.cinjLo=8; + cfg.FEConfig[0].FECalibInt.cinjHi=40; + cfg.FEConfig[0].FECalibInt.vcalCoeff[0]=3; + cfg.FEConfig[0].FECalibInt.vcalCoeff[1]=5; + cfg.FEConfig[0].FECalibInt.vcalCoeff[2]=6; + cfg.FEConfig[0].FECalibInt.vcalCoeff[3]=43; + + ipc::IPCConfigIFAdapter_var moduleHandle; + try { + moduleHandle = m_partition.lookup<ipc::IPCConfigIFAdapter>( "configIF" ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + ipc::ModSetup s; + s.id=42; + s.link=0; + + moduleHandle->IPCdeleteModules(); + std::cout<<"before setupmodules"<<std::endl; + int ret=moduleHandle -> IPCsetupModule( "module","IPC_FEI3_multiThread",s ); + + /* set up trigger method */ + std::cout<<"before createtrg"<<std::endl; + ret=moduleHandle->IPCsetupTriggerIF("EventFromDsp"); + if(ret)std::cout<<"***ERROR*** IPCsetupTrigger failed"<<std::endl; + std::cout<<"after createtrg"<<std::endl; + + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + ipc::IPCFEI3Adapter_var modhandle; + try { + bool v=m_partition.isObjectValid<ipc::IPCFEI3Adapter>("module"); + //if(v)std::cout<<"Valid"<<std::endl; + if(!v) std::cout<<"Not valid"<<std::endl; + modhandle = m_partition.lookup<ipc::IPCFEI3Adapter>( "module" ); + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + + try { + modhandle -> IPCdownloadConfig( cfg ); + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + // zero everything - very important to avoid MARSHALL exception + pointer=(char*)&m_scanPar; + for (int i=0;i<sizeof(ipc::ScanOptions);i++){ + *pointer++=0; + } + // Simple receiver + m_scanPar.receiver=CORBA::string_dup("Simple"); + m_scanPar.parser=CORBA::string_dup("Simple"); + /* define data processor */ + + m_scanPar.histOpt[ipc::IPC_SCAN_OCCUPANCY].optionMask = 1; + m_scanPar.nLoops++; + m_scanPar.scanLoop[0].endofLoopAction.Action = ipc::IPC_SCAN_FIT; + m_scanPar.scanLoop[0].endofLoopAction.fitFunction =ipc::IPC_SCAN_SCURVE; + /* needs to be defined for Parser Object */ + m_scanPar.trigOpt.nL1AperEvent=16; + + /* ScanLoop needs at least these defined */ + m_scanPar.scanLoop[0].nPoints = 101; + m_scanPar.trigOpt.nEvents=100; + m_scanPar.nMaskStages=3; + m_scanPar.scanLoop[0].dataPoints.length(m_scanPar.scanLoop[0].nPoints); + m_scanPar.scanLoop[0].scanParameter=ipc::IPC_SCAN_VCAL; + // m_scanPar.triggerMode=ipc::IPC_SCAN_USE_CLOW; + + for(unsigned int k=0;k<m_scanPar.scanLoop[0].nPoints;k++) + m_scanPar.scanLoop[0].dataPoints[k]=k*2; // default Vcal scaling of 2 + + ipc::IPCScanRootAdapter_var scanRootHandle; + try { + std::cerr << "calling lookup ... {" << std::endl; + scanRootHandle = m_partition.lookup<ipc::IPCScanRootAdapter>( "scanRoot" ); + std::cerr << "} done" << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + + + + try { + std::clog << "Calling configure scan function ... {" << std::endl; + scanRootHandle -> IPCconfigureScan("Regular", m_scanPar ); + //handle->shutdown(); + std::clog << "} done" << std::endl; + + } + + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name() <<std::endl; + } + + // finally start the scan + + ipc::IPCScanAdapter_var handleScanAdapter; + try { + std::cerr << "calling lookup ... {" << std::endl; + handleScanAdapter = m_partition.lookup<ipc::IPCScanAdapter>( "scanCtrl" ); + std::cerr << "} done" << std::endl; + } + catch( daq::ipc::InvalidPartition & ex ) { + ers::error( ex ); + } + catch( daq::ipc::ObjectNotFound & ex ) { + ers::error( ex ); + } + catch( daq::ipc::InvalidObjectName & ex ) { + ers::error( ex ); + } + try { + std::clog << "calling startScan function ... {" << std::endl; + handleScanAdapter -> IPCstartScan( ); + std::clog << "} done" << std::endl; + } + catch(CORBA::Exception & ex) { + std::cerr<<"Corba exception "<<ex._name()<<std::endl; + } + + + + + return 0; + +} diff --git a/rce/rcecalib/server/test_server.cc b/rce/rcecalib/server/test_server.cc new file mode 100644 index 0000000000000000000000000000000000000000..4b5dec6c253ed11da99ba421fba53650138dd4ba --- /dev/null +++ b/rce/rcecalib/server/test_server.cc @@ -0,0 +1,113 @@ +// +// test-server.cc +// +// test application for IPC library +// +// Sergei Kolos January 2000 +// +// description: +// Implements test.accessible interface +// Creates several implementation objects +// Performs timing for the publish and withdraw operations +///////////////////////////////////////////////////////////////////////////////// +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +#include <ers/ers.h> + +#include <ipc/object.h> +#include <ipc/alarm.h> +#include <ipc/core.h> + +#include <owl/timer.h> +#include <owl/semaphore.h> +#include <cmdl/cmdargs.h> + +#include "rcecalib/scanctrl/IPCScan.cc" +#include "rcecalib/scanctrl/IPCScanRoot.cc" +#include "rcecalib/config/IPCConfigIF.cc" +#include "rcecalib/HW/SerialHexdump.hh" +#include "rcecalib/config/IPCModuleFactory.hh" +#include "rcecalib/util/RceName.hh" +#include "rcecalib/scanctrl/Scan.hh" +OWLSemaphore semaphore; + +CmdArgBool echo ('e', "echo", "output results to stdout."); + +void sig_handler( int sig ) +{ + std::cout << " :: [IPCServer::sigint_handler] the signal " << sig << " received - exiting ... "<<std::endl; + semaphore.post(); +} + + +////////////////////////////////////////// +// +// Main function +// +////////////////////////////////////////// + + +int main ( int argc, char ** argv ) +{ + CmdArgStr partition_name ('p', "partition", "partition-name", "partition to work."); + + try { + IPCCore::init( argc, argv ); + } + catch( daq::ipc::Exception & ex ) { + ers::fatal( ex ); + return 1; + } + + // Declare command object and its argument-iterator + CmdLine cmd(*argv, &partition_name, &echo, NULL); + CmdArgvIter arg_iter(--argc, ++argv); + + // Parse arguments + + cmd.parse(arg_iter); + + signal( SIGINT , sig_handler ); + signal( SIGTERM, sig_handler ); + + + IPCPartition p((const char*)partition_name); + + //Serial IF + new SerialHexdump; + + //Module Factory + + ModuleFactory *moduleFactory=new IPCModuleFactory(p); + + char name[128]; + sprintf(name, "configIF_RCE%d", RceName::getRceNumber()); + // Config IF + IPCConfigIF<ipc::single_thread> *cif=new IPCConfigIF<ipc::single_thread>(p, name, moduleFactory); + + sprintf(name, "scanCtrl_RCE%d", RceName::getRceNumber()); + IPCScan<ipc::multi_thread> *scan = new IPCScan<ipc::multi_thread>( p, name); + sprintf(name, "scanRoot_RCE%d", RceName::getRceNumber()); + IPCScanRoot<ipc::single_thread> * scanroot = new IPCScanRoot<ipc::single_thread>( p, name, (ConfigIF*)cif, (Scan*)scan); + + sprintf(name, "RCE%d", RceName::getRceNumber()); + new IPCHistoManager(p,"RceIsServer", name); + // + std::cout << "ipc_test_server has been started." << std::endl; + + semaphore.wait(); + std::cout << "Shutdown." << std::endl; + + cif->_destroy(); + scanroot->_destroy(); + scan->_destroy(); + + if ( echo ) + { + std::cout << "Test successfully completed." << std::endl; + } + + return 0; +} diff --git a/rce/rcecalib/util/AbsRceHisto.cc b/rce/rcecalib/util/AbsRceHisto.cc new file mode 100644 index 0000000000000000000000000000000000000000..9d91c09d92c36bf6fef7da7e8b995f6dc2273475 --- /dev/null +++ b/rce/rcecalib/util/AbsRceHisto.cc @@ -0,0 +1,24 @@ +#include "rcecalib/util/AbsRceHisto.hh" +#include "rcecalib/util/IPCHistoManager.hh" +#include "oh/OHRawProvider.h" + +AbsRceHisto::AbsRceHisto(const char* name, const char* title, int ndim):m_ndim(ndim), m_name(name), m_title(title){ + IPCHistoManager* mgr=IPCHistoManager::instance(); + assert(mgr!=0); + mgr->addToInventory(this); +} +AbsRceHisto::~AbsRceHisto(){ + IPCHistoManager* mgr=IPCHistoManager::instance(); + assert(mgr!=0); + mgr->removeFromInventory(this); +} + +void AbsRceHisto::setAxisTitle(int axis, const char* title){ + if(axis>1)return; + m_axisTitle[axis]=title; +} +const char* AbsRceHisto::axisTitle(int axis){ + if(axis>1)return 0; + return m_axisTitle[axis].c_str(); +} + diff --git a/rce/rcecalib/util/AbsRceHisto.hh b/rce/rcecalib/util/AbsRceHisto.hh new file mode 100644 index 0000000000000000000000000000000000000000..d9ab9b3cf6f3835f8c41652aa2ecf642122d4f8b --- /dev/null +++ b/rce/rcecalib/util/AbsRceHisto.hh @@ -0,0 +1,31 @@ +#ifndef ABS_RCE_HISTO_HH +#define ABS_RCE_HISTO_HH +#include "oh/OHRawProvider.h" + + +class AbsRceHisto{ +public: + AbsRceHisto(const char* name, const char* title, int ndim); + virtual ~AbsRceHisto(); + std::string name() const {return m_name;} + std::string title() const { return m_title; }; + int nDim() const { return m_ndim; }; + virtual int nBin(int d) const { if (d >=0 && d <= 1) return m_dim[d]; else return 0; }; + float min(int d) const { if (d >=0 && d <= 1) return m_lim[d][0]; else return 0; }; + float max(int d) const { if (d >=0 && d <= 1) return m_lim[d][1]; else return 0; }; + void setAxisTitle(int axis, const char* title); + const char* axisTitle(int axis); + //retrieve histograms + virtual void publish(OHRawProvider<>*)=0; +protected: + int m_ndim; //! Number of dimensions (1 or 2) + std::string m_name; //! Histogram name + std::string m_title; //! Histogram title + std::string m_axisTitle[2]; //! Axis titles + unsigned int m_dim[2]; //! Dimensions + float m_lim[2][2]; //! Limits + float m_quot[2]; + float m_const[2]; +}; + +#endif diff --git a/rce/rcecalib/util/DataCond.hh b/rce/rcecalib/util/DataCond.hh new file mode 100644 index 0000000000000000000000000000000000000000..c6d923877a6ce5818919fb1fd368152ce46c9b34 --- /dev/null +++ b/rce/rcecalib/util/DataCond.hh @@ -0,0 +1,14 @@ +#ifndef DATACOND_HH +#define DATACOND_HH + +#include <omnithread.h> + +class DataCond{ +public: + DataCond(): cond(&mutex), waitingForData(false){} + omni_mutex mutex ; + omni_condition cond ; + bool waitingForData; +}; + +#endif diff --git a/rce/rcecalib/util/IPCHistoManager.cc b/rce/rcecalib/util/IPCHistoManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..5459f3f230311a74aa37cf7395200e3db010806f --- /dev/null +++ b/rce/rcecalib/util/IPCHistoManager.cc @@ -0,0 +1,70 @@ + +#include "rcecalib/util/IPCHistoManager.hh" +#include "ipc/partition.h" +#include "rcecalib/util/AbsRceHisto.hh" +#include "IPCScanRootAdapter.hh" +#include "oh/OHRawProvider.h" + + +#include <boost/regex.hpp> + +IPCHistoManager* IPCHistoManager::m_manager=0; + +IPCHistoManager::IPCHistoManager(IPCPartition& p, const char* servername, const char* providername){ + m_provider=new OHRawProvider<>(p, servername, providername, 0); + m_manager=this; +} +IPCHistoManager::~IPCHistoManager(){ + delete m_provider; + m_manager=0; +} +void IPCHistoManager::addToInventory(AbsRceHisto* histo){ + std::string name=histo->name(); + if(m_inventory.find(name)!=m_inventory.end()){ + std::cout<<"Histogram with name "<<name<<" exists already. Replacing..."<<std::endl; + } + m_inventory[name]=histo; +} +void IPCHistoManager::removeFromInventory(AbsRceHisto* histo){ + std::map<std::string, AbsRceHisto*>::iterator it; + it=m_inventory.find(histo->name()); + if(it==m_inventory.end()){ + std::cout<<"Histogram with name "<<histo->name()<<" was not in repository."<<std::endl; + }else{ + m_inventory.erase(it); + } + std::map<std::string, AbsRceHisto*>::iterator it2=m_published.find(histo->name()); + if(it2!=m_published.end()){ + m_published.erase(it2); + } +} + +void IPCHistoManager::publish(const char* rege){ + boost::regex re(rege); + std::map<std::string,AbsRceHisto*>::iterator it; + for(it=m_inventory.begin();it!=m_inventory.end();it++){ + if(boost::regex_match((*it).first,re)){ + (*it).second->publish(m_provider); + m_published[(*it).first]=(*it).second; + } + } +} +std::vector<std::string> IPCHistoManager::getHistoNames(const char *rege){ + std::vector<std::string> retvec; + boost::regex re(rege); + std::map<std::string,AbsRceHisto*>::iterator it; + for(it=m_inventory.begin();it!=m_inventory.end();it++){ + if(boost::regex_match((*it).first,re)){ + retvec.push_back((*it).first); + } + } + return retvec; +} +std::vector<std::string> IPCHistoManager::getPublishedHistoNames(){ + std::vector<std::string> retvec; + std::map<std::string,AbsRceHisto*>::iterator it; + for(it=m_published.begin();it!=m_published.end();it++){ + retvec.push_back((*it).first); + } + return retvec; +} diff --git a/rce/rcecalib/util/IPCHistoManager.hh b/rce/rcecalib/util/IPCHistoManager.hh new file mode 100644 index 0000000000000000000000000000000000000000..c2c31fe860c9fd302e9d5bec90c76a13d2df7470 --- /dev/null +++ b/rce/rcecalib/util/IPCHistoManager.hh @@ -0,0 +1,35 @@ +#ifndef IPC_HISTO_MANAGER_HH +#define IPC_HISTO_MANAGER_HH + +#include <vector> +#include <string> +#include <map> + + +class IPCPartition; + +class AbsRceHisto; +class OHBins; +template<class T> class OHRawProvider; +#include <iostream> + +class IPCHistoManager{ +public: + IPCHistoManager(IPCPartition& p, const char* servername, const char* providername); + ~IPCHistoManager(); + static IPCHistoManager* instance(){ + return m_manager; + } + void addToInventory(AbsRceHisto*); + void removeFromInventory(AbsRceHisto*); + void publish(const char* reg); + std::vector<std::string> getHistoNames(const char* reg); + std::vector<std::string> getPublishedHistoNames(); +private: + std::map<std::string,AbsRceHisto*> m_inventory; + std::map<std::string,AbsRceHisto*> m_published; + OHRawProvider<OHBins>* m_provider; + static IPCHistoManager* m_manager; +}; + +#endif diff --git a/rce/rcecalib/util/Makefile b/rce/rcecalib/util/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c73fd5ecf8dc4d62b2e91a172c156dbb5daecf1c --- /dev/null +++ b/rce/rcecalib/util/Makefile @@ -0,0 +1,20 @@ +# Package level makefile +# ---------------------- +%.mk:; + +# Checks +# ------ +# Check release location variables +ifeq ($(RELEASE_DIR),) +export RELEASE_DIR := $(PWD)/../.. +endif + +include $(RELEASE_DIR)/make/share/setup.mk +include ../flags.mk + +ifndef PREMAKE_DONE +include $(RELEASE_DIR)/make/share/premake.mk +else +include constituents.mk +include $(RELEASE_DIR)/make/sw/package.mk +endif diff --git a/rce/rcecalib/util/RceHisto1d.cc b/rce/rcecalib/util/RceHisto1d.cc new file mode 100644 index 0000000000000000000000000000000000000000..858729f071d3dd63f91a0fc74308b7e15e4e109e --- /dev/null +++ b/rce/rcecalib/util/RceHisto1d.cc @@ -0,0 +1,181 @@ +#ifndef RCEHISTO1D_CC +#define RCEHISTO1D_CC + +#include "rcecalib/util/RceHisto1d.hh" +#include "rcecalib/util/IPCHistoManager.hh" +#include <string> + +template<typename T, typename TE> +RceHisto1d<T, TE>::RceHisto1d(std::string name, std::string title, unsigned int nbin, float xmin, float xmax, bool hasErrors) + :AbsRceHisto(name.c_str(),title.c_str(),1), m_hasErrors(hasErrors){ + m_dim[0] = nbin; + m_dim[1] = 1; + m_lim[0][0] = xmin; + m_lim[0][1] = xmax; + m_lim[1][0] = 0; + m_lim[1][1] = 0; +// if(xmax-xmin!=0)m_quot[0]=float(nbin)/(xmax-xmin); +// else m_quot[0]=0; +// m_const[0]=xmin*m_quot[0]; + m_data=new T[nbin]; + if(m_hasErrors)m_err=new TE[nbin]; + else m_err=0; + for (unsigned int i=0; i<m_dim[0]; i++){ + m_data[i]=0; + if(m_hasErrors)m_err[i]=0; + } +} + +template<typename T, typename TE> +RceHisto1d<T, TE>::RceHisto1d(const RceHisto1d<T, TE> &h):AbsRceHisto(std::string(h.name()+"_copy").c_str(),h.title().c_str(),1){ + m_dim[0] = h.m_dim[0]; + m_dim[1] = h.m_dim[1]; + m_lim[0][0] = h.m_lim[0][0]; + m_lim[0][1] = h.m_lim[0][1]; + m_lim[1][0] = h.m_lim[1][0]; + m_lim[1][1] = h.m_lim[1][1]; + m_hasErrors = h.m_hasErrors; + m_quot[0]=h.m_quot[0]; + m_const[0]=h.m_const[0]; + m_data=new T[m_dim[0]]; + if(m_hasErrors)m_err=new TE[m_dim[0]]; + else m_err=0; + for (int i=0;i<m_dim[0];i++){ + m_data[i]=h(i); + if(m_hasErrors)m_err[i]=h.getBinError(i); + } +} + + +template<typename T, typename TE> +RceHisto1d<T, TE>::~RceHisto1d(){ + delete [] m_data; + if(m_hasErrors)delete [] m_err; +} + +template<typename T, typename TE> +RceHisto1d<T, TE>& RceHisto1d<T, TE>::operator=(const RceHisto1d<T, TE>&h){ + if (&h == this) { + return *this; + } else { + IPCHistoManager* mgr=IPCHistoManager::instance(); + assert(mgr!=0); + mgr->removeFromInventory(this); + delete [] m_data; + if(m_hasErrors)delete [] m_err; + m_ndim = h.m_ndim; + m_name = h.m_name+"_copy"; + m_title = h.m_title; + m_dim[0] = h.m_dim[0]; + m_dim[1] = h.m_dim[1]; + m_lim[0][0] = h.m_lim[0][0]; + m_lim[0][1] = h.m_lim[0][1]; + m_lim[1][0] = h.m_lim[1][0]; + m_lim[1][1] = h.m_lim[1][1]; + m_hasErrors = h.m_hasErrors; + m_quot[0]=h.m_quot[0]; + m_const[0]=h.m_const[0]; + m_data = new T[m_ndim]; + if(m_hasErrors)m_err = new TE[m_ndim]; + for (int i=0;i<m_dim[0];i++){ + m_data[i]=h(i); + if(m_hasErrors)m_err[i]=h.getBinError(i); + } + mgr->addToInventory(this); + } +} + + +template<typename T, typename TE> +T RceHisto1d<T, TE>::operator()(unsigned int i) const{ + return m_data[i]; + } +template<typename T, typename TE> +TE RceHisto1d<T,TE>::getBinError(unsigned i) const{ + if(!m_hasErrors)return 0; + return m_err[i]; +} +template<typename T, typename TE> +void RceHisto1d<T, TE>::set(unsigned int i, T val) { + if(i<m_dim[0])m_data[i]=val; + } +template<typename T, typename TE> +void RceHisto1d<T, TE>::setFast(unsigned int i, T val) { + m_data[i]=val; + } +template<typename T, typename TE> +void RceHisto1d<T, TE>::setBinError(unsigned int i, TE val) { + if(!m_hasErrors)return; + if(i<m_dim[0])m_err[i]=val; + } +template<typename T, typename TE> +void RceHisto1d<T, TE>::setBinErrorFast(unsigned int i, TE val) { + if(!m_hasErrors)return; + m_err[i]=val; + } + +template<typename T, typename TE> +void RceHisto1d<T, TE>::fill(unsigned int i, T val) { + if(i<m_dim[0])m_data[i]+=val; + } +template<typename T, typename TE> +void RceHisto1d<T, TE>::fillFast(unsigned int i, T val) { + m_data[i]+=val; + } +//template<typename T, typename TE> +//void RceHisto1d<T, TE>::fillByValue(float x, T val) { +// if(x>=m_lim[0][0]&&x<m_lim[0][1]){ +// unsigned bin=int (m_quot[0]*x-m_const[0] ); +// m_data[bin]+=val; +// } +//} + +template<typename T, typename TE> +void RceHisto1d<T, TE>::increment(unsigned int i) { + if(i<m_dim[0])m_data[i]++; +} +template<typename T, typename TE> +void RceHisto1d<T, TE>::incrementFast(unsigned int i) { + m_data[i]++; +} + +template<typename T, typename TE> +void RceHisto1d<T, TE>::clear() { + for (unsigned int i=0;i<m_dim[0];i++){ + m_data[i]=0; + if(m_hasErrors)m_err[i]=0; + } +} + + +template<typename T, typename TE> +void RceHisto1d<T, TE>::publish(OHRawProvider<>* p){ + double width=1; + if(nBin(0)>0)width=(max(0)-min(0))/nBin(0); + /* fix for TDAQ 4 relase */ +#ifndef TDAQ_RELEASE_4 + OHAxis<double> xaxis(m_axisTitle[0].c_str(), m_dim[0], min(0), width ); +#else + OHAxis xaxis=OHMakeAxis<double>(m_axisTitle[0].c_str(), m_dim[0], min(0), width ); +#endif + // Create Annotations + std::vector<std::pair<std::string,std::string> > annotations; + annotations.push_back( std::make_pair("RceHisto1d", "RawProvider publish") ); + + // Publish in OH + try { + p->publish(m_name, m_title, xaxis, m_data, m_err, false, -1, annotations); + } catch (daq::oh::RepositoryNotFound) { + std::string mess = "The repository is not found "; + std::cout<<mess<<std::endl; + } catch (daq::oh::ObjectTypeMismatch) { + std::string mess = "Arguments invalid "; + std::cout<<mess<<std::endl; + } catch (...) { + std::string mess = "Unknown exception thrown "; + std::cout<<mess<<std::endl; + } +} + + +#endif diff --git a/rce/rcecalib/util/RceHisto1d.hh b/rce/rcecalib/util/RceHisto1d.hh new file mode 100644 index 0000000000000000000000000000000000000000..55b3a7df29f3ebf805b08f6543a4575751973354 --- /dev/null +++ b/rce/rcecalib/util/RceHisto1d.hh @@ -0,0 +1,35 @@ +#ifndef RCE_HISTO1D_HH +#define RCE_HISTO1D_HH + +#include "rcecalib/util/AbsRceHisto.hh" + +#include "oh/OHRawProvider.h" + + +template<typename T, typename TE> class RceHisto1d: public AbsRceHisto{ +public: + RceHisto1d(std::string name, std::string title, unsigned int nbin, float xmin, float xmax, bool hasErrors=false); //! Constructor 1D + RceHisto1d(const RceHisto1d<T, TE> &h); //! Copy contructor + virtual ~RceHisto1d(); + RceHisto1d &operator=(const RceHisto1d<T, TE>&h); + T operator()(unsigned i) const; + TE getBinError(unsigned i) const; + inline void setBinError(unsigned int i, TE val); + inline void setBinErrorFast(unsigned int i, TE val); + inline void set(unsigned int i, T val); //! Bin write access 1d + inline void setFast(unsigned int i, T val); //! Bin write access 1d + inline void fill(unsigned int i, T val); + inline void fillFast(unsigned int i, T val); +// inline void fillByValue(float x, T val); + inline void increment(unsigned int i); + inline void incrementFast(unsigned int i); + void clear(); + void publish(OHRawProvider<>* p); +private: + T *m_data; + TE *m_err; + bool m_hasErrors; +}; + + +#endif diff --git a/rce/rcecalib/util/RceHisto2d.cc b/rce/rcecalib/util/RceHisto2d.cc new file mode 100644 index 0000000000000000000000000000000000000000..327239f3541040c0347d33d01b05fec8c0a2c10c --- /dev/null +++ b/rce/rcecalib/util/RceHisto2d.cc @@ -0,0 +1,223 @@ +#ifndef RCEHISTO2D_CC +#define RCEHISTO2D_CC + +#include "rcecalib/util/RceHisto2d.hh" +#include "rcecalib/util/IPCHistoManager.hh" +#include <iostream> + +template<typename T, typename TE> +RceHisto2d<T, TE>::RceHisto2d(std::string name, std::string title, unsigned int nbin, float xmin, float xmax, + unsigned int nbin2, float ymin, float ymax, bool isreversed, bool hasErrors) + :AbsRceHisto(name.c_str(),title.c_str(),2), m_hasErrors(hasErrors), m_reverse(isreversed){ + m_dim[0] = nbin; + m_dim[1] = nbin2; + m_lim[0][0] = xmin; + m_lim[0][1] = xmax; + m_lim[1][0] = ymin; + m_lim[1][1] = ymax; + +// if(xmax-xmin!=0)m_quot[0]=float(nbin)/(xmax-xmin); +// else m_quot[0]=0; +// m_const[0]=xmin*m_quot[0]; +// if(ymax-ymin!=0)m_quot[1]=float(nbin2)/(ymax-ymin); +// else m_quot[1]=0; +// m_const[1]=ymin*m_quot[1]; + + m_data = new T[m_dim[0]*m_dim[1]]; + if(m_hasErrors) m_err = new TE[m_dim[0]*m_dim[1]]; + else m_err=0; + for (unsigned int i=0; i<m_dim[0]*m_dim[1]; i++) { + m_data[i] = 0; + if(m_hasErrors)m_err[i]=0; + } +} +template<typename T, typename TE> +RceHisto2d<T, TE>::RceHisto2d(const RceHisto2d<T, TE> &h):AbsRceHisto(std::string(h.name()+"_copy").c_str(),h.title().c_str(),2){ + m_dim[0] = h.m_dim[0]; + m_dim[1] = h.m_dim[1]; + m_lim[0][0] = h.m_lim[0][0]; + m_lim[0][1] = h.m_lim[0][1]; + m_lim[1][0] = h.m_lim[1][0]; + m_lim[1][1] = h.m_lim[1][1]; + m_hasErrors = h.m_hasErrors; + m_reverse = h.m_reverse; + m_quot[0]=h.m_quot[0]; + m_const[0]=h.m_const[0]; + m_quot[1]=h.m_quot[1]; + m_const[1]=h.m_const[1]; + m_data = new T[m_dim[0]*m_dim[1]]; + if(m_hasErrors) m_err = new TE[m_dim[0]*m_dim[1]]; + else m_err=0; + for (unsigned int i=0; i<m_dim[0]*m_dim[1]; i++) { + m_data[i] = 0; + if(m_hasErrors)m_err[i]=0; + } +} + + +template<typename T, typename TE> +RceHisto2d<T, TE>::~RceHisto2d(){ + delete [] m_data; + if(m_hasErrors)delete [] m_err; +} + +template<typename T, typename TE> +RceHisto2d<T, TE>& RceHisto2d<T, TE>::operator=(const RceHisto2d<T, TE>&h){ + if (&h == this) { + return *this; + } else { + IPCHistoManager* mgr=IPCHistoManager::instance(); + assert(mgr!=0); + mgr->removeFromInventory(this); + delete [] m_data; + if(m_hasErrors)delete [] m_err; + m_ndim = h.m_ndim; + m_name = h.m_name+"_copy"; + m_title = h.m_title; + m_dim[0] = h.m_dim[0]; + m_dim[1] = h.m_dim[1]; + m_lim[0][0] = h.m_lim[0][0]; + m_lim[0][1] = h.m_lim[0][1]; + m_lim[1][0] = h.m_lim[1][0]; + m_lim[1][1] = h.m_lim[1][1]; + m_hasErrors = h.m_hasErrors; + m_reverse = h.m_reverse; + m_quot[0]=h.m_quot[0]; + m_const[0]=h.m_const[0]; + m_quot[1]=h.m_quot[1]; + m_const[1]=h.m_const[1]; + m_data = new T[m_dim[0]*m_dim[1]]; + if(m_hasErrors) m_err = new TE[m_dim[0]*m_dim[1]]; + else m_err=0; + for (unsigned int i=0; i<m_dim[0]*m_dim[1]; i++) { + m_data[i] = h.m_data[i]; + if(m_hasErrors)m_err[i]=h.m_err[i]; + } + mgr->addToInventory(this); + } +} + + +template<typename T, typename TE> +inline T RceHisto2d<T, TE>::operator()(unsigned int i, unsigned int j) { + return m_data[index(i,j)]; + } + +template<typename T, typename TE> +inline TE RceHisto2d<T, TE>::getBinError(unsigned int i, unsigned int j) { + if(!m_hasErrors)return 0; + return m_err[index(i,j)]; + } + +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::set(unsigned int i, unsigned j, T val) { + if(i<m_dim[0]&&j<m_dim[1])m_data[index(i,j)]=val; + } +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::setFast(unsigned int i, unsigned j, T val) { + m_data[index(i,j)]=val; + } + +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::setBinError(unsigned int i, unsigned j, TE val) { + if(!m_hasErrors)return; + if(i<m_dim[0]&&j<m_dim[1])m_err[index(i,j)]=val; + } +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::setBinErrorFast(unsigned int i, unsigned j, TE val) { + if(!m_hasErrors)return; + m_err[index(i,j)]=val; + } + +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::fill(unsigned int i, unsigned j, T val) { + if(i<m_dim[0]&&j<m_dim[1])m_data[index(i,j)]+=val; + } +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::fillFast(unsigned int i, unsigned j, T val) { + m_data[index(i,j)]+=val; + } +//template<typename T, typename TE> +//inline void RceHisto2d<T, TE>::fillByValue(float x, float y, T val) { +// if(x>=m_lim[0][0]&&x<m_lim[0][1] && y>=m_lim[1][0]&&y<m_lim[1][1]){ +// unsigned binx=int (m_quot[0]*x-m_const[0] ); +// unsigned biny=int (m_quot[1]*y-m_const[1] ); +// m_data[index(binx,biny)]+=val; +// } +//} +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::increment(unsigned int i, unsigned j) { + if(i<m_dim[0]&&j<m_dim[1])m_data[index(i,j)]++; +} +template<typename T, typename TE> +inline void RceHisto2d<T, TE>::incrementFast(unsigned int i, unsigned j) { + m_data[index(i,j)]++; +} + + + +template<typename T, typename TE> +void RceHisto2d<T, TE>::clear() { + for (unsigned int i=0;i<m_dim[0]*m_dim[1];i++){ + m_data[i]=0; + if(m_hasErrors)m_err[i]=0; + } +} + + +template<typename T, typename TE> +void RceHisto2d<T, TE>::publish(OHRawProvider<>* p){ + double widthx=1; + if(nBin(0)>0)widthx=(max(0)-min(0))/nBin(0); + double widthy=1; + if(nBin(1)>0)widthy=(max(1)-min(1))/nBin(1); + /* fix for TDAQ 4 release */ +#ifndef TDAQ_RELEASE_4 + OHAxis<double> xaxis(m_axisTitle[0].c_str(), m_dim[0], min(0), widthx); + OHAxis<double> yaxis(m_axisTitle[1].c_str(),m_dim[1], min(1), widthy); +#else + OHAxis xaxis=OHMakeAxis<double>(m_axisTitle[0].c_str(), m_dim[0], min(0), widthx); + OHAxis yaxis=OHMakeAxis<double>(m_axisTitle[1].c_str(),m_dim[1], min(1), widthy); +#endif + // Create Annotations + std::vector<std::pair<std::string,std::string> > annotations; + annotations.push_back( std::make_pair("RceHisto2d", "RawProvider publish") ); + + T* sdata=0; + TE* serr=0; + // if x and y were swapped for performance reasons swap them back before shipping + if(m_reverse){ + sdata=new T[m_dim[0]*m_dim[1]]; + if(m_err)serr=new TE[m_dim[0]*m_dim[1]]; + for (unsigned i=0;i<m_dim[0]*m_dim[1];i++){ + sdata[i]=m_data[(i%m_dim[1])*m_dim[0]+(i/m_dim[1])]; + if(m_err)serr[i]=m_err[(i%m_dim[1])*m_dim[0]+(i/m_dim[1])]; + } + } + + // Publish in OH + try { + if(m_reverse) p->publish(m_name, m_title, yaxis, xaxis, sdata, serr, false, -1, annotations); + else p->publish(m_name, m_title, xaxis, yaxis, m_data, m_err, false, -1, annotations); + } catch (daq::oh::RepositoryNotFound) { + std::string mess = "The repository is not found "; + std::cout<<mess<<std::endl; + } catch (daq::oh::ObjectTypeMismatch) { + std::string mess = "Arguments invalid "; + std::cout<<mess<<std::endl; + } catch (...) { + std::string mess = "Unknown exception thrown "; + std::cout<<mess<<std::endl; + } + if(m_reverse){ + delete [] sdata; + if(m_hasErrors)delete [] serr; + } +} + +template<typename T, typename TE> +inline int RceHisto2d<T, TE>::index(int x, int y){ + return x+y*m_dim[0]; +} + +#endif diff --git a/rce/rcecalib/util/RceHisto2d.hh b/rce/rcecalib/util/RceHisto2d.hh new file mode 100644 index 0000000000000000000000000000000000000000..2a53bfc65ee17d0b84e5008599bb8d4d65cb9d32 --- /dev/null +++ b/rce/rcecalib/util/RceHisto2d.hh @@ -0,0 +1,38 @@ +#ifndef RCE_HISTO2D_HH +#define RCE_HISTO2D_HH + +#include "rcecalib/util/AbsRceHisto.hh" + +#include "oh/OHRawProvider.h" + + +template<typename T, typename TE> class RceHisto2d: public AbsRceHisto{ +public: + RceHisto2d(std::string name, std::string title, unsigned int nbin, float xmin, float xmax, //! Constructor 2D + unsigned int nbin2, float xmin2, float xmax2, bool isreversed=false, bool hasErrors=false); + RceHisto2d(const RceHisto2d<T, TE> &h); //! Copy contructor + virtual ~RceHisto2d(); + RceHisto2d &operator=(const RceHisto2d<T, TE>&h); + T operator()(unsigned i, unsigned j); + TE getBinError(unsigned i, unsigned j); + void setBinError(unsigned int i, unsigned j, TE val); + void setBinErrorFast(unsigned int i, unsigned j, TE val); + void set(unsigned int i, unsigned j, T val); //! Bin write access 2d + void setFast(unsigned int i, unsigned j, T val); //! Bin write access 2d + void fill(unsigned int i, unsigned j, T val); + void fillFast(unsigned int i, unsigned j, T val); +// void fillByValue(float x, float y, T val); + void increment(unsigned int i, unsigned j); + void incrementFast(unsigned int i, unsigned j); + void clear(); + void publish(OHRawProvider<>* p); +private: + int index(int x, int y); + T *m_data; + TE *m_err; + bool m_hasErrors; + bool m_reverse; +}; + + +#endif diff --git a/rce/rcecalib/util/RceMath.cc b/rce/rcecalib/util/RceMath.cc new file mode 100644 index 0000000000000000000000000000000000000000..2738d177b326ab3e4563141828c31d7f9a71c928 --- /dev/null +++ b/rce/rcecalib/util/RceMath.cc @@ -0,0 +1,41 @@ +#include "rcecalib/util/RceMath.hh" + +namespace RceMath { +// Calculates SQRT fast, but not very precise +// Dirty playing with bits can give us the sqrt of a float +// Depends on the 32bit architecture +// See: http://bits.stephan-brumme.com/squareRoot.html +float fastCoarseSqrt(float x) { + // Get around dirty casting + union { + float x; + unsigned int i; + } u; + u.x = x; + // adjust bias + u.i += 127 << 23; + // approximation of square root + u.i >>= 1; + //printf("sqrt(%f)=%f\n",x, u.x); + return u.x; +} + +// Calcutes SQRT fast and kinda precise, but no as fast as fastCoarseSqrt() +// Uses basically the same method, but adds a newton approximation step +// to increase precision +// Taken from Quake3 engine +// See: http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf +float fastQuakeSqrt(const float x) { + const float xhalf = 0.5f*x; + union { // get bits for floating value + float x; + int i; + } u; + u.x = x; + u.i = 0x5f3759df - (u.i >> 1); // gives initial guess y0 + float result = x*u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy + //printf("sqrt(%f)=%f\n",x, result); + return result; +} + +} diff --git a/rce/rcecalib/util/RceMath.hh b/rce/rcecalib/util/RceMath.hh new file mode 100644 index 0000000000000000000000000000000000000000..32a0d91eeb6c9c2b33b0de1eb4fcbdb35ec20c6d --- /dev/null +++ b/rce/rcecalib/util/RceMath.hh @@ -0,0 +1,13 @@ +// Mathmatical helper functions + +#ifndef RCEMATH_HH +#define RCEMATH_HH + +#include <stdio.h> + +namespace RceMath { + float fastCoarseSqrt(float x); + float fastQuakeSqrt(float x); +} + +#endif diff --git a/rce/rcecalib/util/RceName.cc b/rce/rcecalib/util/RceName.cc new file mode 100644 index 0000000000000000000000000000000000000000..278830c929b2d715c9c62436a79cfb548cef3bc7 --- /dev/null +++ b/rce/rcecalib/util/RceName.cc @@ -0,0 +1,20 @@ +#include "rcecalib/util/RceName.hh" +#include <stdlib.h> +#include <assert.h> + +int RceName::m_number=0; +bool RceName::m_initialized=false; + +int RceName::getRceNumber(){ + if(m_initialized==false){ + char* name=getenv("RCE_NAME"); + char* endptr; + if(name){ + m_number=(int)strtol(name, &endptr, 0); + assert(*endptr=='\0'); + } + else m_number=0; + m_initialized=true; + } + return m_number; +} diff --git a/rce/rcecalib/util/RceName.hh b/rce/rcecalib/util/RceName.hh new file mode 100644 index 0000000000000000000000000000000000000000..899d8c30452931851304724343a45ce52a167c2f --- /dev/null +++ b/rce/rcecalib/util/RceName.hh @@ -0,0 +1,14 @@ +#ifndef RCENAME_HH +#define RCENAME_HH + +#include <string> + +class RceName{ +public: + static int getRceNumber(); +private: + static int m_number; + static bool m_initialized; +}; + +#endif diff --git a/rce/rcecalib/util/VerifyErrors.hh b/rce/rcecalib/util/VerifyErrors.hh new file mode 100644 index 0000000000000000000000000000000000000000..9569b7be0854be4019a6de53bab6a30873227b75 --- /dev/null +++ b/rce/rcecalib/util/VerifyErrors.hh @@ -0,0 +1,11 @@ +#ifndef VERIFY_ERRORS_HH +#define VERIFY_ERRORS_HH + +namespace ModuleVerify{ + + enum verify_errors{OK=0, GLOBAL_READBACK_FAILED=0x1, GLOBAL_READBACK_DIFFERENT=0x2, PIXEL_WRONG_N_WORDS=0x4, + PIXEL_READBACK_DIFFERENT=0x8, NO_FORMATTER=0x100, NO_MODULE=0x200}; + +}; + +#endif diff --git a/rce/rcecalib/util/constituents.mk b/rce/rcecalib/util/constituents.mk new file mode 100644 index 0000000000000000000000000000000000000000..29c85cf95ae8f47625a6222065c89c8f0ae6f151 --- /dev/null +++ b/rce/rcecalib/util/constituents.mk @@ -0,0 +1,28 @@ + +ifdef SWAP_DATA +CPPFLAGS += '-DSWAP_DATA' +endif + +ifneq ($(findstring ppc-rtems-rce,$(tgt_arch)),) +modlibnames := util +endif +ifneq ($(findstring linux,$(tgt_os)),) +libnames := util +endif + +libsrcs_util := IPCHistoManager.cc \ + RceName.cc \ + AbsRceHisto.cc \ + RceMath.cc + + +libincs_util := rcecalib \ + $(ers_include_path) \ + $(owl_include_path) \ + $(ipc_include_path) \ + $(is_include_path) \ + $(oh_include_path) \ + $(boost_include_path) \ + $(omniorb_include_path) + + diff --git a/rce/rcecalib/util/exceptions.hh b/rce/rcecalib/util/exceptions.hh new file mode 100644 index 0000000000000000000000000000000000000000..1a54acdad488d0030136126fc00b6167522d8966 --- /dev/null +++ b/rce/rcecalib/util/exceptions.hh @@ -0,0 +1,33 @@ +#ifndef SCANCTRLEXCEPTIONS_HH +#define SCANCTRLEXCEPTIONS_HH + +#include "ers/ers.h" + +ERS_DECLARE_ISSUE( rcecalib, // namespace name + Bad_ptree_param, // issue name + "Bad scan parameter: " << reason, // message + ((const char *)reason ) // first attribute + ) + +ERS_DECLARE_ISSUE( rcecalib, // namespace name + Param_exists, // issue name + "Parameter " << reason <<" was previously defined", // message + ((const char *)reason ) // first attribute + ) +ERS_DECLARE_ISSUE( rcecalib, // namespace name + Unknown_Module_Type, // issue name + "No such module type: " << reason, // message + ((const char *)reason ) // first attribute + ) +ERS_DECLARE_ISSUE( rcecalib, // namespace name + Unknown_Scan_Type, // issue name + "No such scan type: " << reason, // message + ((const char *)reason ) // first attribute + ) +ERS_DECLARE_ISSUE( rcecalib, // namespace name + Config_File_Error, // issue name + "Error in config file " , // message + ) + + +#endif diff --git a/rce/rcecalib/xmd.ini b/rce/rcecalib/xmd.ini new file mode 100755 index 0000000000000000000000000000000000000000..ddd58a055b7e3689e7330f760cd8668f7bf86aa3 --- /dev/null +++ b/rce/rcecalib/xmd.ini @@ -0,0 +1 @@ +connect ppc hw -cable type xilinx_platformusb frequency 12000000 -debugdevice isocmstartadr 0xFFFFF000 isocmsize 4096 isocmdcrstartadr 0x0000000 icachestartadr 0x10000000 itagstartadr 0x20000000 dcachestartadr 0x30000000 dtagstartadr 0x40000000 dcrstartadr 0x50000000 diff --git a/rce/scripts/cmake_script b/rce/scripts/cmake_script new file mode 100755 index 0000000000000000000000000000000000000000..9a5d499c6771a3cb71bd5d1791f13c8317f623b2 --- /dev/null +++ b/rce/scripts/cmake_script @@ -0,0 +1,3 @@ +#!/bin/bash +unset LD_LIBRARY_PATH +echo `/usr/bin/cmake $*` diff --git a/rce/scripts/dumpscans b/rce/scripts/dumpscans new file mode 100755 index 0000000000000000000000000000000000000000..0f799517d6f2cffc5236d12c06496f9a3558595c --- /dev/null +++ b/rce/scripts/dumpscans @@ -0,0 +1,22 @@ +#!/bin/csh -f + +rm -f ./scan_fei3 ./scan_fei4a ./scan_fei4b + +touch ./scan_fei3 +touch ./scan_fei4a +touch ./scan_fei4b + +foreach i (`dumpRceScan -l `) +set i=`echo $i | tr -d '\n'` +echo $i >> ./scan_fei3 +dumpRceScan -f PM_FE_I2 $i >> scan_fei3 + +echo $i >> ./scan_fei4b +dumpRceScan -f PM_FE_I4B $i >> scan_fei4b + +echo $i >> ./scan_fei4a +dumpRceScan -f PM_FE_I4A $i >> scan_fei4a + + +end + diff --git a/rce/scripts/findUndefSymbols.pl b/rce/scripts/findUndefSymbols.pl new file mode 100755 index 0000000000000000000000000000000000000000..bded55b22e5021efb0796c09215474014be5f896 --- /dev/null +++ b/rce/scripts/findUndefSymbols.pl @@ -0,0 +1,38 @@ +#!/usr/bin/perl -w + +$core=$ARGV[0]; +$mod=$ARGV[1]; + +@nmm=`nm $mod`; +foreach (@nmm) { + $_ =~ s/^[0-9a-f]* //; + chomp; + @tbm=split; + #print "x$tbm[0]x\n"; + if($tbm[0] eq "U"){ + #print $tbm[1]."\n"; + $usym{$tbm[1]}=0; + } +} +#print %usym; + +@nmc=`nm $core`; +foreach (@nmc) { + $_ =~ s/^[0-9a-f]* //; + chomp; + @tbc=split; + if($tbc[0] ne "U"){ + #print $tbm[1]."\n"; + $usym{$tbc[1]}=1; + } + #print $tbc[0]."\n"; +} +#print $usym{"sleep"}."\n" ; +print "LXFLAGS +="; +for $key ( keys %usym ){ + if ($usym{$key}==0){ + print " -u $key"; + } +} +print "\n"; + diff --git a/rce/scripts/patch.links b/rce/scripts/patch.links new file mode 100755 index 0000000000000000000000000000000000000000..13ebd4ea2b740ca1a9f7b1606f2a68ba4df72c7b --- /dev/null +++ b/rce/scripts/patch.links @@ -0,0 +1,7 @@ +#!/bin/tcsh +ln -sf /daq/slc5/tdaq-common/tdaq-common-01-18-04/installed/i686-slc5-gcc43-opt /daq/slc5/tdaq-common/tdaq-common-01-18-04/installed/i686-slc5-gcc43-dbg +ln -sf /daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6/i686-slc5-gcc43-opt /daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6/i686-slc5-gcc43-dbg +ln -sf /daq/slc5/tdaq/tdaq-04-00-01/installed/i686-slc5-gcc43-opt /daq/slc5/tdaq/tdaq-04-00-01/installed/i686-slc5-gcc43-dbg +ln -sf /daq/slc5/tdaq/tdaq-04-00-01/external/i686-slc5-gcc43-opt /daq/slc5/tdaq/tdaq-04-00-01/external/i686-slc5-gcc43-dbg +ln -sf /daq/slc5/opt/rcecore/1.4/build/rce/lib/i686-slc5-gcc43-opt /daq/slc5/opt/rcecore/1.4/build/rce/lib/i686-slc5-gcc43-dbg + diff --git a/rce/scripts/rce_dow b/rce/scripts/rce_dow new file mode 100755 index 0000000000000000000000000000000000000000..9b5ca15ce06d51b906472cd86e6e335bcc43336a --- /dev/null +++ b/rce/scripts/rce_dow @@ -0,0 +1,8 @@ +#!/bin/tcsh + +setenv TCL_LIBRARY /usr/share/tcl8.4 + +cd $RCE_BIN + +ln -sf $XMD_INI . +expect -f $HOME/rce/rcecalib/scripts/rce_dow.ex diff --git a/rce/scripts/rce_dow.ex b/rce/scripts/rce_dow.ex new file mode 100644 index 0000000000000000000000000000000000000000..389611708478d75d803958a5dc3f3074706660ba --- /dev/null +++ b/rce/scripts/rce_dow.ex @@ -0,0 +1,18 @@ +set timeout 120 +spawn xmd +expect "Starting GDB" +expect "XMD%" +send "stop\r" +expect "XMD%" +send "rst -processor\r" +expect "Target reset" +expect "XMD%" +send "dow calibserver\r" +expect "Setting PC" +expect "XMD%" +send "con\r" +expect "Info:Processor started" +expect "RUNNING> XMD%" +send "\r" +expect "XMD%" +send "exit\r" diff --git a/rce/scripts/setup-gen3.sh b/rce/scripts/setup-gen3.sh index ac775f1170a63d6ffbaa7e3e79f4b20d77d758b6..21a35bdc63fbaa5b13be3fa5d11d18e5b7c664c2 100644 --- a/rce/scripts/setup-gen3.sh +++ b/rce/scripts/setup-gen3.sh @@ -3,9 +3,8 @@ export TDAQ_VERSION=6 export LCG_INST_PATH=/sw/atlas export SDK_ROOT=/opt/AtlasRceSdk/V0.11.1 -_topdir=$(dirname ${BASH_SOURCE})/.. -_topdir=$(cd ${_topdir}/> /dev/null 2>&1 && pwd) -echo ${_topdir} + + source $LCG_INST_PATH/sw/lcg/contrib/gcc/4.9.3/x86_64-slc6/setup.sh source $SDK_ROOT/setup.sh @@ -34,26 +33,26 @@ fi export ROOTSYS=$LCG_INST_PATH/sw/lcg/LCG_81b/ROOT/6.04.12/x86_64-slc6-gcc49-opt export TDAQ_INST_PATH=/sw/atlas/tdaq/tdaq-06-01-00/installed set -- -if [ -d ${_topdir}/scripts ]; then - if [ ! -d ${_topdir}/$arm ]; then - echo Creating ${_topdir}/rce/$arm - mkdir ${_topdir}/$arm +if [ -d ~/daq/rce/scripts ]; then + if [ ! -d ~/daq/rce/$arm ]; then + echo Creating ~/daq/rce/$arm + mkdir ~/daq/rce/$arm fi - if [ ! -d ${_topdir}/$slc ]; then - echo Creating ${_topdir}/$slc - mkdir ${_topdir}/$slc + if [ ! -d ~/daq/rce/$slc ]; then + echo Creating ~/daq/rce/$slc + mkdir ~/daq/rce/$slc fi # source /sw/atlas/setup.sh export MAKEFLAGS="-j12 QUICK=1" - echo cd ${_topdir}/$arm - cd ${_topdir}/$arm - cmake -DCMAKE_BUILD_TYPE="$debug" -DCMAKE_TOOLCHAIN_FILE=${_topdir}/pixelrce/toolchain/arm-archlinux ${_topdir}/pixelrce $rcf - echo cd ${_topdir}/$slc - cd ${_topdir}/$slc - cmake -DCMAKE_BUILD_TYPE="$debug" -DCMAKE_TOOLCHAIN_FILE=${_topdir}/pixelrce/toolchain/tdaq-linux ${_topdir}/pixelrce $rcf + echo cd ~/daq/rce/$arm + cd ~/daq/rce/$arm + cmake -DCMAKE_BUILD_TYPE="$debug" -DCMAKE_TOOLCHAIN_FILE=~/daq/rce/pixelrce/toolchain/arm-archlinux ~/daq/rce/pixelrce $rcf + echo cd ~/daq/rce/$slc + cd ~/daq/rce/$slc + cmake -DCMAKE_BUILD_TYPE="$debug" -DCMAKE_TOOLCHAIN_FILE=~/daq/rce/pixelrce/toolchain/tdaq-linux ~/daq/rce/pixelrce $rcf -export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${_topdir}/${slc}/lib -export PATH=${PATH}:${_topdir}/${slc}/bin +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:~/daq/rce/${slc}/lib +export PATH=${PATH}:~/daq/rce/${slc}/bin export TDAQ_PARTITION=rce_$USER export TDAQ_IPC_INIT_REF=file:~/daq/ipc_root.ref export ORBHOST=192.168.1.1 @@ -65,7 +64,6 @@ alias rce_ipc_ls='ipc_ls ; ipc_ls -p $TDAQ_PARTITION' alias rce_killall='pkill -u $USER ipc_server; pkill -u $USER is_server;' else - echo "${_topdir}/scripts does not exist" + echo "~/daq/rce/scripts does not exist" fi popd -unset _topdir diff --git a/rce/scripts/setup_rce-04-00-00.csh b/rce/scripts/setup_rce-04-00-00.csh new file mode 100644 index 0000000000000000000000000000000000000000..cfe7b5f601f00741150a2f011ecd4d00517ba027 --- /dev/null +++ b/rce/scripts/setup_rce-04-00-00.csh @@ -0,0 +1,148 @@ +#--> These aliases are used to manipulate environmental variables used to hold +#--> directory paths, e.g. PATH, MANPATH. They allow one to append, prepend +#--> or remove specific directories from such variables. +alias addpath_clean 'delpath \!:*; setenv \!:1 ${\!:1}\:\!:2' +alias addpath2_clean 'delpath \!:*; setenv \!:1 \!:2\:${\!:1}' +# add to end of path +alias addpath 'if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* && $\!:1 !~ *\:\!:2\:* && $\!:1 !~ *\:\!:2 ) setenv \!:1 ${\!:1}\:\!:2' +# add to front of path +alias addpath2 'if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* && $\!:1 !~ *\:\!:2\:* && $\!:1 !~ *\:\!:2 ) setenv \!:1 \!:2\:${\!:1}; if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* ) setenv \!:1 \!:2\:`echo ${\!:1} | sed -e s%^\!:2\:%% -e s%:\!:2\:%:%g -e s%:\!:2\$%%`' +alias delpath 'setenv \!:1 `echo ${\!:1} | sed -e s%^\!:2\$%% -e s%^\!:2\:%% -e s%:\!:2\:%:%g -e s%:\!:2\$%%`' +alias modpath 'setenv \!:1 `echo ${\!:1} | sed -e s%^\!:2\$%\!:3% -e s%^\!:2\:%\!:3\:% -e s%:\!:2\:\%:\!:3\:\%g -e s%:\!:2\$%\:\!:3\%`' + +if ( ! -d /home/$USER ) then +exit 0 +endif + +if ( ! $?LD_LIBRARY_PATH ) then +setenv LD_LIBRARY_PATH +endif + +setenv TDAQ_VERSION 4 + +setenv ORBHOST '' +setenv ORBHOST `/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if ( $ORBHOST != '' ) then +setenv ORBendPoint giop:tcp:${ORBHOST}:0 +else +unsetenv ORBHOST +endif + +setenv TDAQ_IPC_INIT_REF file:${HOME}/ipc_root.ref +if ( `uname -m` == 'x86_64' ) then +setenv HOST_ARCH x86_64-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH x86_64-slc5-gcc43-opt +endif +if (`uname -m` == 'i386' ) then +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt +endif + +#override for now - x86_64 build is broken +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt + +setenv RCE_ARCH ppc-rtems-rce405-opt +setenv RCE ${HOME}/rce + +#ambush setup +if ( -e /reg/g/atlas/ambush ) then +setenv AMBUSH /reg/g/atlas/ambush +addpath2 LD_LIBRARY_PATH ${AMBUSH}/lib +addpath2 PATH ${AMBUSH}/bin +endif + +#setup python +if ( -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ) then +addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib +addpath2 PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin +else + echo Error: Python is not installed + exit 1 +endif + +if ( -e /daq/slc5/opt/rtems-4.9.2 ) then + setenv RTEMS /daq/slc5/opt/rtems-4.9.2 +else + echo Error: RTEMS is not installed +endif + +#setup rtems cross compilers +set RTEMS_GCC='' + +if ( -e /daq/slc5/opt/powerpc-rtems49-gcc432 ) then + set RTEMS_GCC=/daq/slc5/opt/powerpc-rtems49-gcc432 +else + echo "rtems gcc not found" + exit 1 +endif + +if ( $RTEMS_GCC != '' ) then +addpath2 LD_LIBRARY_PATH $RTEMS_GCC/lib +addpath2 PATH $RTEMS_GCC/bin +endif + +#setup ROOT +setenv ROOTSYS '' +if ( -e /daq/slc5/sw/lcg/app/releases/ROOT/5.30.02/$TDAQ_HOST_ARCH ) then + setenv ROOTSYS /daq/slc5/sw/lcg/app/releases/ROOT/5.30.02/$TDAQ_HOST_ARCH/root +# this needs the TDAQ gcc + if ( `uname -m` == 'x86_64') then + source /daq/slc5/sw/lcg/contrib/gcc/4.3.5/x86_64-slc5-gcc43-opt/setup.csh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc43-opt/lib + else + source /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.csh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34-opt/lib + endif +else + echo "TDAQ gcc not installed" + exit 1 +endif +if ( $ROOTSYS != '' ) then +addpath2 PATH $ROOTSYS/bin +addpath2 LD_LIBRARY_PATH $ROOTSYS/lib +endif + +#setup RCE client software +addpath2 PATH ${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts +addpath2 LD_LIBRARY_PATH ${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH} + +setenv RELEASE ${RCE} +setenv RCE_BIN ${RCE}/build/rcecalib/bin/${RCE_ARCH} +setenv RCE_MOD ${RCE}/build/rcecalib/mod/${RCE_ARCH} + +setenv XMD_INI ${RCE}/rcecalib/xmd.ini +setenv TDAQ_IPC_INIT_REF file:/${HOME}/ipc_root.ref +setenv SVNROOT svn+ssh://svn.cern.ch/reps/RceCimDev +setenv TDAQ_PARTITION rcetest_${USER} + +alias rce_ipc_server 'ipc_server -p $TDAQ_PARTITION' +alias rce_is_server 'is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls 'ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +alias rce_load 'echo "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r \!:1 -l $RCE_MOD/calibservermod.1.0.prod.so' +alias rce_killall 'pkill -u $USER ipc_server; pkill -u $USER is_server;' + +if ( ! -d ~/calibData ) then +mkdir ~/calibData +endif + +#tdaq setup +setenv TDAQ_INST_PATH /daq/slc5/tdaq/tdaq-04-00-00/installed +setenv TDAQC_INST_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-03/installed +setenv TDAQC_EXT_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-03/external +setenv TDAQ_BOOST /daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6 +addpath2 PATH $TDAQ_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_EXT_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_EXT_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQ_INST_PATH/share/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/share/lib +setenv PYTHONPATH $TDAQ_INST_PATH/$HOST_ARCH/lib + +rehash + + + + diff --git a/rce/scripts/setup_rce-04-00-01.csh b/rce/scripts/setup_rce-04-00-01.csh new file mode 100644 index 0000000000000000000000000000000000000000..b6f49102b489a3e2cb72d4dbb9ddb433c7111468 --- /dev/null +++ b/rce/scripts/setup_rce-04-00-01.csh @@ -0,0 +1,126 @@ +#!/bin/csh +setenv LD_LIBRARY_PATH +setenv PATH /usr/lib/qt-3.3/bin:/bin:/sbin:/usr/sbin/:/usr/local/bin:/usr/bin:/usr/bin/X11:/usr/sue/bin:/usr/X11R6/bin +setenv LINUXVERS SLC`cat /etc/redhat-release | sed -e 's#[0-9])##g' -e 's#[^\.0-9]##g' -e 's#\.[0-9]##'` +setenv TDAQ_VERSION 4 + +setenv ORBHOST '' +setenv ORBHOST `/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +#setenv ORBHOST `/sbin/ifconfig | grep "inet addr:192.168.1" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if ( $ORBHOST != '' ) then +setenv ORBendPoint giop:tcp:${ORBHOST}:0 +else +unsetenv ORBHOST +endif + + + +#override for now - x86_64 build is broken +set DBG_FLAG=opt +if ( "$1" == "debug" ) then +set DBG_FLAG=dbg +endif + +setenv HOST_ARCH i686-slc5-gcc43-${DBG_FLAG} +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-${DBG_FLAG} + +setenv RCE_ARCH ppc-rtems-rce405-opt +setenv RCE ${HOME}/daq/rce + + +#setup python +if ( -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ) then +setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH} +setenv PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin:${PATH} +else + echo Error: Python is not installed +endif + +if ( -e /daq/slc5/opt/rtems-4.9.2 ) then + setenv RTEMS /daq/slc5/opt/rtems-4.9.2 +else + echo Error: RTEMS is not installed +endif + +#setup rtems cross compilers +set RTEMS_GCC='' + +if ( -e /daq/slc5/opt/powerpc-rtems49-gcc432 ) then + set RTEMS_GCC=/daq/slc5/opt/powerpc-rtems49-gcc432 +else + echo "rtems gcc not found" +endif + +if ( $RTEMS_GCC != '' ) then +setenv LD_LIBRARY_PATH $RTEMS_GCC/lib:${LD_LIBRARY_PATH} +setenv PATH $RTEMS_GCC/bin:${PATH} +endif + +#setup ROOT +setenv ROOTSYS '' +if ( -e /daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/i686-slc5-gcc43-opt ) then + setenv ROOTSYS /daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/i686-slc5-gcc43-opt/root +# this needs the TDAQ gcc + if ( `uname -m` == 'x86_64') then + source /daq/slc5/sw/lcg/contrib/gcc/4.3.5/x86_64-slc5-gcc43-opt/setup.csh + setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH} + else + source /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.csh + setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34-opt/lib:${LD_LIBRARY_PATH} + endif +else + echo "TDAQ gcc not installed" +endif +if ( $ROOTSYS != '' ) then +setenv PATH $ROOTSYS/bin:${PATH} +setenv LD_LIBRARY_PATH $ROOTSYS/lib:${LD_LIBRARY_PATH} +endif + +#setup RCE client software +setenv PATH ${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts:${PATH} +setenv LD_LIBRARY_PATH ${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH}:${LD_LIBRARY_PATH} + +setenv RELEASE ${RCE} +setenv RCE_BIN ${RCE}/build/rcecalib/bin/${RCE_ARCH} +setenv RCE_MOD ${RCE}/build/rcecalib/mod/${RCE_ARCH} + +setenv XMD_INI ${RCE}/rcecalib/xmd.ini +setenv TDAQ_IPC_INIT_REF file:/${HOME}/ipc_root.ref +setenv SVNROOT svn+ssh://svn.cern.ch/reps/RceCimDev +setenv TDAQ_PARTITION rcetest_${USER} + +alias rce_ipc_server 'ipc_server -p $TDAQ_PARTITION' +alias rce_is_server 'is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls 'ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +alias rce_load 'echo "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r \!:1 -l $RCE_MOD/calibservermod.1.0.prod.so' +alias rce_killall 'pkill -u $USER ipc_server; pkill -u $USER is_server;' + +if ( ! -d ~/calibData ) then +mkdir ~/calibData +endif + +#tdaq setup +setenv TDAQ_INST_PATH /daq/slc5/tdaq/tdaq-04-00-01/installed +setenv TDAQC_INST_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-04/installed +setenv TDAQC_EXT_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-04/external +setenv TDAQ_BOOST /daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6 +setenv TDAQ_MYSQL /daq/slc5/sw/lcg/external/mysql/5.5.14 +setenv PATH $TDAQ_INST_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQ_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv LD_LIBRARY_PATH $TDAQ_BOOST/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQC_INST_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQC_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQC_EXT_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQC_EXT_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQ_INST_PATH/share/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQ_INST_PATH/share/lib:${LD_LIBRARY_PATH} +setenv PYTHONPATH $TDAQ_INST_PATH/$HOST_ARCH/lib:${PATH} +setenv ARCH $HOST_ARCH +rehash +setenv PIXLIBINTERFACE $RCE/../PixLibInterface +setenv USE_RCE yes +setenv RCE_CORE_VERSION 1.4 + + + + diff --git a/rce/scripts/setup_rce-04-00-01.sh b/rce/scripts/setup_rce-04-00-01.sh new file mode 100644 index 0000000000000000000000000000000000000000..75fa5e0fa0a19b61e86a883175db3f74d50ac05f --- /dev/null +++ b/rce/scripts/setup_rce-04-00-01.sh @@ -0,0 +1,114 @@ +#!/bin/bash +export LD_LIBRARY='' +export PATH=/usr/lib/qt-3.3/bin:/bin:/sbin:/usr/sbin/:/usr/local/bin:/usr/bin:/usr/bin/X11:/usr/sue/bin:/usr/X11R6/bin +export LINUXVERS=SLC`cat /etc/redhat-release | sed -e 's#[0-9])##g' -e 's#[^\.0-9]##g' -e 's#\.[0-9]##'` +if [ -n $LD_LIBRARY_PATH ] ; then + export LD_LIBRARY_PATH='' +fi + +export ORBHOST='' +export ORBHOST=`/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if [ -n $ORBHOST ] ; then + export ORBendPoint="giop:tcp:${ORBHOST}:0" +else + unset ORBHOST +fi + +export TDAQ_IPC_INIT_REF="file:${HOME}/ipc_root.ref" +export HOST_ARCH=i686-slc5-gcc43-opt +export TDAQ_HOST_ARCH=i686-slc5-gcc43-opt + +export RCE_ARCH=ppc-rtems-rce405-opt +export RCE=${HOME}/daq/rce +export ARCH=$HOST_ARCH + +#setup python +if [ -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ]; then +export LD_LIBRARY_PATH=/daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH} +export PATH=/daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin:${PATH} +else + echo Error: Python is not installed +fi + +if [ -e /daq/slc5/opt/rtems-4.9.2 ]; then + export RTEMS=/daq/slc5/opt/rtems-4.9.2 +else + echo Error: RTEMS is not installed +fi + +#setup rtems cross compilers +RTEMS_GCC='' +if [ -e /daq/slc5/opt/powerpc-rtems49-gcc432 ] ; then + RTEMS_GCC=/daq/slc5/opt/powerpc-rtems49-gcc432 +else + echo "rtems gcc not found"รง +fi +if [ -n $RTEMS_GCC ] ; then +export LD_LIBRARY_PATH=$RTEMS_GCC/lib:${LD_LIBRARY_PATH} +export PATH=$RTEMS_GCC/bin:${PATH} +fi + +#setup ROOT +export ROOTSYS="" +if [ -e /daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/${TDAQ_HOST_ARCH} ]; then + export ROOTSYS=/daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/${TDAQ_HOST_ARCH}/root + # this needs the TDAQ gcc + if [ `uname -m` = 'x86_64' ] ; then + . /daq/slc5/sw/lcg/contrib/gcc/4.3.5/x86_64-slc5-gcc43-opt/setup.sh + export LD_LIBRARY_PATH=/daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH} + else + . /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.sh + export LD_LIBRARY_PATH=/daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc43-opt/lib:${LD_LIBRARY_PATH} + fi +else + echo "TDAQ gcc not installed" +fi +if [ -n $ROOTSYS ] ; then + export PATH=$ROOTSYS/bin:${PATH} + export LD_LIBRARY_PATH=$ROOTSYS/lib:${LD_LIBRARY_PATH} +fi + +#setup RCE client software +export PATH=${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts:${PATH} +export LD_LIBRARY_PATH=${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH}:${LD_LIBRARY_PATH} + +export RELEASE=${RCE} +export RCE_BIN=${RCE}/build/rcecalib/bin/${RCE_ARCH} +export RCE_MOD=${RCE}/build/rcecalib/mod/${RCE_ARCH} + +export XMD_INI=${RCE}/rcecalib/xmd.ini +export TDAQ_IPC_INIT_REF=file:/${HOME}/ipc_root.ref +export SVNROOT=svn+ssh://svn.cern.ch/reps/RceCimDev +export TDAQ_PARTITION=rcetest_${USER} + +alias rce_ipc_server='ipc_server -p $TDAQ_PARTITION' +alias rce_is_server='is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls='ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +function rce_load () { echo -e "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r $1 -l $RCE_MOD/calibservermod.1.0.prod.so ; } +alias rce_killall='pkill -u $USER ipc_server; pkill -u $USER is_server;' +#fix HOSTTYPE on bash +export HOSTTYPE=`uname -m`-linux + + +if [ ! -d ~/calibData ] ; then +mkdir ~/calibData +fi +#tdaq setup +export TDAQ_INST_PATH=/daq/slc5/tdaq/tdaq-04-00-01/installed +export TDAQC_INST_PATH=/daq/slc5/tdaq-common/tdaq-common-01-18-04/installed +export TDAQC_EXT_PATH=/daq/slc5/tdaq-common/tdaq-common-01-18-04/external +export TDAQ_BOOST=/daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6 +export TDAQ_MYSQL=/daq/slc5/sw/lcg/external/mysql/5.5.14/ +export PATH=$TDAQ_INST_PATH/$HOST_ARCH/bin:${PATH} +export LD_LIBRARY_PATH=$TDAQ_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +export PATH=$TDAQC_INST_PATH/$HOST_ARCH/bin:${PATH} +export LD_LIBRARY_PATH=$TDAQC_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +export PATH=$TDAQC_EXT_PATH/$HOST_ARCH/bin:${PATH} +export LD_LIBRARY_PATH=$TDAQC_EXT_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +export PATH=$TDAQ_INST_PATH/share/bin:${PATH} +export LD_LIBRARY_PATH=$TDAQ_INST_PATH/share/lib:${LD_LIBRARY_PATH} +export PYTHONPATH=$TDAQ_INST_PATH/$HOST_ARCH/lib +export PIXLIBINTERFACE=${RCE}/../PixLibInterface +export USE_RCE=yes +export TDAQ_VERSION=4 +export RCE_CORE_VERSION=1.4 diff --git a/rce/scripts/setup_rce-04-00-01_rceG1.csh b/rce/scripts/setup_rce-04-00-01_rceG1.csh new file mode 100644 index 0000000000000000000000000000000000000000..81ca19f33953df5535eb4bb424f6b5f89e5101a1 --- /dev/null +++ b/rce/scripts/setup_rce-04-00-01_rceG1.csh @@ -0,0 +1,131 @@ +setenv RCE ${HOME}/daq/rce +setenv RCE_ARCH ppc-rtems-rceG1-opt +# clear path +setenv PATH /usr/lib/qt-3.3/bin:/bin:/sbin:/usr/sbin/:/usr/local/bin:/usr/bin:/usr/bin/X11:/usr/X11R6/bin +setenv LINUXVERS SLC`cat /etc/redhat-release | sed -e 's#[0-9])##g' -e 's#[^\.0-9]##g' -e 's#\.[0-9]##'` +setenv LD_LIBRARY_PATH + +setenv TDAQ_VERSION 4 + +setenv ORBHOST '' +setenv ORBHOST `/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if ( $ORBHOST != '' ) then +setenv ORBendPoint giop:tcp:${ORBHOST}:0 +else +unsetenv ORBHOST +endif + +setenv TDAQ_IPC_INIT_REF file:${HOME}/ipc_root.ref +if ( `uname -m` == 'x86_64' ) then +setenv HOST_ARCH x86_64-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH x86_64-slc5-gcc43-opt +endif +if (`uname -m` == 'i386' ) then +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt +endif + +#override for now - x86_64 build is broken +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt + + +#setup python +if ( -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ) then +setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib: ${LD_LIBRARY_PATH} +setenv PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin:${PATH} +else + echo Error: Python is not installed + exit 1 +endif + +if ( -e /daq/slc5/opt/rtems-4.10.2 ) then + setenv RTEMS /daq/slc5/opt/rtems/4.10.2 + setenv RTEMS_ROOT ${RTEMS} +else + echo Error: RTEMS is not installed +endif + +#setup rtems cross compilers +set RTEMS_GCC='' + +if ( -e /daq/slc5/opt/powerpc-rtems410-gcc445 ) then + set RTEMS_GCC=/daq/slc5/opt/powerpc-rtems410-gcc445 +else + echo "rtems gcc not found" + exit 1 +endif + +if ( $RTEMS_GCC != '' ) then +setenv PATH $RTEMS_GCC/bin:${PATH} +endif + +#setup ROOT +setenv ROOTSYS '' +if ( -e /daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/$TDAQ_HOST_ARCH ) then + setenv ROOTSYS /daq/slc5/sw/lcg/app/releases/ROOT/5.30.05/$TDAQ_HOST_ARCH/root +# this needs the TDAQ gcc + if ( `uname -m` == 'x86_64') then + source /daq/slc5/sw/lcg/contrib/gcc/4.3.5/x86_64-slc5-gcc43-opt/setup.csh + setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc43-opt/lib:${LD_LIBRARY_PATH} + else + source /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.csh + setenv LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34-opt/lib:${LD_LIBRARY_PATH} + endif +else + echo "TDAQ gcc not installed" + exit 1 +endif +if ( $ROOTSYS != '' ) then +setenv PATH $ROOTSYS/bin:${PATH} +setenv LD_LIBRARY_PATH $ROOTSYS/lib:${LD_LIBRARY_PATH} +endif + +#setup RCE client software +setenv PATH ${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts:${PATH} +setenv LD_LIBRARY_PATH ${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH}:${LD_LIBRARY_PATH} + +setenv RELEASE ${RCE} +setenv RCE_BIN ${RCE}/build/rcecalib/bin/${RCE_ARCH} +setenv RCE_MOD ${RCE}/build/rcecalib/mod/${RCE_ARCH} + +setenv XMD_INI ${RCE}/rcecalib/xmd.ini +setenv TDAQ_IPC_INIT_REF file:/${HOME}/ipc_root.ref +setenv SVNROOT svn+ssh://svn.cern.ch/reps/RceCimDev +setenv TDAQ_PARTITION rcetest_${USER} + +alias rce_ipc_server 'ipc_server -p $TDAQ_PARTITION' +alias rce_is_server 'is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls 'ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +alias rce_load 'echo "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r \!:1 -l $RCE_MOD/calibservermod.2.2.prod.so' +alias rce_killall 'pkill -u $USER ipc_server; pkill -u $USER is_server;' + +if ( ! -d ~/calibData ) then +mkdir ~/calibData +endif + +#tdaq setup +setenv TDAQ_INST_PATH /daq/slc5/tdaq/tdaq-04-00-01/installed +setenv TDAQC_INST_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-04/installed +setenv TDAQC_EXT_PATH /daq/slc5/tdaq-common/tdaq-common-01-18-04/external +setenv TDAQ_BOOST /daq/slc5/sw/lcg/external/Boost/1.44.0_python2.6 +setenv TDAQ_MYSQL /daq/slc5/sw/lcg/external/mysql/5.5.14 +setenv PATH $TDAQ_INST_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQ_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv LD_LIBRARY_PATH $TDAQ_BOOST/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQC_INST_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQC_INST_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQC_EXT_PATH/$HOST_ARCH/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQC_EXT_PATH/$HOST_ARCH/lib:${LD_LIBRARY_PATH} +setenv PATH $TDAQ_INST_PATH/share/bin:${PATH} +setenv LD_LIBRARY_PATH $TDAQ_INST_PATH/share/lib:${LD_LIBRARY_PATH} +setenv PYTHONPATH $TDAQ_INST_PATH/$HOST_ARCH/lib:${PATH} +setenv ARCH $HOST_ARCH +rehash +setenv PIXLIBINTERFACE $RCE/../PixLibInterface +setenv USE_RCE yes +setenv RCE_CORE_VERSION 2.2 + + + + diff --git a/rce/scripts/setup_rce.csh b/rce/scripts/setup_rce.csh new file mode 100644 index 0000000000000000000000000000000000000000..a705439a269e00829cd478a723961474f86116f1 --- /dev/null +++ b/rce/scripts/setup_rce.csh @@ -0,0 +1,147 @@ +#--> These aliases are used to manipulate environmental variables used to hold +#--> directory paths, e.g. PATH, MANPATH. They allow one to append, prepend +#--> or remove specific directories from such variables. +alias addpath_clean 'delpath \!:*; setenv \!:1 ${\!:1}\:\!:2' +alias addpath2_clean 'delpath \!:*; setenv \!:1 \!:2\:${\!:1}' +# add to end of path +alias addpath 'if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* && $\!:1 !~ *\:\!:2\:* && $\!:1 !~ *\:\!:2 ) setenv \!:1 ${\!:1}\:\!:2' +# add to front of path +alias addpath2 'if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* && $\!:1 !~ *\:\!:2\:* && $\!:1 !~ *\:\!:2 ) setenv \!:1 \!:2\:${\!:1}; if ( $\!:1 != \!:2 && $\!:1 !~ \!:2\:* ) setenv \!:1 \!:2\:`echo ${\!:1} | sed -e s%^\!:2\:%% -e s%:\!:2\:%:%g -e s%:\!:2\$%%`' +alias delpath 'setenv \!:1 `echo ${\!:1} | sed -e s%^\!:2\$%% -e s%^\!:2\:%% -e s%:\!:2\:%:%g -e s%:\!:2\$%%`' +alias modpath 'setenv \!:1 `echo ${\!:1} | sed -e s%^\!:2\$%\!:3% -e s%^\!:2\:%\!:3\:% -e s%:\!:2\:\%:\!:3\:\%g -e s%:\!:2\$%\:\!:3\%`' + +if ( ! -d /home/$USER ) then +exit 0 +endif +setenv PATH /usr/lib/qt-3.3/bin:/bin:/sbin:/usr/sbin/:/usr/local/bin:/usr/bin:/usr/bin/X11:/usr/sue/bin:/usr/X11R6/bin + +setenv LD_LIBRARY_PATH +setenv TDAQ_VERSION 3 + +setenv ORBHOST '' +setenv ORBHOST `/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if ( $ORBHOST != '' ) then +setenv ORBendPoint giop:tcp:${ORBHOST}:0 +else +unsetenv ORBHOST +endif + +setenv TDAQ_IPC_INIT_REF file:${HOME}/ipc_root.ref +if ( `uname -m` == 'x86_64' ) then +setenv HOST_ARCH x86_64-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH x86_64-slc5-gcc43-opt +endif +if (`uname -m` == 'i386' ) then +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt +endif + +#override for now - x86_64 build is broken +setenv HOST_ARCH i686-slc5-gcc43-opt +setenv TDAQ_HOST_ARCH i686-slc5-gcc43-opt + +setenv RCE_ARCH ppc-rtems-rce405-opt +setenv RCE ${HOME}/daq/rce + +#ambush setup +if ( -e /reg/g/atlas/ambush ) then +setenv AMBUSH /reg/g/atlas/ambush +addpath2 LD_LIBRARY_PATH ${AMBUSH}/lib +addpath2 PATH ${AMBUSH}/bin +endif + +#setup python +if ( -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ) then +addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib +addpath2 PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin +else + echo Error: Python is not installed + exit 1 +endif + +if ( -e /daq/slc5/opt/rtems-4.9.2 ) then + setenv RTEMS /daq/slc5/opt/rtems-4.9.2 +else + echo Error: RTEMS is not installed +endif + +#setup rtems cross compilers +set RTEMS_GCC='' + +if ( -e /daq/slc5/opt/powerpc-rtems49-gcc432 ) then + set RTEMS_GCC=/daq/slc5/opt/powerpc-rtems49-gcc432 +else + echo "rtems gcc not found" + exit 1 +endif + +if ( $RTEMS_GCC != '' ) then +addpath2 LD_LIBRARY_PATH $RTEMS_GCC/lib +addpath2 PATH $RTEMS_GCC/bin +endif + +#setup ROOT +setenv ROOTSYS '' +if ( -e /daq/slc5/sw/lcg/app/releases/ROOT/5.26.00d_python2.6/$TDAQ_HOST_ARCH ) then + setenv ROOTSYS /daq/slc5/sw/lcg/app/releases/ROOT/5.26.00d_python2.6/$TDAQ_HOST_ARCH/root +# this needs the TDAQ gcc + if ( `uname -m` == 'x86_64') then + source /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc34-opt/setup.csh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc34-opt/lib + else + source /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.csh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34-opt/lib + endif +else + echo "TDAQ gcc not installed" + exit 1 +endif +if ( $ROOTSYS != '' ) then +addpath2 PATH $ROOTSYS/bin +addpath2 LD_LIBRARY_PATH $ROOTSYS/lib +endif + +#setup RCE client software +addpath2 PATH ${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts +addpath2 LD_LIBRARY_PATH ${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH} + +setenv RELEASE ${RCE} +setenv RCE_BIN ${RCE}/build/rcecalib/bin/${RCE_ARCH} +setenv RCE_MOD ${RCE}/build/rcecalib/mod/${RCE_ARCH} + +setenv XMD_INI ${RCE}/rcecalib/xmd.ini +setenv TDAQ_IPC_INIT_REF file:/${HOME}/ipc_root.ref +setenv SVNROOT svn+ssh://svn.cern.ch/reps/RceCimDev +setenv TDAQ_PARTITION rcetest_${USER} + +alias rce_ipc_server 'ipc_server -p $TDAQ_PARTITION' +alias rce_is_server 'is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls 'ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +alias rce_load 'echo "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r \!:1 -l $RCE_MOD/calibservermod.1.0.prod.so' +alias rce_killall 'pkill -u $USER ipc_server; pkill -u $USER is_server;' + +if ( ! -d ~/calibData ) then +mkdir ~/calibData +endif + +#tdaq setup +setenv TDAQ_INST_PATH /daq/slc5/tdaq/tdaq-03-00-01/installed +setenv TDAQC_INST_PATH /daq/slc5/tdaq-common/tdaq-common-01-16-02/installed +setenv TDAQC_EXT_PATH /daq/slc5/tdaq-common/tdaq-common-01-16-02/external +setenv TDAQ_BOOST /daq/slc5/sw/lcg/external/Boost/1.42.0_python2.6 +addpath2 PATH $TDAQ_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_EXT_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_EXT_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQ_INST_PATH/share/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/share/lib +setenv PYTHONPATH $TDAQ_INST_PATH/$HOST_ARCH/lib +setenv ARCH $HOST_ARCH +setenv PIXLIBINTERFACE $RCE/../PixLibInterface +rehash + + + + diff --git a/rce/scripts/setup_rce.sh b/rce/scripts/setup_rce.sh new file mode 100644 index 0000000000000000000000000000000000000000..f25d9ef34ff3b870b84ee75cc8c16ea4655daac4 --- /dev/null +++ b/rce/scripts/setup_rce.sh @@ -0,0 +1,183 @@ +#!/bin/bash -xv + +#--> These aliases are used to manipulate environmental variables used to hold +#--> directory paths, e.g. PATH, MANPATH. They allow one to append, prepend +#--> or remove specific directories from such variables. + +if [ -n "${BASH_VERSION:-""}" ]; then + + addpath_clean() + { + delpath $* + eval "$1=\$$1:$2" + } + + addpath2_clean() + { + delpath $* + eval "$1=$2:\$$1" + } + + # add to end of path + addpath() + { + if eval test -z \${$1}; then + eval "$1=$2" + elif ! eval test -z \"\${$1##$2}\" -o -z \"\${$1##*:$2:*}\" -o -z \"\${$1%%*:$2}\" -o -z \"\${$1##$2:*}\" ; then + eval "$1=\$$1:$2" + fi + } + + # add to front of path + addpath2() + { + if eval test -z \${$1}; then + eval "$1=$2" + elif ! eval test -z \"\${$1##$2}\" -o -z \"\${$1##*:$2:*}\" -o -z \"\${$1%%*:$2}\" -o -z \"\${$1##$2:*}\" ; then + eval "$1=$2:\$$1" + fi + } + + # delete from path + delpath() + { + eval "$1=\$(echo \$$1 | sed -e s%^$2\$%% -e s%^$2\:%% -e s%:$2\:%:%g -e s%:$2\\\$%%)" + } + + modpath() + { + eval "$1=\$(echo \$$1 | sed -e s%^$2\$%$3% -e s%^$2\:%$3\:% -e s%:$2\:%:$3\:%g -e s%:$2\\\$%:$3%)" + } +fi + +if [ ! -d /home/$USER ] ; then + exit 0 +fi + + + +if [ -n $LD_LIBRARY_PATH ] ; then + export LD_LIBRARY_PATH='' +fi + +export ORBHOST='' +export ORBHOST=`/sbin/ifconfig | grep "inet addr:1[79]2" | head -1 | gawk -F: '{print $2}' | awk '{print $1}'` +if [ -n $ORBHOST ] ; then + export ORBendPoint="giop:tcp:${ORBHOST}:0" +else + unset ORBHOST +fi + +export TDAQ_IPC_INIT_REF="file:${HOME}/ipc_root.ref" +if [ `uname -m` = 'x86_64' ] ; then + export HOST_ARCH=x86_64-slc5-gcc43-opt + export TDAQ_HOST_ARCH=x86_64-slc5-gcc43-opt +fi +if [ `uname -m` = 'i386' ] ; then + export HOST_ARCH=i386-linux + export TDAQ_HOST_ARCH=i686-slc5-gcc43-opt +fi + +#override for now - x86_64 build is broken +export HOST_ARCH=i686-slc5-gcc43-opt +export TDAQ_HOST_ARCH=i686-slc5-gcc43-opt + +export RCE_ARCH=ppc-rtems-rce405-opt +export RCE=${HOME}/rce + +#ambush setup +if [ -e /reg/g/atlas/ambush ] ; then + export AMBUSH=/reg/g/atlas/ambush + addpath2 LD_LIBRARY_PATH ${AMBUSH}/lib + addpath2 PATH ${AMBUSH}/bin +fi + +#setup python +if [ -e /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt ]; then +addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/lib +addpath2 PATH /daq/slc5/sw/lcg/external/Python/2.6.5/i686-slc5-gcc43-opt/bin +else + echo Error: Python is not installed + exit 1 +fi + +if [ -e /daq/slc5/opt/rtems-4.9.2 ]; then + export RTEMS=/daq/slc5/opt/rtems-4.9.2 +else + echo Error: RTEMS is not installed +fi + +#setup rtems cross compilers +RTEMS_GCC='' +if [ -e /daq/slc5/opt/powerpc-rtems49-gcc432 ] ; then + RTEMS_GCC=/daq/slc5/opt/powerpc-rtems49-gcc432 +else + echo "rtems gcc not found" + exit 1 +fi +if [ -n $RTEMS_GCC ] ; then +addpath2 LD_LIBRARY_PATH $RTEMS_GCC/lib +addpath2 PATH $RTEMS_GCC/bin +fi + +#setup ROOT +export ROOTSYS="" +if [ -e /daq/slc5/sw/lcg/app/releases/ROOT/5.26.00d_python2.6/${TDAQ_HOST_ARCH} ]; then + export ROOTSYS=/daq/slc5/sw/lcg/app/releases/ROOT/5.26.00d_python2.6/${TDAQ_HOST_ARCH}/root + # this needs the TDAQ gcc + if [ `uname -m` = 'x86_64' ] ; then + . /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc34-opt/setup.sh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/x86_64-slc5-gcc34-opt/lib + else + . /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34/setup.sh + addpath2 LD_LIBRARY_PATH /daq/slc5/sw/lcg/contrib/gcc/4.3/slc4_ia32_gcc34-opt/lib + fi +else + echo "TDAQ gcc not installed" + exit 1 +fi +if [ -n $ROOTSYS ] ; then + addpath2 PATH $ROOTSYS/bin + addpath2 LD_LIBRARY_PATH $ROOTSYS/lib +fi + +#setup RCE client software +addpath2 PATH ${RCE}/build/rceis/bin/${HOST_ARCH}:${RCE}/build/rceipc/bin/${HOST_ARCH}:${RCE}/build/rcecalib/bin/${HOST_ARCH}:${RCE}/rcecalib/scripts +addpath2 LD_LIBRARY_PATH ${RCE}/build/rcecalib/lib/${HOST_ARCH}:${RCE}/build/rceers/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceipc/lib/${HOST_ARCH}:${RCE}/build/rceowl/lib/${HOST_ARCH}:${RCE}/build/rceoh/lib/${HOST_ARCH}:${RCE}/build/rceis/lib/${HOST_ARCH} + +export RELEASE=${RCE} +export RCE_BIN=${RCE}/build/rcecalib/bin/${RCE_ARCH} +export RCE_MOD=${RCE}/build/rcecalib/mod/${RCE_ARCH} + +export XMD_INI=${RCE}/rcecalib/xmd.ini +export TDAQ_IPC_INIT_REF=file:/${HOME}/ipc_root.ref +export SVNROOT=svn+ssh://svn.cern.ch/reps/RceCimDev +export TDAQ_PARTITION=rcetest_${USER} + +alias rce_ipc_server='ipc_server -p $TDAQ_PARTITION' +alias rce_is_server='is_server -p $TDAQ_PARTITION -n RceIsServer' +alias rce_ipc_ls='ipc_ls ; ipc_ls -p $TDAQ_PARTITION' +function rce_load () { echo -e "reboot\nsetenv TDAQ_PARTITION $TDAQ_PARTITION\nsetenv TDAQ_IS_COMPRESSION_THRESHOLD 100000000\n" | host_bootloader -r $1 -l $RCE_MOD/calibservermod.1.0.prod.so ; } +alias rce_killall='pkill -u $USER ipc_server; pkill -u $USER is_server;' +#fix HOSTTYPE on bash +export HOSTTYPE=`uname -m`-linux + + +if [ ! -d ~/calibData ] ; then +mkdir ~/calibData +fi +#tdaq setup +export TDAQ_INST_PATH=/daq/slc5/tdaq/tdaq-03-00-01/installed +export TDAQC_INST_PATH=/daq/slc5/tdaq-common/tdaq-common-01-16-02/installed +export TDAQC_EXT_PATH=/daq/slc5/tdaq-common/tdaq-common-01-16-02/external +export TDAQ_BOOST=/daq/slc5/sw/lcg/external/Boost/1.42.0_python2.6 +addpath2 PATH $TDAQ_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_INST_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_INST_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQC_EXT_PATH/$HOST_ARCH/bin +addpath2 LD_LIBRARY_PATH $TDAQC_EXT_PATH/$HOST_ARCH/lib +addpath2 PATH $TDAQ_INST_PATH/share/bin +addpath2 LD_LIBRARY_PATH $TDAQ_INST_PATH/share/lib +export PYTHONPATH=$TDAQ_INST_PATH/$HOST_ARCH/lib +