Commit 44ae6796 authored by Dejan Priversek's avatar Dejan Priversek
Browse files

Initial commit

parents
2019-03-14
; Initial Release
\ No newline at end of file
This diff is collapsed.
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
This diff is collapsed.
# ScopeFun FPGA firmware sources
This is the [Xilinx Artix-7 FPGA](https://www.xilinx.com/products/silicon-devices/fpga/artix-7.html) firmware source code for ScopeFun.
## Getting started
For comiling the FPGA firmware you must install the [ISE WebPACK Design Software](https://www.xilinx.com/products/design-tools/ise-design-suite/ise-webpack.html) from Xilinx.
After completing Vivado installation run the "gen_project.tcl" script from Vivado (Tools -> Run Tcl Script). This will create a new project and link ScopeFun sources from "srcs" folder.
## Licensing
ScopeFun FGPA firmware sources are licensed under GNU General Public License v3 (GPLv3). For details please see the COPYING file(s) and file headers.
\ No newline at end of file
###############################################################################
# Copyright (C) 2019 Dejan Priversek
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
###############################################################################
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property CFGBVS GND [current_design]
set_property CONFIG_MODE S_SERIAL [current_design]
set_property BITSTREAM.CONFIG.PERSIST NO [current_design]
set_property BITSTREAM.STARTUP.STARTUPCLK CCLK [current_design]
This diff is collapsed.
###############################################################################
# Copyright (C) 2016 Dejan Priversek
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
###############################################################################
#adc clock is 250 Mhz, waveform is inverted (p/n clock pins are swapped on pcb)
create_clock -period 4.000 -name clk_adc_p -waveform {2.000 4.000} [get_ports clk_adc_p]
set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_nets clk_adc_p]
# jitter value specified as nanoseconds
set_input_jitter clk_adc_p 0.012
#ADC interface data fifo
#set_protperty IODELAY_GROUP IODELAY_ADC_IF [get_cells ADC_interface/*]
#disable CDC registers timing check
#set_max_delay -datapath_only -from [get_cells ADC_interface/data_fifo_16x20b/enb_reg*] -to [get_cells ADC_interface/data_fifo_16x20b/enb_d_reg*] 2.000
#set_max_delay -datapath_only -from [get_cells ADC_interface/data_fifo_16x20b/*/RAMC_D1] -to [get_cells {ADC_interface/data_fifo_16x20b/do_reg[*]}] 1.500
#calib_done to ADC interface fifo enable
set_max_delay -datapath_only -from [get_pins calib_done_reg/C] -to [get_pins ADC_interface/data_fifo_16x20b/we_d_reg/D] 2.000
#calib_start to ADC interface calib start
set_max_delay -datapath_only -from [get_pins read_calib_start_reg/C] -to [get_pins ADC_interface/read_calib_start_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins read_calib_source_reg/C] -to [get_pins ADC_interface/read_calib_source_reg/D] 2.000
#global reset to DDR3 sample write buffer reset
#set_false_path -from [get_pins gl_reset_reg/C] -to [get_pins RAM_DDR3_inst/write_buff/reset_reg/D]
#set_false_path -from [get_pins gl_reset_reg/C] -to [get_pins RAM_DDR3_inst/write_buff/rst_d_reg/D]
#set_false_path -from [get_pins gl_reset_reg/C] -to [get_pins RAM_DDR3_inst/ram/ui_reset_d_reg/D]
#set_false_path -from [get_pins gl_reset_reg/C] -to [get_pins RAM_DDR3_inst/read_buff/rst_d_reg/D]
set_false_path -from [get_pins clearflags*/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/reset_reg/D]
set_false_path -from [get_pins clearflags*/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/rst_d_reg/D]
#set_false_path -from [get_pins clearflags_d/C] -to [get_pins RAM_DDR3_inst/ram/ui_reset_d_reg/D]
#set_false_path -from [get_pins clearflags_d/C] -to [get_pins RAM_DDR3_inst/RAM_READ_FIFO/rst_d_reg/D]
#ignore timing error for distributed RAM (reads are performed after writes)
set_max_delay -datapath_only -from [get_pins config_RAM/RAM_reg_0_63_*/DP/CLK] -to [get_pins {config_RAM/do2_reg[*]/D}] 2.000
#clk_adc / clk_fx3 to AWG clk
#AWG signal output to core (for trigger)
set_max_delay -datapath_only -from [get_pins {signal_generator_inst/genSignal_1_reg[*]/C}] -to [get_pins {genSignal_1_d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {signal_generator_inst/genSignal_2_reg[*]/C}] -to [get_pins {genSignal_2_d_reg[*]/D}] 2.000
#AWG enable signal
set_false_path -from [get_pins sig_out_enable_d_reg/C] -to [get_pins signal_generator_inst/generator1On_d_reg/D]
set_false_path -from [get_pins sig_out_enable_d_reg/C] -to [get_pins signal_generator_inst/generator2On_d_reg/D]
set_false_path -from [get_pins generator1On_reg/C] -to [get_pins signal_generator_inst/generator1On_d_reg/D]
set_false_path -from [get_pins generator2On_reg/C] -to [get_pins signal_generator_inst/generator2On_d_reg/D]
#AWG inputs
set_max_delay -datapath_only -from [get_pins {generator1Delta_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorDelta_1_i_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator2Delta_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorDelta_2_i_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator1Duty_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorDuty_1d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator2Duty_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorDuty_2d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator1Offset_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorOffset_1d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator2Offset_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorOffset_2d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator1Type_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorType_1d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator2Type_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorType_2d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator1Voltage_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorVoltage_1d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {generator2Voltage_reg[*]/C}] -to [get_pins {signal_generator_inst/generatorVoltage_2d_reg[*]/D}] 2.000
#clk_adc to clk_fx3 CDC
set_max_delay -datapath_only -from [get_cells {timebase_d_reg[*]}] -to [get_cells {timebase_dd_reg[*]}] 2.000
set_max_delay -datapath_only -from [get_pins triggered_reg/C] -to [get_pins triggered_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins {framesize_d_reg[*]/C}] -to [get_pins {framesize_dd_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins getnewframe_reg/C] -to [get_pins getnewframe_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins {RAM_DDR3_inst/PreTrigSavingCnt_reg[*]/C}] -to [get_pins {RAM_DDR3_inst/PreTrigSavingCnt_d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins clearflags*/C] -to [get_pins RAM_DDR3_inst/rst_d_reg/D] 2.000
#clk_fx3 to clk_adc CDC
set_max_delay -datapath_only -from [get_cells {an_trig_delay_reg[*]}] -to [get_cells {an_trig_delay_d_reg[*]}] 2.000
set_max_delay -datapath_only -from [get_pins clearflags_reg/C] -to [get_pins clearflags_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins sig_out_enable_reg/C] -to [get_pins sig_out_enable_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins requestFrame_reg/C] -to [get_pins requestFrame_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins RAM_DDR3_inst/PreTrigSavingCntRecvd_reg/C] -to [get_pins RAM_DDR3_inst/PreTrigSavingCntRecvd_d_reg/D] 2.000
set_max_delay -datapath_only -from [get_pins {RAM_DDR3_inst/PreTrigSavingCnt_reg[*]/C}] -to [get_pins {RAM_DDR3_inst/PreTrigSavingCnt_d_reg[*]/D}] 2.000
set_max_delay -datapath_only -from [get_pins {pre_trigger_d_reg[*]/C}] -to [get_pins {RAM_DDR3_inst/RAM/wr_pretriglen_reg[*]/D}] 2.000
#DDR3 controller
# write FIFO reset
# clk_adc -> clk_fx3
set_max_delay -datapath_only -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst1/bl.fifo_36_inst_bl_1.fifo_36_bl_1/WRCLK] -to [get_pins RAM_DDR3_inst/fwr_AlmostFull_d_reg/D] 2.000
set_false_path -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/rst_i_reg/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst1/bl.fifo_36_inst_bl_1.fifo_36_bl_1/RST]
set_false_path -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/rst_i_reg/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst2/bl.fifo_36_inst_bl_1.fifo_36_bl_1/RST]
set_false_path -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/reset_reg/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst1/bl.fifo_36_inst_bl_1.fifo_36_bl_1/RDEN]
set_false_path -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/reset_reg/C] -to [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst2/bl.fifo_36_inst_bl_1.fifo_36_bl_1/RDEN]
# signals start moving samples from WRITE FIFO into DDR3 RAM
set_max_delay -from [get_pins RAM_DDR3_inst/RAM_WRITE_FIFO/FIFO_DUALCLOCK_MACRO_inst1/bl.fifo_36_inst_bl_1.fifo_36_bl_1/WRCLK] -to [get_pins RAM_DDR3_inst/fwr_AlmostFull_d_reg/D] 2.000
# ADC clock interface is a Source-synchronous DDR interface (min/max times taken from KAD5510P data-sheet)
# clk-to-data delay wrt rising edge : min -260 ps, max 120 ps
# clk-to-data delay wrt falling edge: min -160 ps, max 230 ps
# note: clock is taken from CH1 ADC and clock pins are swapped on pcb
# there is a 180 degree phase shift between ADC1 and ADC2 sampling clock
set_input_delay -clock [get_clocks clk_adc_p] -clock_fall -min -add_delay -0.260 [get_ports {dataA_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -clock_fall -max -add_delay 0.120 [get_ports {dataA_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -min -add_delay -0.160 [get_ports {dataA_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -max -add_delay 0.230 [get_ports {dataA_p[*]}]
# above contraints for dataA inputs are for static timing analasys only
# dynamic calibration is used to find the center of a data eye
# so we can disable timing analysis for dataA inputs with the following line
set_false_path -from [get_ports {dataA_p[*]}] -to [get_pins {ADC_interface/data_ddr_to_se[*].data1_ddr_to_se/D}]
# report_timing -from [get_ports {dataA_p[*]}] -to [get_pins {ADC_interface/data_ddr_to_se[*].data1_ddr_to_se/D}] -delay_type min_max -max_paths 10 -sort_by group -input_pins -routable_nets -name timing_1
# use static timing analysis for dataB ports (we use fixed IDELAY value for dataB inputs)
set_input_delay -clock [get_clocks clk_adc_p] -clock_fall -min -add_delay 1.840 [get_ports {dataB_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -clock_fall -max -add_delay 2.230 [get_ports {dataB_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -min -add_delay 1.740 [get_ports {dataB_p[*]}]
set_input_delay -clock [get_clocks clk_adc_p] -max -add_delay 2.120 [get_ports {dataB_p[*]}]
set_false_path -from [get_ports {dataB_p[*]}] -to [get_pins {ADC_interface/data_ddr_to_se[*].data2_ddr_to_se/D}]
#set_input_delay -clock [get_clocks clk_fx3] -add_delay 1.100 [get_ports {fdata[*]}]
#set_input_delay -clock [get_clocks clk_adc_dclk] -add_delay 1.100 [get_ports {dataB[*]}]
#report out skew of dac_data vs dac_clk
create_generated_clock -name dac_clk_1 -source [get_pins dac_interface/ODDR_CLK/C] -divide_by 1 [get_ports dac_clk_1]
set_output_delay -clock [get_clocks dac_clk_1] -clock_fall -min -add_delay -0.500 [get_ports {dac_data[*]}]
set_output_delay -clock [get_clocks dac_clk_1] -clock_fall -max -add_delay 0.500 [get_ports {dac_data[*]}]
set_output_delay -clock [get_clocks dac_clk_1] -min -add_delay -0.500 [get_ports {dac_data[*]}]
set_output_delay -clock [get_clocks dac_clk_1] -max -add_delay 0.500 [get_ports {dac_data[*]}]
#ignore timing for async signals
set_max_delay -datapath_only -from [get_pins {DebugADCState_reg[*]/C}] -to [get_pins {DebugADCState_d_reg[*]/D}] 4.000
----------------------------------------------------------------------------------
-- Copyright (C) 2019 Dejan Priversek
--
-- 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 3 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, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity LA_core is
generic (
LA_DATA_WIDTH : integer := 12; -- Data input width
LA_COUNTER_WIDTH : integer := 16 -- Stage Counter width
);
Port ( clk_in : in std_logic;
dt_enable : in std_logic;
dataD : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_mask_0 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_mask_1 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_mask_2 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_mask_3 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternA_0 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternA_1 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternA_2 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternA_3 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternB_0 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternB_1 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternB_2 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
digital_trig_patternB_3 : in std_logic_vector (LA_DATA_WIDTH-1 downto 0);
dt_stage_capture : in std_logic_vector (1 downto 0);
dt_delayMaxcnt_0 : in std_logic_vector (LA_COUNTER_WIDTH-1 downto 0);
dt_delayMaxcnt_1 : in std_logic_vector (LA_COUNTER_WIDTH-1 downto 0);
dt_delayMaxcnt_2 : in std_logic_vector (LA_COUNTER_WIDTH-1 downto 0);
dt_delayMaxcnt_3 : in std_logic_vector (LA_COUNTER_WIDTH-1 downto 0);
dtSerial : in std_logic;
dtSerialCh : in std_logic_vector (3 downto 0);
dt_triggered : out std_logic;
reset : in std_logic);
end LA_core;
architecture Behavioral of LA_core is
-- Logic analyzer state machine signals
signal LAstate : std_logic_vector (2 downto 0);
CONSTANT A: STD_LOGIC_VECTOR (2 DownTo 0) := "000";
CONSTANT B: STD_LOGIC_VECTOR (2 DownTo 0) := "001";
CONSTANT C: STD_LOGIC_VECTOR (2 DownTo 0) := "010";
CONSTANT D: STD_LOGIC_VECTOR (2 DownTo 0) := "011";
CONSTANT E: STD_LOGIC_VECTOR (2 DownTo 0) := "100";
CONSTANT F: STD_LOGIC_VECTOR (2 DownTo 0) := "101";
-- logic analyzer data input
signal dataDd : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
signal dataDdd : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
signal dataDddd : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
signal dataDTrigSignal : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
signal dataDTrigSignal_d : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
signal dataDTrigSignal_dd : std_logic_vector (LA_DATA_WIDTH-1 downto 0);
-- logic analyzer core signals
signal dt_enable_d : std_logic;
type trig_patternA_mem_d is array(0 to 3) of STD_LOGIC_VECTOR (LA_DATA_WIDTH-1 downto 0);
signal digital_trig_patternA_d : trig_patternA_mem_d:=((others=> (others=>'0')));
type trig_patternB_mem_d is array(0 to 3) of STD_LOGIC_VECTOR (LA_DATA_WIDTH-1 downto 0);
signal digital_trig_patternB_d : trig_patternB_mem_d:=((others=> (others=>'0')));
type digital_trig_mask_mem_d is array(0 to 3) of STD_LOGIC_VECTOR (LA_DATA_WIDTH-1 downto 0);
signal digital_trig_mask_d : digital_trig_mask_mem_d:=((others=> (others=>'0')));
type digital_trig_mask_mem_c is array(0 to 3) of STD_LOGIC_VECTOR (LA_DATA_WIDTH-1 downto 0);
signal digital_trig_mask_c : digital_trig_mask_mem_c:=((others=> (others=>'0')));
signal dt_stage : integer range 0 to 3 := 0;
signal dt_stage_capture_d : integer range 0 to 3;
signal dt_delaycnt : unsigned (LA_COUNTER_WIDTH-1 downto 0);
type dt_delayMaxcnt_mem is array(0 to 3) of unsigned (LA_COUNTER_WIDTH-1 downto 0);
signal dt_delayMaxcnt : dt_delayMaxcnt_mem :=((others=> (others=>'0')));
type dt_delayMaxcnt_d_mem is array(0 to 3) of unsigned (LA_COUNTER_WIDTH-1 downto 0);
signal dt_delayMaxcnt_d : dt_delayMaxcnt_d_mem :=((others=> (others=>'0')));
signal dtSerial_d : std_logic;
signal dtSerialCh_d : integer range 0 to LA_DATA_WIDTH-1;
type dt_edge_trigger_mem is array(0 to 3) of std_logic;
signal dt_edge_trigger : dt_edge_trigger_mem := (others=> '0');
signal triggered : std_logic;
-- attribute strings
attribute KEEP: boolean;
attribute ASYNC_REG: boolean;
-- apply attributes
attribute KEEP of dataDd: signal is true;
attribute ASYNC_REG of dataDd: signal is true;
attribute KEEP of dataDdd: signal is true;
attribute ASYNC_REG of dataDdd: signal is true;
begin
logic_analyzer: process(clk_in)
begin
if (rising_edge(clk_in)) then
dt_enable_d <= dt_enable;
--digital trigger signal setup
dataDd <= dataD;
dataDdd <= dataDd;
dataDddd <= dataDdd;
if dtSerial_d = '0' then
dataDTrigSignal <= dataDddd;
else
dataDTrigSignal(0) <= dataDddd(dtSerialCh_d);
for i in 0 to LA_DATA_WIDTH-2 loop
dataDTrigSignal(i+1) <= dataDTrigSignal(i);
end loop;
end if;
dataDTrigSignal_d <= dataDTrigSignal;
dataDTrigSignal_dd <= dataDTrigSignal_d;
dt_triggered <= triggered;
case LAstate(2 downto 0) is
when A => -- "IDLE"
triggered <= '0';
dt_stage <= 0;
dt_delaycnt <= to_unsigned(0,LA_COUNTER_WIDTH);
digital_trig_patternA_d(0) <= digital_trig_patternA_0;
digital_trig_patternA_d(1) <= digital_trig_patternA_1;
digital_trig_patternA_d(2) <= digital_trig_patternA_2;
digital_trig_patternA_d(3) <= digital_trig_patternA_3;
digital_trig_patternB_d(0) <= digital_trig_patternB_0;
digital_trig_patternB_d(1) <= digital_trig_patternB_1;
digital_trig_patternB_d(2) <= digital_trig_patternB_2;
digital_trig_patternB_d(3) <= digital_trig_patternB_3;
digital_trig_mask_d(0) <= digital_trig_mask_0;
digital_trig_mask_d(1) <= digital_trig_mask_1;
digital_trig_mask_d(2) <= digital_trig_mask_2;
digital_trig_mask_d(3) <= digital_trig_mask_3;
digital_trig_mask_c(0) <= digital_trig_mask_0;
digital_trig_mask_c(1) <= digital_trig_mask_1;
digital_trig_mask_c(2) <= digital_trig_mask_2;
digital_trig_mask_c(3) <= digital_trig_mask_3;
dt_delayMaxcnt_d(0) <= unsigned(dt_delayMaxcnt_0);
dt_delayMaxcnt_d(1) <= unsigned(dt_delayMaxcnt_1);
dt_delayMaxcnt_d(2) <= unsigned(dt_delayMaxcnt_2);
dt_delayMaxcnt_d(3) <= unsigned(dt_delayMaxcnt_3);
dt_stage_capture_d <= to_integer(unsigned(dt_stage_capture));
dtSerial_d <= dtSerial;
dtSerialCh_d <= to_integer(unsigned(dtSerialCh));
--check if digital trigger is edge or level
for i in 0 to 3 loop
if digital_trig_patternA_d(i) /= digital_trig_patternB_d(i) then
dt_edge_trigger(i) <= '1';
else
dt_edge_trigger(i) <= '0';
end if;
end loop;
-- if external trigger has been enabled
if dt_enable = '1' and dt_enable_d = '0' then
LAstate <= B;
else
LAstate <= A;
end if;
when B => -- "Wait for stage pattern match"
if reset = '1' then
LAstate <= A;
else
if (dt_edge_trigger(dt_stage) = '1' ) then
-- if
-- ( (dataDTrigSignal_dd XNOR digital_trig_patternA_d(dt_stage)) AND
-- ( dataDTrigSignal_d XNOR digital_trig_patternB_d(dt_stage)) AND
-- digital_trig_mask_d(dt_stage) ) = digital_trig_mask_c(dt_stage)
-- then
-- LAstate <= D;
-- else
-- LAstate <= B;
-- end if;
else
if
( (dataDTrigSignal_dd XNOR digital_trig_patternA_d(dt_stage)) AND
digital_trig_mask_d(dt_stage) ) = digital_trig_mask_c(dt_stage)
then
LAstate <= D;
else
LAstate <= B;
end if;
end if;
end if;
-- when C => -- "Check stage counter match"
-- if reset = '1' then
-- LAstate <= A;
-- else
-- -- if delay counter for the current stage is set to 0
-- if dt_delayMaxcnt_d(dt_stage) = 0 then
-- -- if the current stage is the one to start capturing
-- if dt_stage_capture_d = dt_stage then
-- LAstate <= E;
-- else
-- dt_stage <= dt_stage + 1;
-- LAstate <= B;
-- end if;
-- else
-- -- go to count the counter if it is not 0
-- LAstate <= D;
-- end if;
-- end if;
when D => -- count the counter
if reset = '1' then
LAstate <= A;
elsif dt_delaycnt = dt_delayMaxcnt_d(dt_stage) then
-- if the current stage is the one to start saving samples
if dt_stage_capture_d = dt_stage then
LAstate <= E;
else
-- return to trigger detection for the next stage