pax_global_header 0000666 0000000 0000000 00000000064 13132146003 0014503 g ustar 00root root 0000000 0000000 52 comment=241d34c7b2fad944e690953ce049924c15853d31
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/ 0000775 0000000 0000000 00000000000 13132146003 0022212 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/README.md 0000664 0000000 0000000 00000002027 13132146003 0023472 0 ustar 00root root 0000000 0000000
This repository contains readout firmware and test software for the SOLID experiment
Current version is v8 (clone from tags/v8)
The master firmware uses the [ipbb](https://github.com/ipbus/ipbb) build tool, and requires the ipbus system firmware.
The following example procedure should build a board image for the 64 channel readout board. Note that a reasonably up-to-date
operating system (e.g. Centos7) is required.
mkdir work
cd work
curl -L https://github.com/ipbus/ipbb/archive/v0.2.3.tar.gz | tar xvz
source ipbb-0.2.3/env.sh
ipbb init build
cd build
ipbb add git https://github.com/ipbus/ipbus-firmware.git -b ipbus_2_0_v1
ipbb add git https://your_id@bitbucket.org/solidexperiment/solid_firmware.git -b v8
ipbb proj create vivado 64chan solid_firmware:projects/64chan_test
cd proj/64chan
ipbb vivado project
ipbb vivado impl
ipbb vivado bitfile
ipbb vivado package
### Who do I talk to? ###
* Dave Newbold (dave.newbold@cern.ch)
* Nick Ryder (nick.ryder@physics.ox.ac.uk)
* David Cussans (david.cussans@bristol.ac.uk)
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/ 0000775 0000000 0000000 00000000000 13132146003 0023464 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/ 0000775 0000000 0000000 00000000000 13132146003 0024455 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/ 0000775 0000000 0000000 00000000000 13132146003 0026063 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/ 0000775 0000000 0000000 00000000000 13132146003 0026653 5 ustar 00root root 0000000 0000000 firmware/ 0000775 0000000 0000000 00000000000 13132146003 0030410 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim cfg/ 0000775 0000000 0000000 00000000000 13132146003 0031147 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware lib_mappings.tcl 0000664 0000000 0000000 00000000436 13132146003 0034322 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware/cfg set xlib $::env(XILINX_SIMLIBS)
vmap secureip $xlib/secureip
vmap unisim $xlib/unisim
vmap unimacro $xlib/unimacro
vmap unifast $xlib/unifast
vmap unisims_ver $xlib/unisims_ver
vmap unimacro_ver $xlib/unimacro_ver
vmap unifast_ver $xlib/unifast_ver
vmap simprims_ver $xlib/simprims_ver
pc051a_infra_sim.dep 0000664 0000000 0000000 00000000421 13132146003 0034656 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware/cfg src pc051a_infra_sim.vhd
src -c ipbus-firmware:components/ipbus_util ../sim_hdl/clock_sim_7s.vhd
src -c ipbus-firmware:components/ipbus_eth ../sim/eth_mac_sim.vhd
include -c ipbus-firmware:components/ipbus_core
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
pc051a_sim.dep 0000664 0000000 0000000 00000000405 13132146003 0033501 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware/cfg @device_family = "artix7"
@device_name = "xc7a200t"
@device_package = "fbg484"
@device_speed = "-2"
@boardname = "pc051a"
#setup lib_mappings.tcl
src top_pc051a_sim.vhd
include pc051a_infra_sim.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
hdl/ 0000775 0000000 0000000 00000000000 13132146003 0031157 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware pc051a_infra_sim.vhd 0000664 0000000 0000000 00000004527 13132146003 0034712 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware/hdl -- kc705_basex_infra
--
-- All board-specific stuff goes here.
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity pc051a_infra_sim is
port(
clk_ipb_o: out std_logic; -- IPbus clock
rst_ipb_o: out std_logic;
clk125_o: out std_logic;
rst125_o: out std_logic;
nuke: in std_logic; -- The signal of doom
soft_rst: in std_logic; -- The signal of lesser doom
mac_addr: in std_logic_vector(47 downto 0); -- MAC address
ip_addr: in std_logic_vector(31 downto 0); -- IP address
ipb_in: in ipb_rbus; -- ipbus
ipb_out: out ipb_wbus
);
end pc051a_infra_sim;
architecture rtl of pc051a_infra_sim is
signal clk125_fr, clk125, clk_ipb, clk_ipb_i, rst125, rst_ipb, rst_ipb_ctrl: std_logic;
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
begin
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clock_sim_7s
port map(
clko_125 => clk125,
clko_ipb => clk_ipb_i,
locked => open,
nuke => nuke,
soft_rst => soft_rst,
rsto_125 => rst125,
rsto_ipb => rst_ipb,
rsto_ipb_ctrl => rst_ipb_ctrl
);
clk_ipb <= clk_ipb_i; -- Best to align delta delays on all clocks for simulation
clk_ipb_o <= clk_ipb_i;
rst_ipb_o <= rst_ipb;
clk125_o <= clk125;
rst125_o <= rst125;
-- Ethernet MAC core and PHY interface
eth: entity work.eth_mac_sim
generic map(
MULTI_PACKET => true
)
port map(
clk => clk125,
rst => rst125,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
port map(
mac_clk => clk125,
rst_macclk => rst125,
ipb_clk => clk_ipb,
rst_ipb => rst_ipb_ctrl,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_out,
ipb_in => ipb_in,
mac_addr => mac_addr,
ip_addr => ip_addr
);
end rtl;
top_pc051a_sim.vhd 0000664 0000000 0000000 00000001732 13132146003 0034410 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/sim/firmware/hdl -- Top-level design for ipbus demo
--
-- You must edit this file to set the IP and MAC addresses
--
-- Dave Newbold, 08/01/16
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.top_decl.all;
entity top is
end top;
architecture rtl of top is
signal clk_ipb, rst_ipb, clk125, rst125, nuke, soft_rst, userled, clk200: std_logic;
signal ipb_out: ipb_wbus;
signal ipb_in: ipb_rbus;
begin
-- Infrastructure
infra: entity work.pc051a_infra_sim -- Should work for artix also...
port map(
clk_ipb_o => clk_ipb,
rst_ipb_o => rst_ipb,
clk125_o => clk125,
rst125_o => rst125,
nuke => nuke,
soft_rst => soft_rst,
mac_addr => MAC_ADDR,
ip_addr => IP_ADDR,
ipb_in => ipb_in,
ipb_out => ipb_out
);
payload: entity work.payload_sim
port map(
ipb_clk => clk_ipb,
ipb_rst => rst_ipb,
ipb_in => ipb_out,
ipb_out => ipb_in,
clk125 => clk125,
rst125 => rst125,
nuke => nuke,
soft_rst => soft_rst
);
end rtl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/ 0000775 0000000 0000000 00000000000 13132146003 0027230 5 ustar 00root root 0000000 0000000 firmware/ 0000775 0000000 0000000 00000000000 13132146003 0030765 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth cfg/ 0000775 0000000 0000000 00000000000 13132146003 0031524 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware pc051a.dep 0000664 0000000 0000000 00000000426 13132146003 0033211 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/cfg @device_family = "artix7"
@device_name = "xc7a200t"
@device_package = "fbg484"
@device_speed = "-2"
@boardname = "pc051a"
setup settings_v7.tcl
src top_pc051a.vhd
include pc051a_infra.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
src --cd ../ucf pc051a.tcl
pc051a_infra.dep 0000664 0000000 0000000 00000000476 13132146003 0034375 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/cfg src pc051a_infra.vhd
src -c ipbus-firmware:components/ipbus_util clocks_7s_serdes.vhd ipbus_clock_div.vhd led_stretcher.vhd
include -c ipbus-firmware:components/ipbus_core
include -c ipbus-firmware:components/ipbus_eth artix_basex.dep
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd ipbus_package.vhd
settings_v7.tcl 0000664 0000000 0000000 00000000331 13132146003 0034501 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/cfg set obj [get_projects top]
set_property "default_lib" "xil_defaultlib" $obj
set_property "simulator_language" "Mixed" $obj
set_property "source_mgmt_mode" "DisplayOnly" $obj
set_property "target_language" "VHDL" $obj
hdl/ 0000775 0000000 0000000 00000000000 13132146003 0031534 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware pc051a_infra.vhd 0000664 0000000 0000000 00000006636 13132146003 0034422 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/hdl -- kc705_basex_infra
--
-- All board-specific stuff goes here.
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity pc051a_infra is
port(
eth_clk_p: in std_logic; -- 125MHz MGT clock
eth_clk_n: in std_logic;
eth_rx_p: in std_logic; -- Ethernet MGT input
eth_rx_n: in std_logic;
eth_tx_p: out std_logic; -- Ethernet MGT output
eth_tx_n: out std_logic;
sfp_los: in std_logic;
clk_ipb_o: out std_logic; -- IPbus clock
rst_ipb_o: out std_logic;
clk125_o: out std_logic;
rst125_o: out std_logic;
clk200: out std_logic; -- 200MHz unbuffered clock for IDELAYCTRL
nuke: in std_logic; -- The signal of doom
soft_rst: in std_logic; -- The signal of lesser doom
leds: out std_logic_vector(1 downto 0); -- status LEDs
debug: out std_logic_vector(3 downto 0);
mac_addr: in std_logic_vector(47 downto 0); -- MAC address
ip_addr: in std_logic_vector(31 downto 0); -- IP address
ipb_in: in ipb_rbus; -- ipbus
ipb_out: out ipb_wbus
);
end pc051a_infra;
architecture rtl of pc051a_infra is
signal clk125_fr, clk125, clk_ipb, clk_ipb_i, locked, clk_locked, eth_locked, rst125, rst_ipb, rst_ipb_ctrl, rst_eth, onehz, pkt: std_logic;
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
signal led_p: std_logic_vector(0 downto 0);
begin
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_7s_serdes
port map(
clki_fr => clk125_fr,
clki_125 => clk125,
clko_ipb => clk_ipb_i,
clko_200 => clk200,
eth_locked => eth_locked,
locked => clk_locked,
nuke => nuke,
soft_rst => soft_rst,
rsto_125 => rst125,
rsto_ipb => rst_ipb,
rsto_eth => rst_eth,
rsto_ipb_ctrl => rst_ipb_ctrl,
onehz => onehz
);
clk_ipb <= clk_ipb_i; -- Best to align delta delays on all clocks for simulation
clk_ipb_o <= clk_ipb_i;
rst_ipb_o <= rst_ipb;
clk125_o <= clk125;
rst125_o <= rst125;
locked <= clk_locked and eth_locked;
stretch: entity work.led_stretcher
generic map(
WIDTH => 1
)
port map(
clk => clk125,
d(0) => pkt,
q => led_p
);
leds <= ('0', onehz);
debug <= sfp_los & '0' & led_p(0) & (locked and onehz);
-- Ethernet MAC core and PHY interface
eth: entity work.eth_7s_1000basex_gtp
port map(
gt_clkp => eth_clk_p,
gt_clkn => eth_clk_n,
gt_txp => eth_tx_p,
gt_txn => eth_tx_n,
gt_rxp => eth_rx_p,
gt_rxn => eth_rx_n,
sfp_los => sfp_los,
clk125_out => clk125,
clk125_fr => clk125_fr,
rsti => rst_eth,
locked => eth_locked,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
port map(
mac_clk => clk125,
rst_macclk => rst125,
ipb_clk => clk_ipb,
rst_ipb => rst_ipb_ctrl,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_out,
ipb_in => ipb_in,
mac_addr => mac_addr,
ip_addr => ip_addr,
pkt => pkt
);
end rtl;
top_pc051a.vhd 0000664 0000000 0000000 00000007743 13132146003 0034125 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/hdl -- Top-level design for ipbus demo
--
-- You must edit this file to set the IP and MAC addresses
--
-- Dave Newbold, 08/01/16
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.top_decl.all;
entity top is port(
eth_clk_p: in std_logic; -- 125MHz MGT clock
eth_clk_n: in std_logic;
eth_rx_p: in std_logic; -- Ethernet MGT input
eth_rx_n: in std_logic;
eth_tx_p: out std_logic; -- Ethernet MGT output
eth_tx_n: out std_logic;
sfp_los: in std_logic;
sfp_tx_disable: out std_logic;
sfp_scl: out std_logic;
sfp_sda: out std_logic;
leds: out std_logic_vector(1 downto 0); -- TE712 LEDs
leds_c: out std_logic_vector(3 downto 0); -- carrier LEDs
dip_sw: in std_logic_vector(3 downto 0); -- carrier switches
si5326_scl: out std_logic;
si5326_sda: inout std_logic;
si5326_rstn: out std_logic;
si5326_phase_inc: out std_logic;
si5326_phase_dec: out std_logic;
si5326_clk1_validn: in std_logic;
si5326_clk2_validn: in std_logic;
si5326_lol: in std_logic;
si5326_clk_sel: out std_logic;
si5326_rate0: out std_logic;
si5326_rate1: out std_logic;
clk40_p: in std_logic;
clk40_n: in std_logic;
adc_spi_cs: out std_logic_vector(1 downto 0);
adc_spi_mosi: out std_logic;
adc_spi_miso: in std_logic_vector(1 downto 0);
adc_spi_sclk: out std_logic;
adc_d_p: in std_logic_vector(N_CHAN - 1 downto 0);
adc_d_n: in std_logic_vector(N_CHAN - 1 downto 0);
analog_scl: out std_logic;
analog_sda: inout std_logic;
sync_in_p: in std_logic;
sync_in_n: in std_logic;
trig_in_p: in std_logic;
trig_in_n: in std_logic;
trig_out_p: out std_logic;
trig_out_n: out std_logic;
clk_pll_p: out std_logic;
clk_pll_n: out std_logic
);
end top;
architecture rtl of top is
signal clk_ipb, rst_ipb, clk125, rst125, nuke, soft_rst, userled, clk200: std_logic;
signal ipb_out: ipb_wbus;
signal ipb_in: ipb_rbus;
signal debug: std_logic_vector(3 downto 0);
signal si5326_sda_o, analog_sda_o: std_logic;
begin
-- Infrastructure
infra: entity work.pc051a_infra -- Should work for artix also...
port map(
eth_clk_p => eth_clk_p,
eth_clk_n => eth_clk_n,
eth_tx_p => eth_tx_p,
eth_tx_n => eth_tx_n,
eth_rx_p => eth_rx_p,
eth_rx_n => eth_rx_n,
sfp_los => sfp_los,
clk_ipb_o => clk_ipb,
rst_ipb_o => rst_ipb,
clk125_o => clk125,
rst125_o => rst125,
clk200 => clk200,
nuke => nuke,
soft_rst => soft_rst,
leds => leds(1 downto 0),
debug => leds_c,
mac_addr(47 downto 4) => MAC_ADDR(47 downto 4),
mac_addr(3 downto 0) => dip_sw,
ip_addr(31 downto 4) => IP_ADDR(31 downto 4),
ip_addr(3 downto 0) => dip_sw,
ipb_in => ipb_in,
ipb_out => ipb_out
);
sfp_tx_disable <= '0';
sfp_scl <= '1';
sfp_sda <= '1';
payload: entity work.payload
port map(
ipb_clk => clk_ipb,
ipb_rst => rst_ipb,
ipb_in => ipb_out,
ipb_out => ipb_in,
clk125 => clk125,
rst125 => rst125,
clk200 => clk200,
nuke => nuke,
soft_rst => soft_rst,
userleds => open,
si5326_scl => si5326_scl,
si5326_sda_o => si5326_sda_o,
si5326_sda_i => si5326_sda,
si5326_rstn => si5326_rstn,
si5326_phase_inc => si5326_phase_inc,
si5326_phase_dec => si5326_phase_dec,
si5326_clk1_validn => si5326_clk1_validn,
si5326_clk2_validn => si5326_clk2_validn,
si5326_lol => si5326_lol,
si5326_clk_sel => si5326_clk_sel,
si5326_rate0 => si5326_rate0,
si5326_rate1 => si5326_rate1,
clk40_p => clk40_p,
clk40_n => clk40_n,
adc_cs => adc_spi_cs,
adc_mosi => adc_spi_mosi,
adc_miso => adc_spi_miso,
adc_sclk => adc_spi_sclk,
adc_d_p => adc_d_p,
adc_d_n => adc_d_n,
analog_scl => analog_scl,
analog_sda_o => analog_sda_o,
analog_sda_i => analog_sda,
sync_in_p => sync_in_p,
sync_in_n => sync_in_n,
trig_in_p => trig_in_p,
trig_in_n => trig_in_n,
trig_out_p => trig_out_p,
trig_out_n => trig_out_n,
clk_pll_p => clk_pll_p,
clk_pll_n => clk_pll_n
);
si5326_sda <= '0' when si5326_sda_o = '0' else 'Z';
analog_sda <= '0' when analog_sda_o = '0' else 'Z';
end rtl;
ucf/ 0000775 0000000 0000000 00000000000 13132146003 0031542 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware pc051a.tcl 0000664 0000000 0000000 00000016615 13132146003 0033250 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051a/base_fw/synth/firmware/ucf
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
# Ethernet RefClk (125MHz)
create_clock -period 8.000 -name eth_refclk [get_ports eth_clk_p]
# Ethernet monitor clock hack (62.5MHz)
create_clock -period 16.000 -name clk_dc [get_pins infra/eth/dc_buf/O]
# System synchronous clock (40MHz nominal)
create_clock -period 25.000 -name clk40 [get_ports clk40_p]
set_clock_groups -asynchronous -group [get_clocks -include_generated_clocks clk40] -group [get_clocks -include_generated_clocks eth_refclk] -group [get_clocks -include_generated_clocks [get_clocks -filter {name =~ infra/eth/phy/*/RXOUTCLK}]] -group [get_clocks -include_generated_clocks [get_clocks -filter {name =~ infra/eth/phy/*/TXOUTCLK}]]
# Area constraints
create_pblock infra
resize_pblock [get_pblocks infra] -add {CLOCKREGION_X1Y4:CLOCKREGION_X1Y4}
#add_cells_to_pblock [get_pblocks infra] [get_cells -quiet [list infra]]
create_pblock chans
resize_pblock [get_pblocks chans] -add {CLOCKREGION_X0Y3:CLOCKREGION_X0Y3}
#add_cells_to_pblock [get_pblocks chans] [get_cells -quiet [list payload]]
#remove_cells_from_pblock [get_pblocks chans] [get_cells payload/idelctrl]
set_property PACKAGE_PIN F6 [get_ports eth_clk_p]
set_property PACKAGE_PIN E6 [get_ports eth_clk_n]
set_property LOC GTPE2_CHANNEL_X0Y4 [get_cells -hier -filter {name=~infra/eth/*/gtpe2_i}]
proc false_path {patt clk} {
set p [get_ports -quiet $patt -filter {direction != out}]
if {[llength $p] != 0} {
set_input_delay 0 -clock [get_clocks $clk] [get_ports $patt -filter {direction != out}]
set_false_path -from [get_ports $patt -filter {direction != out}]
}
set p [get_ports -quiet $patt -filter {direction != in}]
if {[llength $p] != 0} {
set_output_delay 0 -clock [get_clocks $clk] [get_ports $patt -filter {direction != in}]
set_false_path -to [get_ports $patt -filter {direction != in}]
}
}
set_property IOSTANDARD LVCMOS33 [get_ports {sfp_*}]
set_property PACKAGE_PIN W17 [get_ports {sfp_los}]
set_property PULLUP TRUE [get_ports {sfp_los}]
set_property PACKAGE_PIN V19 [get_ports {sfp_tx_disable}]
set_property PACKAGE_PIN Y18 [get_ports {sfp_scl}]
set_property PACKAGE_PIN U20 [get_ports {sfp_sda}]
false_path sfp_* eth_refclk
set_property IOSTANDARD LVCMOS33 [get_ports {leds[*]}]
set_property PACKAGE_PIN W22 [get_ports {leds[0]}]
set_property PACKAGE_PIN U22 [get_ports {leds[1]}]
false_path {leds[*]} eth_refclk
set_property IOSTANDARD LVCMOS25 [get_ports {leds_c[*]}]
set_property PACKAGE_PIN B13 [get_ports {leds_c[0]}]
set_property PACKAGE_PIN C13 [get_ports {leds_c[1]}]
set_property PACKAGE_PIN E17 [get_ports {leds_c[2]}]
set_property PACKAGE_PIN F16 [get_ports {leds_c[3]}]
false_path {leds_c[*]} eth_refclk
set_property IOSTANDARD LVCMOS25 [get_ports {dip_sw[*]}]
set_property PACKAGE_PIN D14 [get_ports {dip_sw[0]}]
set_property PACKAGE_PIN D15 [get_ports {dip_sw[1]}]
set_property PACKAGE_PIN E13 [get_ports {dip_sw[2]}]
set_property PACKAGE_PIN E14 [get_ports {dip_sw[3]}]
false_path {dip_sw[*]} eth_refclk
set_property IOSTANDARD LVCMOS33 [get_ports {si5326_*}]
set_property PACKAGE_PIN T18 [get_ports {si5326_scl}]
set_property PACKAGE_PIN R18 [get_ports {si5326_sda}]
set_property PACKAGE_PIN R19 [get_ports {si5326_rstn}]
set_property PACKAGE_PIN U18 [get_ports {si5326_phase_inc}]
set_property PACKAGE_PIN U17 [get_ports {si5326_phase_dec}]
set_property PACKAGE_PIN P16 [get_ports {si5326_clk1_validn}]
set_property PACKAGE_PIN R17 [get_ports {si5326_clk2_validn}]
set_property PACKAGE_PIN Y21 [get_ports {si5326_lol}]
set_property PACKAGE_PIN Y19 [get_ports {si5326_clk_sel}]
set_property PACKAGE_PIN P19 [get_ports {si5326_rate0}]
set_property PACKAGE_PIN U21 [get_ports {si5326_rate1}]
false_path {si5326_*} eth_refclk
#set_property IOSTANDARD LVCMOS33 [get_ports {analog_*}]
#set_property PACKAGE_PIN Y22 [get_ports {analog_scl}]
#set_property PACKAGE_PIN T21 [get_ports {analog_sda}]
#false_path {analog_*} eth_refclk
set_property IOSTANDARD LVCMOS25 [get_ports {analog_*}]
set_property PACKAGE_PIN H20 [get_ports {analog_scl}]
set_property PACKAGE_PIN J22 [get_ports {analog_sda}]
set_property PULLTYPE PULLUP [get_ports {analog_sda}]
false_path {analog_*} eth_refclk
set_property IOSTANDARD LVDS_25 [get_ports {clk40_*}]
set_property PACKAGE_PIN W11 [get_ports {clk40_p}]
set_property PACKAGE_PIN W12 [get_ports {clk40_n}]
set_property IOSTANDARD LVDS_25 [get_ports {trig_out_* trig_in_* sync_in_*}]
set_property PACKAGE_PIN J15 [get_ports {trig_out_p}]
set_property PACKAGE_PIN H15 [get_ports {trig_out_n}]
set_property PACKAGE_PIN G17 [get_ports {trig_in_p}]
set_property PACKAGE_PIN G18 [get_ports {trig_in_n}]
set_property PACKAGE_PIN H17 [get_ports {sync_in_p}]
set_property PACKAGE_PIN H18 [get_ports {sync_in_n}]
false_path {sync_*} eth_refclk
set_property IOSTANDARD LVDS_25 [get_ports {clk_pll_*}]
set_property PACKAGE_PIN E22 [get_ports {clk_pll_p}]
set_property PACKAGE_PIN D22 [get_ports {clk_pll_n}]
false_path {clk_pll_*} eth_refclk
set_property IOSTANDARD LVCMOS18 [get_ports {adc_spi_*}]
set_property PACKAGE_PIN Y12 [get_ports {adc_spi_sclk}]
set_property PACKAGE_PIN Y11 [get_ports {adc_spi_mosi}]
set_property PACKAGE_PIN AB13 [get_ports {adc_spi_miso[0]}]
set_property PACKAGE_PIN AA13 [get_ports {adc_spi_miso[1]}]
set_property PACKAGE_PIN AA11 [get_ports {adc_spi_cs[0]}]
set_property PACKAGE_PIN AA10 [get_ports {adc_spi_cs[1]}]
false_path {adc_spi_*} eth_refclk
set_property IOSTANDARD LVDS_25 [get_ports {adc_d_*}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[0]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[1]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[2]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[3]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[4]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[5]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[6]}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*[7]}]
#set_property DIFF_TERM TRUE [get_ports {adc_d_*[8]}]
#set_property DIFF_TERM TRUE [get_ports {adc_d_*[9]}]
#set_property DIFF_TERM TRUE [get_ports {adc_d_*[10]}]
#set_property DIFF_TERM TRUE [get_ports {adc_d_*[11]}]
set_property PACKAGE_PIN F19 [get_ports {adc_d_p[0]}]
set_property PACKAGE_PIN F20 [get_ports {adc_d_n[0]}]
set_property PACKAGE_PIN E21 [get_ports {adc_d_p[1]}]
set_property PACKAGE_PIN D21 [get_ports {adc_d_n[1]}]
set_property PACKAGE_PIN B21 [get_ports {adc_d_p[2]}]
set_property PACKAGE_PIN A21 [get_ports {adc_d_n[2]}]
set_property PACKAGE_PIN C22 [get_ports {adc_d_p[3]}]
set_property PACKAGE_PIN B22 [get_ports {adc_d_n[3]}]
set_property PACKAGE_PIN B17 [get_ports {adc_d_p[4]}]
set_property PACKAGE_PIN B18 [get_ports {adc_d_n[4]}]
set_property PACKAGE_PIN E19 [get_ports {adc_d_p[5]}]
set_property PACKAGE_PIN D19 [get_ports {adc_d_n[5]}]
set_property PACKAGE_PIN A13 [get_ports {adc_d_p[6]}]
set_property PACKAGE_PIN A14 [get_ports {adc_d_n[6]}]
set_property PACKAGE_PIN C14 [get_ports {adc_d_p[7]}]
set_property PACKAGE_PIN C15 [get_ports {adc_d_n[7]}]
#set_property PACKAGE_PIN A15 [get_ports {adc_d_p[8]}]
#set_property PACKAGE_PIN A16 [get_ports {adc_d_n[8]}]
#set_property PACKAGE_PIN B15 [get_ports {adc_d_p[9]}]
#set_property PACKAGE_PIN B16 [get_ports {adc_d_n[9]}]
#set_property PACKAGE_PIN C18 [get_ports {adc_d_p[10]}]
#set_property PACKAGE_PIN C19 [get_ports {adc_d_n[10]}]
#set_property PACKAGE_PIN D17 [get_ports {adc_d_p[11]}]
#set_property PACKAGE_PIN C17 [get_ports {adc_d_n[11]}]
false_path {adc_d_*} eth_refclk
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/ 0000775 0000000 0000000 00000000000 13132146003 0024456 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/ 0000775 0000000 0000000 00000000000 13132146003 0026064 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/ 0000775 0000000 0000000 00000000000 13132146003 0026654 5 ustar 00root root 0000000 0000000 firmware/ 0000775 0000000 0000000 00000000000 13132146003 0030411 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim cfg/ 0000775 0000000 0000000 00000000000 13132146003 0031150 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware lib_mappings.tcl 0000664 0000000 0000000 00000000436 13132146003 0034323 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware/cfg set xlib $::env(XILINX_SIMLIBS)
vmap secureip $xlib/secureip
vmap unisim $xlib/unisim
vmap unimacro $xlib/unimacro
vmap unifast $xlib/unifast
vmap unisims_ver $xlib/unisims_ver
vmap unimacro_ver $xlib/unimacro_ver
vmap unifast_ver $xlib/unifast_ver
vmap simprims_ver $xlib/simprims_ver
pc051a_infra_sim.dep 0000664 0000000 0000000 00000000421 13132146003 0034657 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware/cfg src pc051a_infra_sim.vhd
src -c ipbus-firmware:components/ipbus_util ../sim_hdl/clock_sim_7s.vhd
src -c ipbus-firmware:components/ipbus_eth ../sim/eth_mac_sim.vhd
include -c ipbus-firmware:components/ipbus_core
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
pc051a_sim.dep 0000664 0000000 0000000 00000000404 13132146003 0033501 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware/cfg @device_family = "artix7"
@device_name = "xc7a200t"
@device_package = "fbg484"
@device_speed = "-2"
@boardname = "pc051a"
setup lib_mappings.tcl
src top_pc051a_sim.vhd
include pc051a_infra_sim.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
hdl/ 0000775 0000000 0000000 00000000000 13132146003 0031160 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware pc051a_infra_sim.vhd 0000664 0000000 0000000 00000004527 13132146003 0034713 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware/hdl -- kc705_basex_infra
--
-- All board-specific stuff goes here.
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity pc051a_infra_sim is
port(
clk_ipb_o: out std_logic; -- IPbus clock
rst_ipb_o: out std_logic;
clk125_o: out std_logic;
rst125_o: out std_logic;
nuke: in std_logic; -- The signal of doom
soft_rst: in std_logic; -- The signal of lesser doom
mac_addr: in std_logic_vector(47 downto 0); -- MAC address
ip_addr: in std_logic_vector(31 downto 0); -- IP address
ipb_in: in ipb_rbus; -- ipbus
ipb_out: out ipb_wbus
);
end pc051a_infra_sim;
architecture rtl of pc051a_infra_sim is
signal clk125_fr, clk125, clk_ipb, clk_ipb_i, rst125, rst_ipb, rst_ipb_ctrl: std_logic;
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
begin
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clock_sim_7s
port map(
clko_125 => clk125,
clko_ipb => clk_ipb_i,
locked => open,
nuke => nuke,
soft_rst => soft_rst,
rsto_125 => rst125,
rsto_ipb => rst_ipb,
rsto_ipb_ctrl => rst_ipb_ctrl
);
clk_ipb <= clk_ipb_i; -- Best to align delta delays on all clocks for simulation
clk_ipb_o <= clk_ipb_i;
rst_ipb_o <= rst_ipb;
clk125_o <= clk125;
rst125_o <= rst125;
-- Ethernet MAC core and PHY interface
eth: entity work.eth_mac_sim
generic map(
MULTI_PACKET => true
)
port map(
clk => clk125,
rst => rst125,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
port map(
mac_clk => clk125,
rst_macclk => rst125,
ipb_clk => clk_ipb,
rst_ipb => rst_ipb_ctrl,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_out,
ipb_in => ipb_in,
mac_addr => mac_addr,
ip_addr => ip_addr
);
end rtl;
top_pc051a_sim.vhd 0000664 0000000 0000000 00000001732 13132146003 0034411 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/sim/firmware/hdl -- Top-level design for ipbus demo
--
-- You must edit this file to set the IP and MAC addresses
--
-- Dave Newbold, 08/01/16
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.top_decl.all;
entity top is
end top;
architecture rtl of top is
signal clk_ipb, rst_ipb, clk125, rst125, nuke, soft_rst, userled, clk200: std_logic;
signal ipb_out: ipb_wbus;
signal ipb_in: ipb_rbus;
begin
-- Infrastructure
infra: entity work.pc051a_infra_sim -- Should work for artix also...
port map(
clk_ipb_o => clk_ipb,
rst_ipb_o => rst_ipb,
clk125_o => clk125,
rst125_o => rst125,
nuke => nuke,
soft_rst => soft_rst,
mac_addr => MAC_ADDR,
ip_addr => IP_ADDR,
ipb_in => ipb_in,
ipb_out => ipb_out
);
payload: entity work.payload_sim
port map(
ipb_clk => clk_ipb,
ipb_rst => rst_ipb,
ipb_in => ipb_out,
ipb_out => ipb_in,
clk125 => clk125,
rst125 => rst125,
nuke => nuke,
soft_rst => soft_rst
);
end rtl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/ 0000775 0000000 0000000 00000000000 13132146003 0027231 5 ustar 00root root 0000000 0000000 firmware/ 0000775 0000000 0000000 00000000000 13132146003 0030766 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth cfg/ 0000775 0000000 0000000 00000000000 13132146003 0031525 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware pc051b.dep 0000664 0000000 0000000 00000000434 13132146003 0033212 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/cfg @device_family = "artix7"
@device_name = "xc7a200t"
@device_package = "fbg484"
@device_speed = "-2"
@boardname = "solid_64chan"
setup settings_v7.tcl
src top_pc051b.vhd
include pc051b_infra.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
src --cd ../ucf pc051b.tcl
pc051b_infra.dep 0000664 0000000 0000000 00000000476 13132146003 0034377 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/cfg src pc051b_infra.vhd
src -c ipbus-firmware:components/ipbus_util clocks_7s_serdes.vhd ipbus_clock_div.vhd led_stretcher.vhd
include -c ipbus-firmware:components/ipbus_core
include -c ipbus-firmware:components/ipbus_eth artix_basex.dep
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd ipbus_package.vhd
settings_v7.tcl 0000664 0000000 0000000 00000000331 13132146003 0034502 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/cfg set obj [get_projects top]
set_property "default_lib" "xil_defaultlib" $obj
set_property "simulator_language" "Mixed" $obj
set_property "source_mgmt_mode" "DisplayOnly" $obj
set_property "target_language" "VHDL" $obj
hdl/ 0000775 0000000 0000000 00000000000 13132146003 0031535 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware pc051b_infra.vhd 0000664 0000000 0000000 00000006631 13132146003 0034417 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/hdl -- pc051b_infra
--
-- All board-specific stuff goes here.
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity pc051b_infra is
port(
eth_clk_p: in std_logic; -- 125MHz MGT clock
eth_clk_n: in std_logic;
eth_rx_p: in std_logic; -- Ethernet MGT input
eth_rx_n: in std_logic;
eth_tx_p: out std_logic; -- Ethernet MGT output
eth_tx_n: out std_logic;
sfp_los: in std_logic;
clk_ipb_o: out std_logic; -- IPbus clock
rst_ipb_o: out std_logic;
clk125_o: out std_logic;
rst125_o: out std_logic;
clk200: out std_logic; -- 200MHz unbuffered clock for IDELAYCTRL
nuke: in std_logic; -- The signal of doom
soft_rst: in std_logic; -- The signal of lesser doom
leds: out std_logic_vector(1 downto 0); -- status LEDs
debug: out std_logic_vector(3 downto 0);
mac_addr: in std_logic_vector(47 downto 0); -- MAC address
ip_addr: in std_logic_vector(31 downto 0); -- IP address
ipb_in: in ipb_rbus; -- ipbus
ipb_out: out ipb_wbus
);
end pc051b_infra;
architecture rtl of pc051b_infra is
signal clk125_fr, clk125, clk_ipb, clk_ipb_i, locked, clk_locked, eth_locked, rst125, rst_ipb, rst_ipb_ctrl, rst_eth, onehz, pkt: std_logic;
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
signal led_p: std_logic_vector(0 downto 0);
begin
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_7s_serdes
port map(
clki_fr => clk125_fr,
clki_125 => clk125,
clko_ipb => clk_ipb_i,
clko_200 => clk200,
eth_locked => eth_locked,
locked => clk_locked,
nuke => nuke,
soft_rst => soft_rst,
rsto_125 => rst125,
rsto_ipb => rst_ipb,
rsto_eth => rst_eth,
rsto_ipb_ctrl => rst_ipb_ctrl,
onehz => onehz
);
clk_ipb <= clk_ipb_i; -- Best to align delta delays on all clocks for simulation
clk_ipb_o <= clk_ipb_i;
rst_ipb_o <= rst_ipb;
clk125_o <= clk125;
rst125_o <= rst125;
locked <= clk_locked and eth_locked;
stretch: entity work.led_stretcher
generic map(
WIDTH => 1
)
port map(
clk => clk125,
d(0) => pkt,
q => led_p
);
leds <= ('0', onehz);
debug <= sfp_los & '0' & led_p(0) & (locked and onehz);
-- Ethernet MAC core and PHY interface
eth: entity work.eth_7s_1000basex_gtp
port map(
gt_clkp => eth_clk_p,
gt_clkn => eth_clk_n,
gt_txp => eth_tx_p,
gt_txn => eth_tx_n,
gt_rxp => eth_rx_p,
gt_rxn => eth_rx_n,
sfp_los => sfp_los,
clk125_out => clk125,
clk125_fr => clk125_fr,
rsti => rst_eth,
locked => eth_locked,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
port map(
mac_clk => clk125,
rst_macclk => rst125,
ipb_clk => clk_ipb,
rst_ipb => rst_ipb_ctrl,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_out,
ipb_in => ipb_in,
mac_addr => mac_addr,
ip_addr => ip_addr,
pkt => pkt
);
end rtl;
top_pc051b.vhd 0000664 0000000 0000000 00000005636 13132146003 0034126 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/hdl -- Top-level design for ipbus demo
--
-- You must edit this file to set the IP and MAC addresses
--
-- Dave Newbold, 08/01/16
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.top_decl.all;
entity top is port(
eth_clk_p: in std_logic; -- 125MHz MGT clock
eth_clk_n: in std_logic;
eth_rx_p: in std_logic; -- Ethernet MGT input
eth_rx_n: in std_logic;
eth_tx_p: out std_logic; -- Ethernet MGT output
eth_tx_n: out std_logic;
leds: out std_logic_vector(1 downto 0); -- TE712 LEDs
leds_c: out std_logic_vector(2 downto 0); -- carrier LEDs
addr: in std_logic_vector(7 downto 0); -- carrier switches
sel: out std_logic_vector(4 downto 0); -- bus select lines to CPLD
i2c_scl: out std_logic; -- I2C bus via CPLD
i2c_sda_i: in std_logic;
i2c_sda_o: out std_logic;
spi_csn: out std_logic;
spi_mosi: out std_logic;
spi_miso: in std_logic;
spi_sclk: out std_logic;
clkgen_lol: in std_logic; -- si5345 LOL
clkgen_rstn: out std_logic; -- si5345 RST
clk_p: in std_logic; -- clk from si5345
clk_n: in std_logic;
sync_in: in std_logic; -- IO via timing interface
trig_in: in std_logic;
trig_out: out std_logic;
adc_d_p: in std_logic_vector(63 downto 0); -- ADC serial input data
adc_d_n: in std_logic_vector(63 downto 0)
);
end top;
architecture rtl of top is
signal clk_ipb, rst_ipb, clk125, rst125, nuke, soft_rst, userled, clk200: std_logic;
signal ipb_out: ipb_wbus;
signal ipb_in: ipb_rbus;
signal debug: std_logic_vector(3 downto 0);
signal addrn: std_logic_vector(7 downto 0);
begin
-- Infrastructure
addrn <= not addr;
infra: entity work.pc051b_infra -- Should work for artix also...
port map(
eth_clk_p => eth_clk_p,
eth_clk_n => eth_clk_n,
eth_tx_p => eth_tx_p,
eth_tx_n => eth_tx_n,
eth_rx_p => eth_rx_p,
eth_rx_n => eth_rx_n,
sfp_los => '0',
clk_ipb_o => clk_ipb,
rst_ipb_o => rst_ipb,
clk125_o => clk125,
rst125_o => rst125,
clk200 => clk200,
nuke => nuke,
soft_rst => soft_rst,
leds => leds(1 downto 0),
debug => open,
mac_addr(47 downto 8) => MAC_ADDR(47 downto 8),
mac_addr(7 downto 0) => addrn,
ip_addr(31 downto 8) => IP_ADDR(31 downto 8),
ip_addr(7 downto 0) => addrn,
ipb_in => ipb_in,
ipb_out => ipb_out
);
payload: entity work.payload
port map(
ipb_clk => clk_ipb,
ipb_rst => rst_ipb,
ipb_in => ipb_out,
ipb_out => ipb_in,
clk125 => clk125,
rst125 => rst125,
clk200 => clk200,
nuke => nuke,
soft_rst => soft_rst,
userleds => leds_c,
addr => addr,
sel => sel,
i2c_scl => i2c_scl,
i2c_sda_i => i2c_sda_i,
i2c_sda_o => i2c_sda_o,
spi_csn => spi_csn,
spi_mosi => spi_mosi,
spi_miso => spi_miso,
spi_sclk => spi_sclk,
clkgen_lol => clkgen_lol,
clkgen_rstn => clkgen_rstn,
clk_p => clk_p,
clk_n => clk_n,
sync_in => sync_in,
trig_in => trig_in,
trig_out => trig_out,
adc_d_p => adc_d_p,
adc_d_n => adc_d_n
);
end rtl;
ucf/ 0000775 0000000 0000000 00000000000 13132146003 0031543 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware pc051b.tcl 0000664 0000000 0000000 00000026651 13132146003 0033253 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/boards/pc051b/base_fw/synth/firmware/ucf
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
# Ethernet RefClk (125MHz)
create_clock -period 8.000 -name eth_refclk [get_ports eth_clk_p]
# Ethernet monitor clock hack (62.5MHz)
create_clock -period 16.000 -name clk_dc [get_pins infra/eth/dc_buf/O]
# System synchronous clock (40MHz nominal)
create_clock -period 25.000 -name clk40 [get_ports clk_p]
set_clock_groups -asynchronous -group [get_clocks -include_generated_clocks eth_refclk] -group [get_clocks -include_generated_clocks [get_clocks -filter {name =~ infra/eth/phy/*/RXOUTCLK}]] -group [get_clocks -include_generated_clocks [get_clocks -filter {name =~ infra/eth/phy/*/TXOUTCLK}]]
set_clock_groups -asynchronous -group [get_clocks -include_generated_clocks clk40]
# Area constraints
create_pblock infra
resize_pblock [get_pblocks infra] -add {CLOCKREGION_X1Y4:CLOCKREGION_X1Y4}
set_property PACKAGE_PIN F6 [get_ports eth_clk_p]
set_property PACKAGE_PIN E6 [get_ports eth_clk_n]
set_property LOC GTPE2_CHANNEL_X0Y4 [get_cells -hier -filter {name=~infra/eth/*/gtpe2_i}]
proc false_path {patt clk} {
set p [get_ports -quiet $patt -filter {direction != out}]
if {[llength $p] != 0} {
set_input_delay 0 -clock [get_clocks $clk] [get_ports $patt -filter {direction != out}]
set_false_path -from [get_ports $patt -filter {direction != out}]
}
set p [get_ports -quiet $patt -filter {direction != in}]
if {[llength $p] != 0} {
set_output_delay 0 -clock [get_clocks $clk] [get_ports $patt -filter {direction != in}]
set_false_path -to [get_ports $patt -filter {direction != in}]
}
}
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {leds[*]}]
set_property PACKAGE_PIN W22 [get_ports {leds[0]}]
set_property PACKAGE_PIN U22 [get_ports {leds[1]}]
false_path {leds[*]} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {leds_c[*]}]
set_property PACKAGE_PIN W19 [get_ports {leds_c[0]}]
set_property PACKAGE_PIN Y18 [get_ports {leds_c[1]}]
set_property PACKAGE_PIN W20 [get_ports {leds_c[2]}]
false_path {leds_c[*]} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {addr[*]}]
set_property PACKAGE_PIN AA20 [get_ports {addr[0]}]
set_property PACKAGE_PIN Y21 [get_ports {addr[1]}]
set_property PACKAGE_PIN AB21 [get_ports {addr[2]}]
set_property PACKAGE_PIN U20 [get_ports {addr[3]}]
set_property PACKAGE_PIN AA21 [get_ports {addr[4]}]
set_property PACKAGE_PIN Y22 [get_ports {addr[5]}]
set_property PACKAGE_PIN AB22 [get_ports {addr[6]}]
set_property PACKAGE_PIN V20 [get_ports {addr[7]}]
false_path {addr[*]} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {sel[*]}]
set_property PACKAGE_PIN U18 [get_ports {sel[0]}]
set_property PACKAGE_PIN R18 [get_ports {sel[1]}]
set_property PACKAGE_PIN T18 [get_ports {sel[2]}]
set_property PACKAGE_PIN P16 [get_ports {sel[3]}]
set_property PACKAGE_PIN R17 [get_ports {sel[4]}]
false_path {sel[*]} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {i2c_*}]
set_property PACKAGE_PIN AA18 [get_ports {i2c_scl}]
set_property PACKAGE_PIN U17 [get_ports {i2c_sda_i}]
set_property PACKAGE_PIN AB18 [get_ports {i2c_sda_o}]
false_path {i2c_*} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {spi_*}]
set_property PACKAGE_PIN T21 [get_ports {spi_sclk}]
set_property PACKAGE_PIN U21 [get_ports {spi_mosi}]
set_property PACKAGE_PIN P19 [get_ports {spi_miso}]
set_property PACKAGE_PIN R19 [get_ports {spi_csn}]
false_path {spi_*} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports {clkgen_*}]
set_property PACKAGE_PIN V18 [get_ports {clkgen_rstn}]
set_property PACKAGE_PIN V19 [get_ports {clkgen_lol}]
false_path {clkgen_*} eth_refclk
# Bank 13, 2V5
set_property IOSTANDARD LVDS_25 [get_ports {clk_*}]
set_property DIFF_TERM TRUE [get_ports {clk_*}]
set_property PACKAGE_PIN W11 [get_ports {clk_p}]
set_property PACKAGE_PIN W12 [get_ports {clk_n}]
# Bank 15, 2V5
set_property IOSTANDARD LVCMOS25 [get_ports {sync_in trig_in}]
set_property PACKAGE_PIN J16 [get_ports {sync_in}]
set_property PACKAGE_PIN M17 [get_ports {trig_in}]
false_path {sync_in trig_in} eth_refclk
# Bank 14, 3V3
set_property IOSTANDARD LVCMOS33 [get_ports trig_out]
set_property PACKAGE_PIN Y19 [get_ports {trig_out}]
false_path {trig_out} eth_refclk
# Bank 13,15,16, 2V5 / 14, 3V3 (bits 61, 63)
set_property IOSTANDARD LVDS_25 [get_ports {adc_d_*}]
set_property DIFF_TERM TRUE [get_ports {adc_d_*}]
set_property DIFF_TERM FALSE [get_ports {adc_d_*[61] adc_d_*[63]}]
set_property PACKAGE_PIN W14 [get_ports {adc_d_p[0]}]
set_property PACKAGE_PIN Y14 [get_ports {adc_d_n[0]}]
set_property PACKAGE_PIN AA13 [get_ports {adc_d_p[1]}]
set_property PACKAGE_PIN AB13 [get_ports {adc_d_n[1]}]
set_property PACKAGE_PIN Y13 [get_ports {adc_d_p[2]}]
set_property PACKAGE_PIN AA14 [get_ports {adc_d_n[2]}]
set_property PACKAGE_PIN Y11 [get_ports {adc_d_p[3]}]
set_property PACKAGE_PIN Y12 [get_ports {adc_d_n[3]}]
set_property PACKAGE_PIN AA10 [get_ports {adc_d_p[4]}]
set_property PACKAGE_PIN AA11 [get_ports {adc_d_n[4]}]
set_property PACKAGE_PIN E22 [get_ports {adc_d_p[5]}]
set_property PACKAGE_PIN D22 [get_ports {adc_d_n[5]}]
set_property PACKAGE_PIN B20 [get_ports {adc_d_p[6]}]
set_property PACKAGE_PIN A20 [get_ports {adc_d_n[6]}]
set_property PACKAGE_PIN G21 [get_ports {adc_d_p[7]}]
set_property PACKAGE_PIN G22 [get_ports {adc_d_n[7]}]
set_property PACKAGE_PIN D20 [get_ports {adc_d_p[8]}]
set_property PACKAGE_PIN C20 [get_ports {adc_d_n[8]}]
set_property PACKAGE_PIN E21 [get_ports {adc_d_p[9]}]
set_property PACKAGE_PIN D21 [get_ports {adc_d_n[9]}]
set_property PACKAGE_PIN A18 [get_ports {adc_d_p[10]}]
set_property PACKAGE_PIN A19 [get_ports {adc_d_n[10]}]
set_property PACKAGE_PIN F18 [get_ports {adc_d_p[11]}]
set_property PACKAGE_PIN E18 [get_ports {adc_d_n[11]}]
set_property PACKAGE_PIN F19 [get_ports {adc_d_p[12]}]
set_property PACKAGE_PIN F20 [get_ports {adc_d_n[12]}]
set_property PACKAGE_PIN C22 [get_ports {adc_d_p[13]}]
set_property PACKAGE_PIN B22 [get_ports {adc_d_n[13]}]
set_property PACKAGE_PIN A15 [get_ports {adc_d_p[14]}]
set_property PACKAGE_PIN A16 [get_ports {adc_d_n[14]}]
set_property PACKAGE_PIN B21 [get_ports {adc_d_p[15]}]
set_property PACKAGE_PIN A21 [get_ports {adc_d_n[15]}]
set_property PACKAGE_PIN B15 [get_ports {adc_d_p[16]}]
set_property PACKAGE_PIN B16 [get_ports {adc_d_n[16]}]
set_property PACKAGE_PIN C18 [get_ports {adc_d_p[17]}]
set_property PACKAGE_PIN C19 [get_ports {adc_d_n[17]}]
set_property PACKAGE_PIN B17 [get_ports {adc_d_p[18]}]
set_property PACKAGE_PIN B18 [get_ports {adc_d_n[18]}]
set_property PACKAGE_PIN E19 [get_ports {adc_d_p[19]}]
set_property PACKAGE_PIN D19 [get_ports {adc_d_n[19]}]
set_property PACKAGE_PIN A13 [get_ports {adc_d_p[20]}]
set_property PACKAGE_PIN A14 [get_ports {adc_d_n[20]}]
set_property PACKAGE_PIN C14 [get_ports {adc_d_p[21]}]
set_property PACKAGE_PIN C15 [get_ports {adc_d_n[21]}]
set_property PACKAGE_PIN E16 [get_ports {adc_d_p[22]}]
set_property PACKAGE_PIN D16 [get_ports {adc_d_n[22]}]
set_property PACKAGE_PIN D17 [get_ports {adc_d_p[23]}]
set_property PACKAGE_PIN C17 [get_ports {adc_d_n[23]}]
set_property PACKAGE_PIN C13 [get_ports {adc_d_p[24]}]
set_property PACKAGE_PIN B13 [get_ports {adc_d_n[24]}]
set_property PACKAGE_PIN F13 [get_ports {adc_d_p[25]}]
set_property PACKAGE_PIN F14 [get_ports {adc_d_n[25]}]
set_property PACKAGE_PIN D14 [get_ports {adc_d_p[26]}]
set_property PACKAGE_PIN D15 [get_ports {adc_d_n[26]}]
set_property PACKAGE_PIN E13 [get_ports {adc_d_p[27]}]
set_property PACKAGE_PIN E14 [get_ports {adc_d_n[27]}]
set_property PACKAGE_PIN F16 [get_ports {adc_d_p[28]}]
set_property PACKAGE_PIN E17 [get_ports {adc_d_n[28]}]
set_property PACKAGE_PIN T16 [get_ports {adc_d_p[29]}]
set_property PACKAGE_PIN U16 [get_ports {adc_d_n[29]}]
set_property PACKAGE_PIN U15 [get_ports {adc_d_p[30]}]
set_property PACKAGE_PIN V15 [get_ports {adc_d_n[30]}]
set_property PACKAGE_PIN V10 [get_ports {adc_d_p[31]}]
set_property PACKAGE_PIN W10 [get_ports {adc_d_n[31]}]
set_property PACKAGE_PIN W15 [get_ports {adc_d_p[32]}]
set_property PACKAGE_PIN W16 [get_ports {adc_d_n[32]}]
set_property PACKAGE_PIN T14 [get_ports {adc_d_p[33]}]
set_property PACKAGE_PIN T15 [get_ports {adc_d_n[33]}]
set_property PACKAGE_PIN Y16 [get_ports {adc_d_p[34]}]
set_property PACKAGE_PIN AA16 [get_ports {adc_d_n[34]}]
set_property PACKAGE_PIN AA15 [get_ports {adc_d_p[35]}]
set_property PACKAGE_PIN AB15 [get_ports {adc_d_n[35]}]
set_property PACKAGE_PIN AB16 [get_ports {adc_d_p[36]}]
set_property PACKAGE_PIN AB17 [get_ports {adc_d_n[36]}]
set_property PACKAGE_PIN V13 [get_ports {adc_d_p[37]}]
set_property PACKAGE_PIN V14 [get_ports {adc_d_n[37]}]
set_property PACKAGE_PIN L14 [get_ports {adc_d_p[38]}]
set_property PACKAGE_PIN L15 [get_ports {adc_d_n[38]}]
set_property PACKAGE_PIN M15 [get_ports {adc_d_p[39]}]
set_property PACKAGE_PIN M16 [get_ports {adc_d_n[39]}]
set_property PACKAGE_PIN K17 [get_ports {adc_d_p[40]}]
set_property PACKAGE_PIN J17 [get_ports {adc_d_n[40]}]
set_property PACKAGE_PIN J15 [get_ports {adc_d_p[41]}]
set_property PACKAGE_PIN H15 [get_ports {adc_d_n[41]}]
set_property PACKAGE_PIN H17 [get_ports {adc_d_p[42]}]
set_property PACKAGE_PIN H18 [get_ports {adc_d_n[42]}]
set_property PACKAGE_PIN G17 [get_ports {adc_d_p[43]}]
set_property PACKAGE_PIN G18 [get_ports {adc_d_n[43]}]
set_property PACKAGE_PIN N22 [get_ports {adc_d_p[44]}]
set_property PACKAGE_PIN M22 [get_ports {adc_d_n[44]}]
set_property PACKAGE_PIN G15 [get_ports {adc_d_p[45]}]
set_property PACKAGE_PIN G16 [get_ports {adc_d_n[45]}]
set_property PACKAGE_PIN M13 [get_ports {adc_d_p[46]}]
set_property PACKAGE_PIN L13 [get_ports {adc_d_n[46]}]
set_property PACKAGE_PIN H13 [get_ports {adc_d_p[47]}]
set_property PACKAGE_PIN G13 [get_ports {adc_d_n[47]}]
set_property PACKAGE_PIN N20 [get_ports {adc_d_p[48]}]
set_property PACKAGE_PIN M20 [get_ports {adc_d_n[48]}]
set_property PACKAGE_PIN M18 [get_ports {adc_d_p[49]}]
set_property PACKAGE_PIN L18 [get_ports {adc_d_n[49]}]
set_property PACKAGE_PIN M21 [get_ports {adc_d_p[50]}]
set_property PACKAGE_PIN L21 [get_ports {adc_d_n[50]}]
set_property PACKAGE_PIN N18 [get_ports {adc_d_p[51]}]
set_property PACKAGE_PIN N19 [get_ports {adc_d_n[51]}]
set_property PACKAGE_PIN J19 [get_ports {adc_d_p[52]}]
set_property PACKAGE_PIN H19 [get_ports {adc_d_n[52]}]
set_property PACKAGE_PIN J14 [get_ports {adc_d_p[53]}]
set_property PACKAGE_PIN H14 [get_ports {adc_d_n[53]}]
set_property PACKAGE_PIN L19 [get_ports {adc_d_p[54]}]
set_property PACKAGE_PIN L20 [get_ports {adc_d_n[54]}]
set_property PACKAGE_PIN J20 [get_ports {adc_d_p[55]}]
set_property PACKAGE_PIN J21 [get_ports {adc_d_n[55]}]
set_property PACKAGE_PIN K18 [get_ports {adc_d_p[56]}]
set_property PACKAGE_PIN K19 [get_ports {adc_d_n[56]}]
set_property PACKAGE_PIN K13 [get_ports {adc_d_p[57]}]
set_property PACKAGE_PIN K14 [get_ports {adc_d_n[57]}]
set_property PACKAGE_PIN J22 [get_ports {adc_d_p[58]}]
set_property PACKAGE_PIN H22 [get_ports {adc_d_n[58]}]
set_property PACKAGE_PIN L16 [get_ports {adc_d_p[59]}]
set_property PACKAGE_PIN K16 [get_ports {adc_d_n[59]}]
set_property PACKAGE_PIN H20 [get_ports {adc_d_p[60]}]
set_property PACKAGE_PIN G20 [get_ports {adc_d_n[60]}]
set_property PACKAGE_PIN AA19 [get_ports {adc_d_p[61]}]
set_property PACKAGE_PIN AB20 [get_ports {adc_d_n[61]}]
set_property PACKAGE_PIN K21 [get_ports {adc_d_p[62]}]
set_property PACKAGE_PIN K22 [get_ports {adc_d_n[62]}]
set_property PACKAGE_PIN V17 [get_ports {adc_d_p[63]}]
set_property PACKAGE_PIN W17 [get_ports {adc_d_n[63]}]
false_path {adc_d_*} eth_refclk
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/ 0000775 0000000 0000000 00000000000 13132146003 0024377 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/ 0000775 0000000 0000000 00000000000 13132146003 0025754 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/addr_table/ 0000775 0000000 0000000 00000000000 13132146003 0030035 5 ustar 00root root 0000000 0000000 freq_ctr.xml 0000664 0000000 0000000 00000000477 13132146003 0032315 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/addr_table
mp7_ttc.xml 0000664 0000000 0000000 00000004701 13132146003 0032057 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/addr_table
state_history.xml 0000664 0000000 0000000 00000001226 13132146003 0033402 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/ 0000775 0000000 0000000 00000000000 13132146003 0027570 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cfg/ 0000775 0000000 0000000 00000000000 13132146003 0030327 5 ustar 00root root 0000000 0000000 mp7_ttc.dep 0000664 0000000 0000000 00000000072 13132146003 0032316 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cfg src mp7_ttc.vhd ttc_clocks.vhd
include mp7_ttc_common.dep
mp7_ttc_common.dep 0000664 0000000 0000000 00000001041 13132146003 0033663 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cfg src -c components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_mp7_ttc.vhd
addrtab -t mp7_ttc.xml
src ttc_cmd.vhd l1a_gen.vhd rng_wrapper.vhd rng_n1024_r32_t5_k32_s1c48.vhd ttc_ctrs.vhd ttc_decoder.vhd bunch_ctr.vhd freq_ctr.vhd freq_ctr_div.vhd ttc_cmd_ctrs.vhd
src -c components/ipbus_util del_array.vhd
src ttc_history_new.vhd
include state_history.dep
src tmt_sync.vhd
include -c components/ipbus_slaves syncreg_v.dep
src mp7_ttc_decl.vhd
src -c components/ipbus_slaves ipbus_reg_types.vhd
src -c components/ipbus_core ipbus_package.vhd
mp7_ttc_sim.dep 0000664 0000000 0000000 00000000130 13132146003 0033161 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cfg src ../sim_hdl/mp7_ttc_sim.vhd ../sim_hdl/ttc_clocks_sim.vhd
include mp7_ttc_common.dep
state_history.dep 0000664 0000000 0000000 00000000552 13132146003 0033645 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cfg src state_history.vhd
src -c components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_state_history.vhd
addrtab -t state_history.xml
src -c components/ipbus_slaves ipbus_ported_sdpram72.vhd
include -c components/ipbus_slaves syncreg_v.dep
src mp7_ttc_decl.vhd
src -c components/ipbus_slaves ipbus_reg_types.vhd
src -c components/ipbus_core ipbus_package.vhd
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cgn/ 0000775 0000000 0000000 00000000000 13132146003 0030337 5 ustar 00root root 0000000 0000000 ttc_history_fifo.vhd 0000664 0000000 0000000 00000024125 13132146003 0034345 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cgn --------------------------------------------------------------------------------
-- 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-2013 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file ttc_history_fifo.vhd when simulating
-- the core, ttc_history_fifo. 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 ttc_history_fifo IS
PORT (
rst : IN STD_LOGIC;
wr_clk : IN STD_LOGIC;
rd_clk : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(40 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(40 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC
);
END ttc_history_fifo;
ARCHITECTURE ttc_history_fifo_a OF ttc_history_fifo IS
-- synthesis translate_off
COMPONENT wrapped_ttc_history_fifo
PORT (
rst : IN STD_LOGIC;
wr_clk : IN STD_LOGIC;
rd_clk : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(40 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(40 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_ttc_history_fifo USE ENTITY XilinxCoreLib.fifo_generator_v9_3(behavioral)
GENERIC MAP (
c_add_ngc_constraint => 0,
c_application_type_axis => 0,
c_application_type_rach => 0,
c_application_type_rdch => 0,
c_application_type_wach => 0,
c_application_type_wdch => 0,
c_application_type_wrch => 0,
c_axi_addr_width => 32,
c_axi_aruser_width => 1,
c_axi_awuser_width => 1,
c_axi_buser_width => 1,
c_axi_data_width => 64,
c_axi_id_width => 4,
c_axi_ruser_width => 1,
c_axi_type => 0,
c_axi_wuser_width => 1,
c_axis_tdata_width => 64,
c_axis_tdest_width => 4,
c_axis_tid_width => 8,
c_axis_tkeep_width => 4,
c_axis_tstrb_width => 4,
c_axis_tuser_width => 4,
c_axis_type => 0,
c_common_clock => 0,
c_count_type => 0,
c_data_count_width => 11,
c_default_value => "BlankString",
c_din_width => 41,
c_din_width_axis => 1,
c_din_width_rach => 32,
c_din_width_rdch => 64,
c_din_width_wach => 32,
c_din_width_wdch => 64,
c_din_width_wrch => 2,
c_dout_rst_val => "0",
c_dout_width => 41,
c_enable_rlocs => 0,
c_enable_rst_sync => 1,
c_error_injection_type => 0,
c_error_injection_type_axis => 0,
c_error_injection_type_rach => 0,
c_error_injection_type_rdch => 0,
c_error_injection_type_wach => 0,
c_error_injection_type_wdch => 0,
c_error_injection_type_wrch => 0,
c_family => "virtex6",
c_full_flags_rst_val => 1,
c_has_almost_empty => 0,
c_has_almost_full => 0,
c_has_axi_aruser => 0,
c_has_axi_awuser => 0,
c_has_axi_buser => 0,
c_has_axi_rd_channel => 0,
c_has_axi_ruser => 0,
c_has_axi_wr_channel => 0,
c_has_axi_wuser => 0,
c_has_axis_tdata => 0,
c_has_axis_tdest => 0,
c_has_axis_tid => 0,
c_has_axis_tkeep => 0,
c_has_axis_tlast => 0,
c_has_axis_tready => 1,
c_has_axis_tstrb => 0,
c_has_axis_tuser => 0,
c_has_backup => 0,
c_has_data_count => 0,
c_has_data_counts_axis => 0,
c_has_data_counts_rach => 0,
c_has_data_counts_rdch => 0,
c_has_data_counts_wach => 0,
c_has_data_counts_wdch => 0,
c_has_data_counts_wrch => 0,
c_has_int_clk => 0,
c_has_master_ce => 0,
c_has_meminit_file => 0,
c_has_overflow => 0,
c_has_prog_flags_axis => 0,
c_has_prog_flags_rach => 0,
c_has_prog_flags_rdch => 0,
c_has_prog_flags_wach => 0,
c_has_prog_flags_wdch => 0,
c_has_prog_flags_wrch => 0,
c_has_rd_data_count => 0,
c_has_rd_rst => 0,
c_has_rst => 1,
c_has_slave_ce => 0,
c_has_srst => 0,
c_has_underflow => 0,
c_has_valid => 1,
c_has_wr_ack => 0,
c_has_wr_data_count => 0,
c_has_wr_rst => 0,
c_implementation_type => 2,
c_implementation_type_axis => 1,
c_implementation_type_rach => 1,
c_implementation_type_rdch => 1,
c_implementation_type_wach => 1,
c_implementation_type_wdch => 1,
c_implementation_type_wrch => 1,
c_init_wr_pntr_val => 0,
c_interface_type => 0,
c_memory_type => 1,
c_mif_file_name => "BlankString",
c_msgon_val => 0,
c_optimization_mode => 0,
c_overflow_low => 0,
c_preload_latency => 0,
c_preload_regs => 1,
c_prim_fifo_type => "2kx18",
c_prog_empty_thresh_assert_val => 4,
c_prog_empty_thresh_assert_val_axis => 1022,
c_prog_empty_thresh_assert_val_rach => 1022,
c_prog_empty_thresh_assert_val_rdch => 1022,
c_prog_empty_thresh_assert_val_wach => 1022,
c_prog_empty_thresh_assert_val_wdch => 1022,
c_prog_empty_thresh_assert_val_wrch => 1022,
c_prog_empty_thresh_negate_val => 5,
c_prog_empty_type => 0,
c_prog_empty_type_axis => 0,
c_prog_empty_type_rach => 0,
c_prog_empty_type_rdch => 0,
c_prog_empty_type_wach => 0,
c_prog_empty_type_wdch => 0,
c_prog_empty_type_wrch => 0,
c_prog_full_thresh_assert_val => 2047,
c_prog_full_thresh_assert_val_axis => 1023,
c_prog_full_thresh_assert_val_rach => 1023,
c_prog_full_thresh_assert_val_rdch => 1023,
c_prog_full_thresh_assert_val_wach => 1023,
c_prog_full_thresh_assert_val_wdch => 1023,
c_prog_full_thresh_assert_val_wrch => 1023,
c_prog_full_thresh_negate_val => 2046,
c_prog_full_type => 0,
c_prog_full_type_axis => 0,
c_prog_full_type_rach => 0,
c_prog_full_type_rdch => 0,
c_prog_full_type_wach => 0,
c_prog_full_type_wdch => 0,
c_prog_full_type_wrch => 0,
c_rach_type => 0,
c_rd_data_count_width => 11,
c_rd_depth => 2048,
c_rd_freq => 1,
c_rd_pntr_width => 11,
c_rdch_type => 0,
c_reg_slice_mode_axis => 0,
c_reg_slice_mode_rach => 0,
c_reg_slice_mode_rdch => 0,
c_reg_slice_mode_wach => 0,
c_reg_slice_mode_wdch => 0,
c_reg_slice_mode_wrch => 0,
c_synchronizer_stage => 2,
c_underflow_low => 0,
c_use_common_overflow => 0,
c_use_common_underflow => 0,
c_use_default_settings => 0,
c_use_dout_rst => 1,
c_use_ecc => 0,
c_use_ecc_axis => 0,
c_use_ecc_rach => 0,
c_use_ecc_rdch => 0,
c_use_ecc_wach => 0,
c_use_ecc_wdch => 0,
c_use_ecc_wrch => 0,
c_use_embedded_reg => 0,
c_use_fifo16_flags => 0,
c_use_fwft_data_count => 0,
c_valid_low => 0,
c_wach_type => 0,
c_wdch_type => 0,
c_wr_ack_low => 0,
c_wr_data_count_width => 11,
c_wr_depth => 2048,
c_wr_depth_axis => 1024,
c_wr_depth_rach => 16,
c_wr_depth_rdch => 1024,
c_wr_depth_wach => 16,
c_wr_depth_wdch => 1024,
c_wr_depth_wrch => 16,
c_wr_freq => 1,
c_wr_pntr_width => 11,
c_wr_pntr_width_axis => 10,
c_wr_pntr_width_rach => 4,
c_wr_pntr_width_rdch => 10,
c_wr_pntr_width_wach => 4,
c_wr_pntr_width_wdch => 10,
c_wr_pntr_width_wrch => 4,
c_wr_response_latency => 1,
c_wrch_type => 0
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_ttc_history_fifo
PORT MAP (
rst => rst,
wr_clk => wr_clk,
rd_clk => rd_clk,
din => din,
wr_en => wr_en,
rd_en => rd_en,
dout => dout,
full => full,
empty => empty,
valid => valid
);
-- synthesis translate_on
END ttc_history_fifo_a;
ttc_history_fifo.xco 0000664 0000000 0000000 00000015724 13132146003 0034362 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/cgn ##############################################################
#
# Xilinx Core Generator version 14.5
# Date: Wed Jul 10 17:14:08 2013
#
##############################################################
#
# 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 = true
SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false
SET designentry = VHDL
SET device = xc6vlx130t
SET devicefamily = virtex6
SET flowvendor = Foundation_ISE
SET formalverification = false
SET foundationsym = false
SET implementationfiletype = Ngc
SET package = ff1156
SET removerpms = false
SET simulationfiles = Behavioral
SET speedgrade = -1
SET verilogsim = true
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=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=ttc_history_fifo
CSET data_count=false
CSET data_count_width=11
CSET disable_timing_violations=true
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=2047
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=2046
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=41
CSET input_depth=2048
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=41
CSET output_depth=2048
CSET overflow_flag=false
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=No_Programmable_Full_Threshold
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=11
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=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=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=11
CSET wuser_width=1
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2012-11-19T12:39:56Z
# END Extra information
GENERATE
# CRC: af3ce0cc
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/doc/ 0000775 0000000 0000000 00000000000 13132146003 0030335 5 ustar 00root root 0000000 0000000 mp7_ttc.txt 0000664 0000000 0000000 00000010075 13132146003 0032377 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/doc Annotated address table for mp7_ttc
DMN, 13-07-15
This block contains the control registers for the TTC decoder block, and the various
LHC counters.
Set to enable L1A and B-commands from the external (AMC13) TTC input.
Set to clear the single and double error counters (clears on rising edge only).
Set to issue a single L1A - there is currently no way to specify the
BX on which this happens.
Set to enable the internal BC0 generator. This issues a BC0 command when the bunch
counter reaches the maximum value of 3564. Note that if the bunch counter has
already overflowed, it must be reset for internal BC0 to start being issued.
Set to prevent BC0 commands being recorded in the history buffer. All B-commands
(including BC0) are recorded by default.
Set to begin filling the history buffer (begins on rising edge, stops only when full).
Set to increment the fine delay setting for the TTC signal sampling clock. In the
MP7, each increment causes an additional delay of ~52ps. The delay can be reset
using the overall TTC block reset via the board control register. Typically used
for finding the optimal clock delay for a new board, should not be used in normal
operation.
Set to clear the LHC counters (clears on rising edge only).
Set to fill the capture buffers (edge-sensitive).
Specifies an arbitrary B-command to send internally. The command is sent as soon
as the register is set, so keep this at zero unless you wish to issue a B-command
with every write to this location. There is currently no way to specify the BX
on which the command is issued (make a feature request if you want this!).
Specifies the global delay to all external (AMC13) TTC signals in BX.
LHC bunch counter (0 -> 0xdeb).
Flag indicating that TTC sampling clock fine delay block is ready for use.
LHC event counter (starts at 0x1 after reset, a la CMS rules)
LHC orbit counter (starts at 0x0 after reset - correct or not?)
TTC decoder single bit error counter.
TTC decoder double bit error counter.
This block contains frequency counters for various generated clocks within the
chip. The register contains the number of clock cycles counted during 64k clock
cycles of the ipbus clock (currently running at 31.250MHz).
This block gives access to a history buffer which records every L1A and B-command
received via the TTC system (either externally or interally generated). The buffer
is a FIFO which is triggered, and then records commands until it fills. The FIFO
can be read out at any time, including when it is filling. Each FIFO entry is
two sequential words:
Word 0:
b31: Entry valid
b24: L1A on this corrsing (since L1A can coincide with B-command)
b19-8: LHC BX number
b7-0: TTC command (can be zero if there is an L1A)
Word 1:
b23:0: LHC orbit number
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl/ 0000775 0000000 0000000 00000000000 13132146003 0030337 5 ustar 00root root 0000000 0000000 bunch_ctr.vhd 0000664 0000000 0000000 00000007071 13132146003 0032737 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- bunch_ctr
--
-- General-purpose bunch counter, locked to BC0 signal
--
-- Free-running with period dictated by LHC_BUNCH_COUNT until a bc0 input
-- arrives - then it will lock to that and subsequently raise 'err' if bc0
-- does not arrive in the right place.
--
-- CLOCK_RATIO is the ratio between clk and clk40.
-- CLK_DIV is the division of the clock for bctr
-- The divider count is available on pctr
-- NB: CLK_DIV should be a factor of CLOCK_RATIO
-- OFFSET is useful for making an 'early' counter required for ram address
-- lines, etc. It's specified in terms of clock cycles, not BX.
-- LOCK_CTR controls lock / error check mode of counter
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity bunch_ctr is
generic(
CLOCK_RATIO: positive := 1;
CLK_DIV: positive := 1;
CTR_WIDTH: positive := 12;
OCTR_WIDTH: positive := 12;
LHC_BUNCH_COUNT: positive;
OFFSET: natural := 0;
BC0_BX: natural := 0;
LOCK_CTR: boolean := true
);
port(
clk: in std_logic;
rst: in std_logic;
clr: in std_logic;
bc0: in std_logic; -- clk40 domain
oc0: in std_logic := '0';
bctr: out std_logic_vector(CTR_WIDTH - 1 downto 0);
pctr: out std_logic_vector(2 downto 0);
bmax: out std_logic;
octr: out std_logic_vector(OCTR_WIDTH - 1 downto 0);
lock: out std_logic
);
begin
assert 2 ** CTR_WIDTH > LHC_BUNCH_COUNT * CLOCK_RATIO / CLK_DIV
report "Not enough bits in bunch counter"
severity failure;
assert CLK_DIV < 9
report "Division ratio too high"
severity failure;
end bunch_ctr;
architecture rtl of bunch_ctr is
constant SCYC: integer := ((BC0_BX * CLOCK_RATIO) + OFFSET + 2) mod (LHC_BUNCH_COUNT * CLOCK_RATIO);
constant OFF: integer := SCYC / CLK_DIV;
constant P_OFF: integer := SCYC mod CLK_DIV;
signal bctr_i: unsigned(CTR_WIDTH - 1 downto 0) := (others => '0');
signal pctr_i: unsigned(2 downto 0) := (others => '0');
signal lock_i, lock_lost: std_logic := '0';
signal bc0_d, bc0_dd, sync, sync_d, bmax_i, pmax_i, err_i: std_logic;
signal octr_i: unsigned(OCTR_WIDTH - 1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
bc0_d <= bc0; -- CDC (related clocks)
bc0_dd <= bc0_d;
sync_d <= sync;
if rst = '1' or clr = '1' then
bctr_i <= (others => '0');
pctr_i <= (others => '0');
lock_i <= '0';
lock_lost <= '0';
elsif sync = '1' and LOCK_CTR and lock_i = '0' and lock_lost = '0' then
bctr_i <= to_unsigned(OFF, CTR_WIDTH);
pctr_i <= to_unsigned(P_OFF, pctr_i'length);
lock_i <= '1';
else
if sync_d = '1' and lock_i = '1' and (bctr_i /= to_unsigned(OFF, CTR_WIDTH) or pctr_i /= to_unsigned(P_OFF, pctr_i'length)) then
lock_i <= '0';
lock_lost <= '1';
end if;
if pmax_i = '1' then
pctr_i <= "000";
if bmax_i = '1' then
bctr_i <= (others => '0');
else
bctr_i <= bctr_i + 1;
end if;
else
pctr_i <= pctr_i + 1;
end if;
end if;
end if;
end process;
sync <= '1' when bc0_d = '1' and bc0_dd = '0' else '0';
pmax_i <= '1' when pctr_i = to_unsigned(CLK_DIV - 1, 3) else '0';
bmax_i <= '1' when bctr_i = to_unsigned(LHC_BUNCH_COUNT * CLOCK_RATIO / CLK_DIV - 1, CTR_WIDTH) else '0';
process(clk)
begin
if rising_edge(clk) then
if oc0 = '1' or rst = '1' or clr = '1' then
octr_i <= to_unsigned(0, octr_i'length);
elsif bmax_i = '1' and pmax_i = '1' then
octr_i <= octr_i + 1;
end if;
end if;
end process;
bctr <= std_logic_vector(bctr_i);
pctr <= std_logic_vector(pctr_i);
octr <= std_logic_vector(octr_i);
lock <= lock_i;
bmax <= bmax_i and pmax_i;
end rtl;
freq_ctr.vhd 0000664 0000000 0000000 00000005044 13132146003 0032573 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- freq_ctr
--
-- General clock frequency monitor
--
-- Optimised to measure a large number of clocks, without requiring large resources
-- in each local clock domain (e.g. for monitoring transceiver clocks)
--
-- Counts number of pulses of the (divided by 64) clock in 16M cycles of ipbus clock
-- Should deal with clocks between 1MHz and ~320MHz
--
-- Dave Newbold, September 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
library unisim;
use unisim.VComponents.all;
entity freq_ctr is
generic(
N_CLK: natural := 1
);
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clkdiv: in std_logic_vector(N_CLK - 1 downto 0)
);
begin
assert N_CLK <= 16
report "Too many clocks for freq_ctr"
severity failure;
end freq_ctr;
architecture rtl of freq_ctr is
constant ADDR_WIDTH: integer := calc_width(N_CLK);
signal sel: integer range 0 to 2 ** ADDR_WIDTH - 1 := 0;
signal ctr, tctr, sctr: unsigned(23 downto 0) := X"000000";
signal stat, ctrl: ipb_reg_v(0 downto 0);
signal cd: std_logic_vector(2 ** ADDR_WIDTH - 1 downto 0) := (others => '0');
signal t_in, t, t_d, valid, svalid, cyc: std_logic;
attribute SHREG_EXTRACT: string;
attribute SHREG_EXTRACT of t_in: signal is "no"; -- Synchroniser not to be optimised into shreg
begin
reg: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipb_in,
ipbus_out => ipb_out,
d => stat,
q => ctrl
);
cyc <= ipb_in.ipb_strobe and ipb_in.ipb_write and not ipb_in.ipb_addr(0);
sel <= to_integer(unsigned(ctrl(0)(ADDR_WIDTH - 1 downto 0))) when ADDR_WIDTH > 0 else 0;
cd(N_CLK - 1 downto 0) <= clkdiv;
cd(2 ** ADDR_WIDTH - 1 downto N_CLK) <= (others => '0');
process(clk) -- Synchroniser
begin
if rising_edge(clk) then
t_in <= cd(sel);
t <= t_in;
t_d <= t;
end if;
end process;
process(clk) -- Counters
begin
if rising_edge(clk) then
ctr <= ctr + 1;
if ctr = X"000000" or (ctr(15 downto 0) = X"0000" and ctrl(0)(4) = '1') then
sctr <= tctr;
tctr <= X"000000";
elsif t = '1' and t_d = '0' then
tctr <= tctr + 1;
end if;
if ctr = X"000000" then
svalid <= valid;
valid <= '1';
elsif cyc = '1' then
svalid <= '0';
valid <= '0';
end if;
end if;
end process;
stat(0) <= "0000000" & svalid & std_logic_vector(sctr) when ctrl(0)(4) = '0' else
"0000000" & svalid & std_logic_vector(sctr(15 downto 0)) & X"00";
end rtl;
freq_ctr_div.vhd 0000664 0000000 0000000 00000001771 13132146003 0033440 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- freq_ctr_div
--
-- General clock frequency monitor
--
-- This part divides a local clock by 64, the output to be sent to the
-- frequency counter part.
--
-- Dave Newbold, September 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity freq_ctr_div is
generic(
N_CLK: positive := 1
);
port(
clk: in std_logic_vector(N_CLK - 1 downto 0);
clkdiv: out std_logic_vector(N_CLK - 1 downto 0)
);
end freq_ctr_div;
architecture rtl of freq_ctr_div is
signal t: std_logic_vector(N_CLK - 1 downto 0) := (others => '0');
begin
div_gen: for i in N_CLK - 1 downto 0 generate
signal q: std_logic;
signal cnt: natural range 0 to 31;
begin
process(clk(i))
begin
if rising_edge(clk(i)) then
if cnt = 0 then
cnt <= 31;
q <= '1';
else
cnt <= cnt - 1;
q <= '0';
end if;
if q = '1' then
t(i) <= not t(i);
end if;
end if;
end process;
end generate;
clkdiv <= t;
end rtl;
ipbus_decode_mp7_ttc.vhd 0000664 0000000 0000000 00000004747 13132146003 0035061 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_mp7_ttc is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_mp7_ttc(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Mon Oct 19 15:30:59 2015
constant N_SLV_CSR: integer := 0;
constant N_SLV_FREQ: integer := 1;
constant N_SLV_L1_GEN: integer := 2;
constant N_SLV_HIST: integer := 3;
constant N_SLV_CMD_CTRS: integer := 4;
constant N_SLV_TMT: integer := 5;
constant N_SLAVES: integer := 6;
-- END automatically generated VHDL
end ipbus_decode_mp7_ttc;
package body ipbus_decode_mp7_ttc is
function ipbus_sel_mp7_ttc(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Mon Oct 19 15:30:59 2015
if std_match(addr, "---------------------------00---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000018
elsif std_match(addr, "---------------------------0100-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FREQ, IPBUS_SEL_WIDTH)); -- freq / base 0x00000008 / mask 0x0000001e
elsif std_match(addr, "---------------------------0101-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_L1_GEN, IPBUS_SEL_WIDTH)); -- l1_gen / base 0x0000000a / mask 0x0000001e
elsif std_match(addr, "---------------------------011--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_HIST, IPBUS_SEL_WIDTH)); -- hist / base 0x0000000c / mask 0x0000001c
elsif std_match(addr, "---------------------------10---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CMD_CTRS, IPBUS_SEL_WIDTH)); -- cmd_ctrs / base 0x00000010 / mask 0x00000018
elsif std_match(addr, "---------------------------1100-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TMT, IPBUS_SEL_WIDTH)); -- tmt / base 0x00000018 / mask 0x0000001e
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_mp7_ttc;
end ipbus_decode_mp7_ttc;
ipbus_decode_state_history.vhd 0000664 0000000 0000000 00000003250 13132146003 0036371 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_state_history is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_state_history(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Mon Oct 19 15:31:00 2015
constant N_SLV_CSR: integer := 0;
constant N_SLV_BUFFER: integer := 1;
constant N_SLAVES: integer := 2;
-- END automatically generated VHDL
end ipbus_decode_state_history;
package body ipbus_decode_state_history is
function ipbus_sel_state_history(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Mon Oct 19 15:31:00 2015
if std_match(addr, "------------------------------0-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000002
elsif std_match(addr, "------------------------------1-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_BUFFER, IPBUS_SEL_WIDTH)); -- buffer / base 0x00000002 / mask 0x00000002
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_state_history;
end ipbus_decode_state_history;
l1a_gen.vhd 0000664 0000000 0000000 00000004700 13132146003 0032272 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- l1a_gen
--
-- Poisson L1A generator
--
-- div signal is used as simple threshold on 32b random
--
-- Dave Newbold, August 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.mp7_ttc_decl.all;
entity l1a_gen is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
tclk: in std_logic;
trst: in std_logic;
l1a: out std_logic
);
end l1a_gen;
architecture rtl of l1a_gen is
signal ctrl, stat: ipb_reg_v(0 downto 0);
signal stb: std_logic_vector(0 downto 0);
signal r: std_logic_vector(31 downto 0);
signal l1a_d: std_logic_vector(N_RULES downto 0);
signal tcnt: unsigned(31 downto 0);
signal l1a_c, l1a_i: std_logic;
signal rveto: std_logic_vector(N_RULES - 1 downto 0);
begin
-- control register
reg: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
rst => rst,
ipb_in => ipb_in,
ipb_out => ipb_out,
slv_clk => tclk,
d => stat,
q => ctrl,
stb => stb
);
stat(0) <= std_logic_vector(tcnt);
-- RNG
rng: entity work.rng_wrapper
port map(
clk => tclk,
rst => trst,
random => r
);
l1a_c <= '1' when r(31 downto 30) = "00" and unsigned(r(29 downto 0)) < unsigned(ctrl(0)(29 downto 0)) else '0';
-- Trigger counter (pre-rules)
process(tclk)
begin
if rising_edge(tclk) then
if trst = '1' then
tcnt <= (others => '0');
elsif l1a_c = '1' then
tcnt <= tcnt + 1;
end if;
end if;
end process;
-- Veto
l1a_i <= l1a_c and not or_reduce(rveto);
l1a <= l1a_i;
-- Trigger rules
l1a_d(0) <= l1a_i;
rgen: for i in 0 to N_RULES - 1 generate
signal delay: integer;
signal ctr: unsigned(2 downto 0);
begin
del: entity work.del_array
generic map(
DWIDTH => 1,
DELAY => TRIG_RULES(i).window_del
)
port map(
clk => tclk,
d(0) => l1a_d(i),
q(0) => l1a_d(i + 1)
);
process(tclk) -- keep track of trigger count in rolling window
begin
if rising_edge(tclk) then
if trst = '1' or ctrl(0)(31) = '0' then
ctr <= (others => '0');
else
if l1a_d(0) = '1' and l1a_d(i + 1) = '0' then
ctr <= ctr + 1;
elsif l1a_d(0) = '0' and l1a_d(i + 1) = '1' then
ctr <= ctr - 1;
end if;
end if;
end if;
end process;
rveto(i) <= '1' when ctr = to_unsigned(TRIG_RULES(i).maxtrig, 3) else '0';
end generate;
end rtl;
mp7_ttc.vhd 0000664 0000000 0000000 00000020015 13132146003 0032336 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- mp7_ttc
--
-- TTC decoder, counters, LHC clock distribution, etc
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_mp7_ttc.all;
use work.mp7_ttc_decl.all;
use work.top_decl.all;
entity mp7_ttc is
port(
clk: in std_logic; -- ipbus clock & rst
rst: in std_logic;
mmcm_rst: in std_logic; -- clock domain full reset
sel: in std_logic; -- TTC clock / internal clock select
lock: out std_logic; -- MMCM lock status
stop: out std_logic; -- MMCM clock status
ipb_in: in ipb_wbus; -- ipbus
ipb_out: out ipb_rbus;
clk40_in_p: in std_logic; -- TTC backplane clock signals
clk40_in_n: in std_logic;
clk40ish_in: in std_logic; -- internal pseudo-40MHz clock
clk40: out std_logic; -- clock outputs
rsto40: out std_logic; -- clock domain reset outputs
clk_p: out std_logic;
rst_p: out std_logic;
clk_payload: out std_logic;
rst_payload: out std_logic;
ttc_in_p: in std_logic; -- TTC protocol backplane signals
ttc_in_n: in std_logic;
ttc_cmd: out ttc_cmd_t; -- TTC b command output
ttc_cmd_dist: out ttc_cmd_t;
ttc_l1a: out std_logic; -- L1A output
ttc_l1a_flag: out std_logic; -- L1A qualifier output
l1a_throttle: in std_logic;
dist_lock: in std_logic;
bunch_ctr: out bctr_t;
evt_ctr: in eoctr_t;
orb_ctr: out eoctr_t;
oc_flag: out std_logic;
ec_flag: out std_logic;
tmt_sync: out tmt_sync_t;
monclk: in std_logic_vector(2 downto 0) -- clock monitoring inputs from MGTs
);
end mp7_ttc;
architecture rtl of mp7_ttc is
signal clk40_i, rst40_i, clk40s, clk40_div, rsti, clk40_a, rst40_a: std_logic;
signal clk80_i, rst80_i, clk160_i, rst160_i, clk240_i, rst240_i: std_logic;
signal l1a, l1a_ttc, l1a_int, l1a_del, l1a_pend, cmd_bx, cmd_pend, l1a_issue, cmd_issue: std_logic;
signal psok, bc0_fr, ctr_clr, err_rst: std_logic;
signal cmd, cmd_ttc, cmd_del: ttc_cmd_t;
signal bunch_ctr_i: bctr_t;
signal req_bx: unsigned(bctr_t'range);
signal orb_ctr_i: eoctr_t;
signal sinerr_ctr, dberr_ctr: std_logic_vector(15 downto 0);
signal stat: ipb_reg_v(3 downto 0);
signal ctrl: ipb_reg_v(1 downto 0);
signal stb: std_logic_vector(1 downto 0);
signal bc0_lock: std_logic;
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal tmt_ctrl: ipb_reg_v(0 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_mp7_ttc(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- TTC control registers
reg: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 2,
N_STAT => 4
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CSR),
ipb_out => ipbr(N_SLV_CSR),
slv_clk => clk40_a,
d => stat,
q => ctrl,
stb => stb
);
-- MMCM for clock multiplication / phase adjustment
rsti <= rst or ctrl(0)(2); -- CDC, unrelated clocks
clocks: entity work.ttc_clocks
port map(
clk40_in_p => clk40_in_p,
clk40_in_n => clk40_in_n,
clk_p40 => clk40ish_in,
clko_40 => clk40_i,
clko_80 => clk80_i,
clko_160 => clk160_i,
clko_240 => clk240_i,
rsto_40 => rst40_i,
rsto_80 => rst80_i,
rsto_160 => rst160_i,
rsto_240 => rst240_i,
clko_40s => clk40s,
stopped => stop,
locked => lock,
rst_mmcm => mmcm_rst,
rsti => rsti,
clksel => sel,
psval => ctrl(1)(11 downto 0),
psok => psok,
psen => ctrl(1)(12)
);
clk40_a <= clk40_i; -- Needed to make sure delta delays line up in simulation!
rst40_a <= rst40_i;
clk40 <= clk40_i;
rsto40 <= rst40_i;
with CLOCK_RATIO select clk_p <=
clk40_i when 1,
clk80_i when 2,
clk160_i when 4,
clk240_i when others;
with CLOCK_RATIO select rst_p <=
rst40_i when 1,
rst80_i when 2,
rst160_i when 4,
rst240_i when others;
with CLOCK_RATIO_PAYLOAD select clk_payload <=
clk40_i when 1,
clk80_i when 2,
clk160_i when 4,
clk240_i when others;
with CLOCK_RATIO_PAYLOAD select rst_payload <=
rst40_i when 1,
rst80_i when 2,
rst160_i when 4,
rst240_i when others;
-- TTC protocol decoder
err_rst <= ctrl(0)(1) and stb(0);
ttccmd: entity work.ttc_cmd
generic map(
LHC_BUNCH_COUNT => LHC_BUNCH_COUNT
)
port map(
clk => clk40_a,
rst => rst40_a,
sclk => clk40s,
ttc_in_p => ttc_in_p,
ttc_in_n => ttc_in_n,
l1a => l1a_ttc,
cmd => cmd_ttc,
sinerr_ctr => sinerr_ctr,
dberr_ctr => dberr_ctr,
c_delay => ctrl(1)(20 downto 16),
en_ttc => ctrl(0)(0),
err_rst => err_rst
);
-- L1A generation
l1agen: entity work.l1a_gen
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_L1_GEN),
ipb_out => ipbr(N_SLV_L1_GEN),
tclk => clk40_a,
trst => rst40_a,
l1a => l1a_int
);
l1a <= l1a_ttc or (l1a_int and not (ctrl(0)(8) and l1a_throttle)) or (l1a_pend and (cmd_bx or not ctrl(0)(10)) ); -- Note that internal throttle only applies to random trigger source
l1a_issue <= l1a and not l1a_ttc and not l1a_int;
-- TTC command generation
req_bx <= unsigned(ctrl(0)(23 downto 12)) - TTC_DEL - 1 when unsigned(ctrl(0)(23 downto 12)) > TTC_DEL else LHC_BUNCH_COUNT + unsigned(ctrl(0)(23 downto 12)) - TTC_DEL - 1;
cmd_bx <= '1' when std_logic_vector(req_bx) = bunch_ctr_i else '0';
process(cmd_ttc, bc0_fr, cmd_pend, cmd_bx, ctrl(0)(10))
begin
cmd_issue <= '0';
if cmd_ttc /= TTC_BCMD_NULL then
cmd <= cmd_ttc;
elsif bc0_fr = '1' then
cmd <= TTC_BCMD_BC0;
elsif cmd_pend = '1' and (cmd_bx = '1' or ctrl(0)(10) = '0') then
cmd <= ctrl(0)(31 downto 24);
cmd_issue <= '1';
else
cmd <= TTC_BCMD_NULL;
end if;
end process;
process(clk40_a)
begin
if rising_edge(clk40_a) then
cmd_pend <= (cmd_pend or (ctrl(0)(9) and stb(0))) and not (rst40_a or cmd_issue);
l1a_pend <= (l1a_pend or (ctrl(0)(7) and stb(0))) and not (rst40_a or l1a_issue);
ttc_cmd_dist <= cmd;
end if;
end process;
-- Counters
ctr_clr <= ctrl(0)(6) and stb(0);
ttcctr: entity work.ttc_ctrs
port map(
clk => clk40_a,
rst => rst40_a,
ttc_cmd => cmd,
l1a => l1a,
clr => '0',
en_int_bc0 => ctrl(0)(3),
bc0_lock => bc0_lock,
bc0_fr => bc0_fr,
ttc_cmd_out => cmd_del,
l1a_out => l1a_del,
bunch_ctr => bunch_ctr_i,
orb_ctr => orb_ctr_i
);
ttc_cmd <= cmd_del;
ttc_l1a <= l1a_del;
bunch_ctr <= bunch_ctr_i;
orb_ctr <= orb_ctr_i;
oc_flag <= '1' when orb_ctr_i(13 downto 0) = (13 downto 0 => '0') and bc0_lock = '1' else '0';
ec_flag <= '1' when evt_ctr(16 downto 0) = (16 downto 0 => '0') else '0';
-- Status reg
stat(0) <= std_logic_vector(to_unsigned(LHC_BUNCH_COUNT, 12)) & (l1a_pend or cmd_pend) & psok & dist_lock & bc0_lock & X"0" & bunch_ctr_i;
stat(1) <= evt_ctr;
stat(2) <= orb_ctr_i;
stat(3) <= dberr_ctr & sinerr_ctr;
-- clk40 frequency monitoring
div: entity work.freq_ctr_div
port map(
clk(0) => clk40_a,
clkdiv(0) => clk40_div
);
-- Clock frequency monitor
ctr: entity work.freq_ctr
generic map(
N_CLK => 4
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_FREQ),
ipb_out => ipbr(N_SLV_FREQ),
clkdiv(0) => clk40_div,
clkdiv(3 downto 1) => monclk
);
-- TTC history buffer
hist: entity work.ttc_history_new
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_HIST),
ipb_out => ipbr(N_SLV_HIST),
ttc_clk => clk40_a,
ttc_rst => rst40_a,
ttc_l1a => l1a_del,
ttc_cmd => cmd_del,
ttc_bx => bunch_ctr_i,
ttc_orb => orb_ctr_i,
ttc_evt => evt_ctr
);
-- Command counters
cmdctrs: entity work.ttc_cmd_ctrs
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CMD_CTRS),
ipb_out => ipbr(N_SLV_CMD_CTRS),
ttc_clk => clk40_a,
clr => ctr_clr,
ttc_cmd => cmd_del
);
-- TMT stuff
tmt: entity work.tmt_sync
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_TMT),
ipb_out => ipbr(N_SLV_TMT),
ttc_clk => clk40_a,
bctr => bunch_ctr_i,
tmt_l1a_sync => ttc_l1a_flag,
tmt_pkt_sync => tmt_sync(0)
);
end rtl;
mp7_ttc_decl.vhd 0000664 0000000 0000000 00000004173 13132146003 0033334 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- mp7_counters_decl
--
-- Defines the array subtypes for distributed counters
--
-- Dave Newbold, September 2013
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.top_decl.all;
use work.mp7_brd_decl.all;
package mp7_ttc_decl is
subtype ttc_cmd_t is std_logic_vector(7 downto 0);
subtype bctr_t is std_logic_vector(11 downto 0);
subtype pctr_t is std_logic_vector(2 downto 0);
subtype octr_t is std_logic_vector(11 downto 0);
subtype eoctr_t is std_logic_vector(31 downto 0);
type ttc_cmd_array is array(natural range <>) of ttc_cmd_t;
type ttc_stuff_t is
record
ttc_cmd: ttc_cmd_t;
bctr: bctr_t;
pctr: pctr_t;
end record;
type ttc_stuff_array is array(natural range <>) of ttc_stuff_t;
constant TTC_DEL: integer := 4;
constant TTC_BC0_BX: integer := 3539; -- Do not screw with this unless you like wasting time
constant TTC_N_BCMD: integer := 7;
constant TTC_BCMD_BC0: ttc_cmd_t := X"01";
constant TTC_BCMD_EC0: ttc_cmd_t := X"02";
constant TTC_BCMD_RESYNC: ttc_cmd_t := X"04";
constant TTC_BCMD_OC0: ttc_cmd_t := X"08";
constant TTC_BCMD_TEST_SYNC: ttc_cmd_t := X"0c";
constant TTC_BCMD_START: ttc_cmd_t := X"10";
constant TTC_BCMD_STOP: ttc_cmd_t := X"14";
constant TTC_BCMD_NULL: ttc_cmd_t := X"00";
constant N_RULES: integer := 4;
type trig_rule is
record
window_del: integer;
maxtrig: integer;
end record;
type trig_rules_t is array(0 to N_RULES - 1) of trig_rule;
constant TRIG_RULES: trig_rules_t := (
(2, 1), -- window size 3
(22, 2), -- window size 25
(75, 3), -- window size 100
(140, 4) -- window size 240
);
function ttc_chain_del(i: integer) return integer;
subtype tmt_sync_t is std_logic_vector(0 downto 0);
type tmt_sync_array is array(natural range <>) of tmt_sync_t;
end mp7_ttc_decl;
package body mp7_ttc_decl is
function ttc_chain_del(i: integer) return integer is
variable delay: integer;
begin
delay := (TTC_DEL * CLOCK_RATIO) - 2 - i; -- 2 compensates for pipeline registers between TTC block and first region
if i > CROSS_REGION then
return(delay - 1);
else
return(delay);
end if;
end function ttc_chain_del;
end package body mp7_ttc_decl;
rng_n1024_r32_t5_k32_s1c48.vhd 0000664 0000000 0000000 00000025316 13132146003 0035103 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
entity rng_n1024_r32_t5_k32_s1c48_SR is
generic(K:integer);
port(clk:in std_logic; ce:in std_logic; din:in std_logic; dout:out std_logic);
end entity;
architecture RTL of rng_n1024_r32_t5_k32_s1c48_SR is
signal bits : std_logic_vector(0 to K);
begin
bits(0) <= din;
process(clk, ce) begin
if(rising_edge(clk) and (ce='1')) then
bits(1 to K) <= bits(0 to K-1);
end if;
end process;
dout <= bits(K);
end;
library ieee;
use ieee.std_logic_1164.all;
entity rng_n1024_r32_t5_k32_s1c48 is
port(
clk:in std_logic;
ce:in std_logic;
mode:in std_logic;
s_in:in std_logic;
s_out:out std_logic;
rng:out std_logic_vector(31 downto 0)
);
end rng_n1024_r32_t5_k32_s1c48;
architecture RTL of rng_n1024_r32_t5_k32_s1c48 is
signal fifo_out, r_out:std_logic_vector(31 downto 0);
begin
rng(0) <= r_out(6);
rng(1) <= r_out(10);
rng(2) <= r_out(26);
rng(3) <= r_out(14);
rng(4) <= r_out(2);
rng(5) <= r_out(30);
rng(6) <= r_out(0);
rng(7) <= r_out(22);
rng(8) <= r_out(24);
rng(9) <= r_out(27);
rng(10) <= r_out(29);
rng(11) <= r_out(13);
rng(12) <= r_out(8);
rng(13) <= r_out(28);
rng(14) <= r_out(7);
rng(15) <= r_out(3);
rng(16) <= r_out(23);
rng(17) <= r_out(9);
rng(18) <= r_out(21);
rng(19) <= r_out(19);
rng(20) <= r_out(20);
rng(21) <= r_out(25);
rng(22) <= r_out(18);
rng(23) <= r_out(17);
rng(24) <= r_out(31);
rng(25) <= r_out(1);
rng(26) <= r_out(4);
rng(27) <= r_out(16);
rng(28) <= r_out(12);
rng(29) <= r_out(5);
rng(30) <= r_out(11);
rng(31) <= r_out(15);
s_out <= fifo_out(23);
regs : process(clk) begin
if(rising_edge(clk) and (ce='1')) then
r_out(0)<=(mode and fifo_out(0)) or ((not mode) and ('0' xor fifo_out(16) xor fifo_out(0) xor fifo_out(12) xor fifo_out(27)));
r_out(1)<=(mode and fifo_out(1)) or ((not mode) and ('0' xor fifo_out(16) xor fifo_out(12) xor fifo_out(20) xor fifo_out(24) xor fifo_out(1)));
r_out(2)<=(mode and fifo_out(2)) or ((not mode) and ('0' xor fifo_out(2) xor fifo_out(15) xor fifo_out(0) xor fifo_out(11) xor fifo_out(1)));
r_out(3)<=(mode and fifo_out(3)) or ((not mode) and ('0' xor fifo_out(3) xor fifo_out(2) xor fifo_out(4) xor fifo_out(5) xor fifo_out(25)));
r_out(4)<=(mode and fifo_out(4)) or ((not mode) and ('0' xor fifo_out(7) xor fifo_out(19) xor fifo_out(4) xor fifo_out(23) xor fifo_out(26)));
r_out(5)<=(mode and fifo_out(5)) or ((not mode) and ('0' xor fifo_out(10) xor fifo_out(3) xor fifo_out(0) xor fifo_out(5) xor fifo_out(6)));
r_out(6)<=(mode and fifo_out(6)) or ((not mode) and ('0' xor fifo_out(3) xor fifo_out(9) xor fifo_out(11) xor fifo_out(20) xor fifo_out(6)));
r_out(7)<=(mode and fifo_out(7)) or ((not mode) and ('0' xor fifo_out(7) xor fifo_out(22) xor fifo_out(24) xor fifo_out(28) xor fifo_out(14)));
r_out(8)<=(mode and fifo_out(8)) or ((not mode) and ('0' xor fifo_out(7) xor fifo_out(16) xor fifo_out(18) xor fifo_out(8)));
r_out(9)<=(mode and fifo_out(9)) or ((not mode) and ('0' xor fifo_out(9) xor fifo_out(0) xor fifo_out(18) xor fifo_out(23) xor fifo_out(13)));
r_out(10)<=(mode and fifo_out(10)) or ((not mode) and ('0' xor fifo_out(10) xor fifo_out(9) xor fifo_out(21) xor fifo_out(29) xor fifo_out(28)));
r_out(11)<=(mode and fifo_out(11)) or ((not mode) and ('0' xor fifo_out(3) xor fifo_out(15) xor fifo_out(11) xor fifo_out(6)));
r_out(12)<=(mode and fifo_out(12)) or ((not mode) and ('0' xor fifo_out(18) xor fifo_out(12) xor fifo_out(26) xor fifo_out(24) xor fifo_out(6)));
r_out(13)<=(mode and fifo_out(13)) or ((not mode) and ('0' xor fifo_out(4) xor fifo_out(31) xor fifo_out(8) xor fifo_out(13) xor fifo_out(30)));
r_out(14)<=(mode and fifo_out(14)) or ((not mode) and ('0' xor fifo_out(15) xor fifo_out(30) xor fifo_out(5) xor fifo_out(14) xor fifo_out(27)));
r_out(15)<=(mode and fifo_out(15)) or ((not mode) and ('0' xor fifo_out(15) xor fifo_out(4) xor fifo_out(22) xor fifo_out(8) xor fifo_out(26)));
r_out(16)<=(mode and fifo_out(16)) or ((not mode) and ('0' xor fifo_out(16) xor fifo_out(2) xor fifo_out(9) xor fifo_out(26) xor fifo_out(14)));
r_out(17)<=(mode and fifo_out(17)) or ((not mode) and ('0' xor fifo_out(17) xor fifo_out(19) xor fifo_out(12) xor fifo_out(31) xor fifo_out(8)));
r_out(18)<=(mode and fifo_out(18)) or ((not mode) and ('0' xor fifo_out(21) xor fifo_out(18) xor fifo_out(20) xor fifo_out(5) xor fifo_out(14)));
r_out(19)<=(mode and fifo_out(19)) or ((not mode) and ('0' xor fifo_out(19) xor fifo_out(4) xor fifo_out(25) xor fifo_out(1)));
r_out(20)<=(mode and fifo_out(20)) or ((not mode) and ('0' xor fifo_out(10) xor fifo_out(17) xor fifo_out(2) xor fifo_out(20) xor fifo_out(1)));
r_out(21)<=(mode and fifo_out(21)) or ((not mode) and ('0' xor fifo_out(17) xor fifo_out(16) xor fifo_out(21) xor fifo_out(11) xor fifo_out(25)));
r_out(22)<=(mode and fifo_out(22)) or ((not mode) and ('0' xor fifo_out(17) xor fifo_out(2) xor fifo_out(22) xor fifo_out(8) xor fifo_out(28)));
r_out(23)<=(mode and s_in) or ((not mode) and ('0' xor fifo_out(0) xor fifo_out(21) xor fifo_out(23) xor fifo_out(29)));
r_out(24)<=(mode and fifo_out(24)) or ((not mode) and ('0' xor fifo_out(11) xor fifo_out(24) xor fifo_out(13) xor fifo_out(6) xor fifo_out(27)));
r_out(25)<=(mode and fifo_out(25)) or ((not mode) and ('0' xor fifo_out(7) xor fifo_out(22) xor fifo_out(12) xor fifo_out(30) xor fifo_out(25)));
r_out(26)<=(mode and fifo_out(26)) or ((not mode) and ('0' xor fifo_out(10) xor fifo_out(21) xor fifo_out(18) xor fifo_out(22) xor fifo_out(26)));
r_out(27)<=(mode and fifo_out(27)) or ((not mode) and ('0' xor fifo_out(17) xor fifo_out(29) xor fifo_out(13) xor fifo_out(5) xor fifo_out(27)));
r_out(28)<=(mode and fifo_out(28)) or ((not mode) and ('0' xor fifo_out(10) xor fifo_out(19) xor fifo_out(15) xor fifo_out(28) xor fifo_out(14)));
r_out(29)<=(mode and fifo_out(29)) or ((not mode) and ('0' xor fifo_out(23) xor fifo_out(31) xor fifo_out(29) xor fifo_out(20) xor fifo_out(30)));
r_out(30)<=(mode and fifo_out(30)) or ((not mode) and ('0' xor fifo_out(9) xor fifo_out(31) xor fifo_out(30) xor fifo_out(25) xor fifo_out(28)));
r_out(31)<=(mode and fifo_out(31)) or ((not mode) and ('0' xor fifo_out(31) xor fifo_out(29) xor fifo_out(24) xor fifo_out(13) xor fifo_out(1)));
end if;
end process;
fifo_0 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(1), dout=>fifo_out(0));
fifo_1 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>30)
port map(clk=>clk, ce=>ce, din=>r_out(2), dout=>fifo_out(1));
fifo_2 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(3), dout=>fifo_out(2));
fifo_3 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(4), dout=>fifo_out(3));
fifo_4 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(5), dout=>fifo_out(4));
fifo_5 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(6), dout=>fifo_out(5));
fifo_6 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>31)
port map(clk=>clk, ce=>ce, din=>r_out(7), dout=>fifo_out(6));
fifo_7 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(8), dout=>fifo_out(7));
fifo_8 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>26)
port map(clk=>clk, ce=>ce, din=>r_out(9), dout=>fifo_out(8));
fifo_9 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(10), dout=>fifo_out(9));
fifo_10 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(11), dout=>fifo_out(10));
fifo_11 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(12), dout=>fifo_out(11));
fifo_12 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(13), dout=>fifo_out(12));
fifo_13 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(14), dout=>fifo_out(13));
fifo_14 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>21)
port map(clk=>clk, ce=>ce, din=>r_out(15), dout=>fifo_out(14));
fifo_15 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(16), dout=>fifo_out(15));
fifo_16 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(17), dout=>fifo_out(16));
fifo_17 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(18), dout=>fifo_out(17));
fifo_18 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(19), dout=>fifo_out(18));
fifo_19 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(20), dout=>fifo_out(19));
fifo_20 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(21), dout=>fifo_out(20));
fifo_21 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(22), dout=>fifo_out(21));
fifo_22 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(23), dout=>fifo_out(22));
fifo_23 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(24), dout=>fifo_out(23));
fifo_24 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>29)
port map(clk=>clk, ce=>ce, din=>r_out(25), dout=>fifo_out(24));
fifo_25 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>30)
port map(clk=>clk, ce=>ce, din=>r_out(26), dout=>fifo_out(25));
fifo_26 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(27), dout=>fifo_out(26));
fifo_27 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>29)
port map(clk=>clk, ce=>ce, din=>r_out(28), dout=>fifo_out(27));
fifo_28 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(29), dout=>fifo_out(28));
fifo_29 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>28)
port map(clk=>clk, ce=>ce, din=>r_out(30), dout=>fifo_out(29));
fifo_30 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(31), dout=>fifo_out(30));
fifo_31 : entity work.rng_n1024_r32_t5_k32_s1c48_SR generic map (K=>32)
port map(clk=>clk, ce=>ce, din=>r_out(0), dout=>fifo_out(31));
end RTL;
rng_wrapper.vhd 0000664 0000000 0000000 00000002162 13132146003 0033312 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- rng_wrapper
--
-- Wrapper for decent uniform 32b PRNG:
--
-- http://cas.ee.ic.ac.uk/people/dt10/research/rngs-fpga-lut_sr.html
--
-- Note that for reproducibility, we seed the RNG after every reset with an arbitrary
-- hardwired pattern; a full seed load cycle is necessary to flush any state
-- from the RNG FIFOs.
--
-- Dave Newbold, August 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity rng_wrapper is
port(
clk: in std_logic;
rst: in std_logic;
random: out std_logic_vector(31 downto 0)
);
end rng_wrapper;
architecture rtl of rng_wrapper is
signal mode, s_in: std_logic;
signal cnt: unsigned(9 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
cnt <= (others => '0');
mode <= '1';
elsif mode = '1' then
cnt <= cnt + 1;
if cnt = "1111111111" then
mode <= '0';
end if;
end if;
end if;
end process;
s_in <= cnt(3); -- Any seed value except zero will do
rng: entity work.rng_n1024_r32_t5_k32_s1c48
port map(
clk => clk,
ce => '1',
mode => mode,
s_in => s_in,
rng => random
);
end rtl;
state_history.vhd 0000664 0000000 0000000 00000006150 13132146003 0033666 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- state_history
--
-- Circular buffer for storing ttc commands, tts transitions, etc
--
-- ctrl(0): freeze
-- ctrl(1): reset
-- ctrl(15 downto 8): mask bits
-- stat(ADDR_WIDTH - 1 downto 0): write pointer
-- stat(16): wrap-around flag
--
-- 72b RAM word is organised as
-- 71:56 state_data; 55:36 evt_num; 35:16 orb_num; 15:4 bx_num; 3:0 cyc_num
--
-- Dave Newbold, August 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_state_history.all;
use work.mp7_ttc_decl.all;
entity state_history is
generic(
ADDR_WIDTH: integer := 9
);
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
ttc_clk: in std_logic; -- TTC clk40
ttc_rst: in std_logic;
ttc_bx: in bctr_t;
ttc_cyc: in pctr_t := (pctr_t'range => '0');
ttc_orb: in eoctr_t;
ttc_evt: in eoctr_t;
state: in std_logic_vector(15 downto 0)
);
end state_history;
architecture rtl of state_history is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl, stat: ipb_reg_v(0 downto 0);
signal addr: std_logic_vector(ADDR_WIDTH - 1 downto 0);
signal freeze, brst, we, wrap, strobe: std_logic;
signal state_d, mask: std_logic_vector(15 downto 0);
signal d: std_logic_vector(71 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_state_history(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- control register
ctrlreg: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CSR),
ipb_out => ipbr(N_SLV_CSR),
slv_clk => ttc_clk,
d => stat,
q => ctrl,
qmask(0) => X"ffff0003"
);
freeze <= ctrl(0)(0);
brst <= ctrl(0)(1);
mask <= ctrl(0)(31 downto 16);
stat(0)(ADDR_WIDTH - 1 downto 0) <= addr;
stat(0)(15 downto ADDR_WIDTH) <= (others => '0');
stat(0)(16) <= wrap;
stat(0)(31 downto 17) <= (others => '0');
-- strobe
process(ttc_clk)
begin
if rising_edge(ttc_clk) then
state_d <= state;
end if;
end process;
strobe <= or_reduce((state xor state_d) and not mask);
-- address pointer
process(ttc_clk)
begin
if rising_edge(ttc_clk) then
we <= strobe and not freeze;
d <= state & ttc_evt(19 downto 0) & ttc_orb(19 downto 0) & ttc_bx & '0' & ttc_cyc;
if ttc_rst = '1' or brst = '1' then
addr <= (others => '0');
wrap <= '0';
elsif we = '1' then
addr <= std_logic_vector(unsigned(addr) + 1);
if addr = (addr'range => '1') then
wrap <= '1';
end if;
end if;
end if;
end process;
-- buffer
buf: entity work.ipbus_ported_sdpram72
generic map(
ADDR_WIDTH => ADDR_WIDTH
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_BUFFER),
ipb_out => ipbr(N_SLV_BUFFER),
wclk => ttc_clk,
we => we,
d => d,
addr => addr
);
end rtl;
tmt_sync.vhd 0000664 0000000 0000000 00000002472 13132146003 0032630 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- tmt_sync
--
-- Provide sync signals for TMT
--
-- Dave Newbold, July 2015
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.mp7_ttc_decl.all;
entity tmt_sync is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
ttc_clk: in std_logic;
bctr: in bctr_t;
tmt_l1a_sync: out std_logic;
tmt_pkt_sync: out std_logic
);
end tmt_sync;
architecture rtl of tmt_sync is
signal ctrl: ipb_reg_v(0 downto 0);
signal ctr: unsigned(3 downto 0) := (others => '0');
signal en : std_logic;
begin
-- Control reg
reg: entity work.ipbus_reg_v
generic map(
N_REG => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipb_in,
ipbus_out => ipb_out,
q => ctrl,
qmask => (0 => X"0001FFFF")
);
process(ttc_clk)
begin
if rising_edge(ttc_clk) then
if (bctr(bctr'left downto 4) = (bctr'left downto 4 => '0') and bctr(3 downto 0) = ctrl(0)(7 downto 4)) or ctr = unsigned(ctrl(0)(3 downto 0)) then
ctr <= X"0";
else
ctr <= ctr + 1;
end if;
end if;
end process;
tmt_l1a_sync <= '1' when ctr = unsigned(ctrl(0)(11 downto 8)) and en = '1' else '0';
tmt_pkt_sync <= '1' when ctr = unsigned(ctrl(0)(15 downto 12)) and en = '1' else '0';
en <= ctrl(0)(16);
end rtl;
ttc_bc0_check.vhd 0000664 0000000 0000000 00000002754 13132146003 0033446 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_bc0_check
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity ttc_bc0_check is
port(
clk: in std_logic;
rst: in std_logic;
clr: in std_logic;
bc0: in std_logic;
lock: out std_logic;
len: out std_logic_vector(11 downto 0);
err: out std_logic
);
end ttc_bc0_check;
architecture rtl of ttc_bc0_check is
signal bctr, len_i: unsigned(11 downto 0);
signal my_bc0, lock_i: std_logic;
type state_type is (ST_IDLE, ST_FIRST, ST_CHECK, ST_ERR);
signal state: state_type;
begin
lock_i <= '1' when state = ST_CHECK or state = ST_ERR else '0';
process(clk)
begin
if rising_edge(clk) then
if lock_i = '0' and bc0 = '1' then
bctr <= X"001";
len_i <= bctr;
elsif lock_i = '1' and bctr = (len_i - 1) then
bctr <= X"000";
else
bctr <= bctr + 1;
end if;
end if;
end process;
my_bc0 <= '1' when bctr = X"000" else '0';
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or clr = '1' then
state <= ST_IDLE;
else
case state is
when ST_IDLE =>
if bc0 = '1' then
state <= ST_FIRST;
end if;
when ST_FIRST =>
if bc0 = '1' then
state <= ST_CHECK;
end if;
when ST_CHECK =>
if (bc0 xor my_bc0) = '1' then
state <= ST_ERR;
end if;
when ST_ERR =>
end case;
end if;
end if;
end process;
lock <= lock_i;
len <= std_logic_vector(len_i);
err <= '1' when state = ST_ERR else '0';
end rtl;
ttc_clocks.vhd 0000664 0000000 0000000 00000011603 13132146003 0033114 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_clocks
--
-- Clock generation for LHC clocks
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
entity ttc_clocks is
port(
clk40_in_p: in std_logic;
clk40_in_n: in std_logic;
clk_p40: in std_logic;
clko_40: out std_logic;
clko_80: out std_logic;
clko_120: out std_logic;
clko_160: out std_logic;
clko_240: out std_logic;
rsto_40: out std_logic;
rsto_80: out std_logic;
rsto_120: out std_logic;
rsto_160: out std_logic;
rsto_240: out std_logic;
clko_40s: out std_logic;
stopped: out std_logic;
locked: out std_logic;
rst_mmcm: in std_logic;
rsti: in std_logic;
clksel: in std_logic;
psen: in std_logic;
psval: in std_logic_vector(11 downto 0);
psok: out std_logic
);
end ttc_clocks;
architecture rtl of ttc_clocks is
signal clk40_bp, clk40_bp_u, clk_fb, clk_fb_fr, clk_p40_b: std_logic;
signal clk40_u, clk80_u, clk120_u, clk160_u, clk240_u, clk40s_u, clk40_i, clk80_i, clk120_i, clk160_i, clk240_i: std_logic;
signal locked_i, rsto_80_r, rsto_120_r, rsto_160_r, rsto_240_r: std_logic;
signal pscur_i: std_logic_vector(11 downto 0);
signal psrst, psgo, psincdec, psdone, psbusy, psdiff: std_logic;
attribute KEEP: string;
attribute KEEP of clk40_i: signal is "TRUE";
attribute KEEP of clk120_i: signal is "TRUE";
attribute KEEP of clk160_i: signal is "TRUE";
attribute KEEP of clk240_i: signal is "TRUE";
attribute KEEP of rsto_120_r: signal is "TRUE";
attribute KEEP of rsto_160_r: signal is "TRUE";
attribute KEEP of rsto_240_r: signal is "TRUE";
begin
-- Input buffers
ibuf_clk40: IBUFGDS
port map(
i => clk40_in_p,
ib => clk40_in_n,
o => clk40_bp_u
);
bufr_clk40: BUFG
port map(
i => clk40_bp_u,
o => clk40_bp
);
-- MMCM
mmcm: MMCME2_ADV
generic map(
clkin1_period => 25.0,
clkin2_period => 25.0,
clkfbout_mult_f => 24.0,
clkout1_divide => 24,
clkout2_divide => 24,
clkout2_phase => 45.0, -- Adjust on test
clkout2_use_fine_ps => true,
clkout3_divide => 12,
clkout4_divide => 6,
clkout5_divide => 4,
clkout6_divide => 8
)
port map(
clkin1 => clk40_bp,
clkin2 => clk_p40,
clkinsel => clksel,
clkfbin => clk_fb,
clkfbout => clk_fb,
clkout1 => clk40_u,
clkout2 => clk40s_u,
clkout3 => clk80_u,
clkout4 => clk160_u,
clkout5 => clk240_u,
clkout6 => clk120_u,
rst => rst_mmcm,
pwrdwn => '0',
clkinstopped => stopped,
locked => locked_i,
daddr => "0000000",
di => X"0000",
dwe => '0',
den => '0',
dclk => '0',
psclk => clk40_i,
psen => psgo,
psincdec => psincdec,
psdone => psdone
);
locked <= locked_i;
-- Phase shift state machine
psrst <= rst_mmcm or not locked_i or not psen;
process(clk40_i)
begin
if rising_edge(clk40_i) then
if psrst = '1' then
pscur_i <= X"000";
elsif psdone = '1' then
if psincdec = '1' then
pscur_i <= std_logic_vector(unsigned(pscur_i) + 1);
else
pscur_i <= std_logic_vector(unsigned(pscur_i) - 1);
end if;
end if;
psgo <= psdiff and not (psbusy or psgo or psrst);
psbusy <= ((psbusy and not psdone) or psgo) and not psrst;
end if;
end process;
psincdec <= '1' when psval > pscur_i else '0';
psdiff <= '1' when psval /= pscur_i else '0';
psok <= not psdiff;
-- Buffers
bufg_40: BUFG
port map(
i => clk40_u,
o => clk40_i
);
clko_40 <= clk40_i;
process(clk40_i)
begin
if rising_edge(clk40_i) then
rsto_40 <= rsti or not locked_i;
end if;
end process;
bufg_80: BUFG
port map(
i => clk80_u,
o => clk80_i
);
clko_80 <= clk80_i;
process(clk80_i)
begin
if rising_edge(clk80_i) then
rsto_80_r <= rsti or not locked_i; -- Disaster looms if tools duplicate this signal
rsto_80 <= rsto_80_r; -- Pipelining for high-fanout signal
end if;
end process;
bufg_120: BUFG
port map(
i => clk120_u,
o => clk120_i
);
clko_120 <= clk120_i;
process(clk120_i)
begin
if rising_edge(clk120_i) then
rsto_120_r <= rsti or not locked_i; -- Disaster looms if tools duplicate this signal
rsto_120 <= rsto_120_r; -- Pipelining for high-fanout signal
end if;
end process;
bufg_160: BUFG
port map(
i => clk160_u,
o => clk160_i
);
clko_160 <= clk160_i;
process(clk160_i)
begin
if rising_edge(clk160_i) then
rsto_160_r <= rsti or not locked_i; -- Disaster looms if tools duplicate this signal
rsto_160 <= rsto_160_r; -- Pipelining for high-fanout signal
end if;
end process;
bufg_240: BUFG
port map(
i => clk240_u,
o => clk240_i
);
clko_240 <= clk240_i;
process(clk240_i)
begin
if rising_edge(clk240_i) then
rsto_240_r <= rsti or not locked_i; -- Disaster looms if tools duplicate this signal
rsto_240 <= rsto_240_r; -- Pipelining for high-fanout signal
end if;
end process;
bufr_40s: BUFH
port map(
i => clk40s_u,
o => clko_40s
);
end rtl;
ttc_clocks_v6.vhd 0000664 0000000 0000000 00000005457 13132146003 0033541 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_clocks
--
-- Clock generation for LHC clocks
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity ttc_clocks is
port(
clk40_in_p: in std_logic;
clk40_in_n: in std_logic;
clk_p40: in std_logic;
clko_40: out std_logic;
clko_160: out std_logic;
clko_240: out std_logic;
rsto_40: out std_logic;
rsto_160: out std_logic;
rsto_240: out std_logic;
clko_40s: out std_logic;
stopped: out std_logic;
locked: out std_logic;
locked_fr: out std_logic;
rst_mmcm: in std_logic;
rsti: in std_logic;
clksel: in std_logic;
psclk: in std_logic;
psinc: in std_logic
);
end ttc_clocks;
architecture rtl of ttc_clocks is
signal clk40_bp, clk40_bp_u, clk_fb, clk_fb_fr, clk_p40_b: std_logic;
signal clk40_u, clk160_u, clk240_u, clk40s_u, clk40_i, clk160_i, clk240_i: std_logic;
signal locked_i: std_logic;
attribute KEEP: string;
attribute KEEP of clk40_i: signal is "TRUE";
attribute KEEP of clk160_i: signal is "TRUE";
attribute KEEP of clk240_i: signal is "TRUE";
begin
ibuf_clk40: IBUFGDS
port map(
i => clk40_in_p,
ib => clk40_in_n,
o => clk40_bp_u
);
bufr_clk40: BUFH
port map(
i => clk40_bp_u,
o => clk40_bp
);
bufr_clk40_fr: BUFH
port map(
i => clk_p40,
o => clk_p40_b
);
mmcm: MMCM_ADV
generic map(
clkin1_period => 25.0,
clkin2_period => 25.0,
clkfbout_mult_f => 24.0,
clkout1_divide => 24,
clkout2_divide => 24,
clkout2_phase => 225.0, -- Adjust on test
clkout2_use_fine_ps => true,
clkout4_divide => 6,
clkout5_divide => 4
)
port map(
clkin1 => clk40_bp,
clkin2 => clk_p40_b,
clkinsel => clksel,
clkfbin => clk_fb,
clkfbout => clk_fb,
clkout1 => clk40_u,
clkout2 => clk40s_u,
clkout4 => clk160_u,
clkout5 => clk240_u,
rst => rst_mmcm,
pwrdwn => '0',
clkinstopped => stopped,
locked => locked_i,
daddr => "0000000",
di => X"0000",
dwe => '0',
den => '0',
dclk => '0',
psclk => psclk,
psen => psinc,
psincdec => '1'
);
locked <= locked_i;
bufg_40: BUFG
port map(
i => clk40_u,
o => clk40_i
);
clko_40 <= clk40_i;
process(clk40_i)
begin
if rising_edge(clk40_i) then
rsto_40 <= rsti or not locked_i;
end if;
end process;
bufg_160: BUFG
port map(
i => clk160_u,
o => clk160_i
);
clko_160 <= clk160_i;
process(clk160_i)
begin
if rising_edge(clk160_i) then
rsto_160 <= rsti or not locked_i;
end if;
end process;
bufg_240: BUFG
port map(
i => clk240_u,
o => clk240_i
);
clko_240 <= clk240_i;
process(clk240_i)
begin
if rising_edge(clk240_i) then
rsto_240 <= rsti or not locked_i;
end if;
end process;
bufr_40s: BUFR
port map(
i => clk40s_u,
ce => '1',
clr => '0',
o => clko_40s
);
end rtl;
ttc_cmd.vhd 0000664 0000000 0000000 00000005222 13132146003 0032401 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_cmd
--
-- Decoder for TTC commands
--
-- All signals synchronous to clk unless stated
-- Priority for commands is:
-- external TTC
-- internal BC0 (highest priority)
-- internal
-- no action (default)
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
use work.mp7_ttc_decl.all;
entity ttc_cmd is
generic(
LHC_BUNCH_COUNT: integer
);
port(
clk: in std_logic; -- Main TTC clock
rst: in std_logic;
sclk: in std_logic; -- Sampling clock for TTC data
ttc_in_p: in std_logic; -- TTC datastream from AMC13
ttc_in_n: in std_logic;
l1a: out std_logic; -- L1A output
cmd: out ttc_cmd_t; -- B-command output (zero if no command)
sinerr_ctr: out std_logic_vector(15 downto 0);
dberr_ctr: out std_logic_vector(15 downto 0);
c_delay: in std_logic_vector(4 downto 0); -- Coarse delay for TTC signals
en_ttc: in std_logic; -- enable TTC inputs
err_rst: in std_logic -- Err ctr reset
);
end ttc_cmd;
architecture rtl of ttc_cmd is
signal ttc_data, ttc_data_d: std_logic_vector(1 downto 0);
signal ttc_in, ttc_in_d, sinerr, dberr, stb_ttc: std_logic;
signal cmd_ttc, cmda, cmdb, cmdc, ext_cmd_i: ttc_cmd_t;
signal ttc_l1a, ext_cmd_pend, ext_cmd_rx, cmd_slot: std_logic;
signal sinerr_ctr_i, dberr_ctr_i: unsigned(15 downto 0);
begin
buf: IBUFDS
port map(
i => ttc_in_p,
ib => ttc_in_n,
o => ttc_in
);
ddr: IDDR
generic map(
DDR_CLK_EDGE => "SAME_EDGE"
)
port map(
q1 => ttc_data(0),
q2 => ttc_data(1),
c => sclk,
ce => '1',
d => ttc_in,
r => '0',
s => '0'
);
cdel0: SRLC32E
port map(
q => ttc_data_d(0),
d => ttc_data(0),
clk => clk,
ce => '1',
a => c_delay
);
cdel1: SRLC32E
port map(
q => ttc_data_d(1),
d => ttc_data(1),
clk => clk,
ce => '1',
a => c_delay
);
decode: entity work.ttc_decoder
port map(
ttc_clk => clk,
ttc_data => ttc_data_d,
l1accept => ttc_l1a,
sinerrstr => sinerr,
dberrstr => dberr,
brcststr => stb_ttc,
brcst => cmd_ttc
);
l1a <= ttc_l1a and en_ttc;
cmd <= cmd_ttc when en_ttc = '1' and stb_ttc = '1' else TTC_BCMD_NULL;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' or err_rst = '1' then
sinerr_ctr_i <= (others => '0');
dberr_ctr_i <= (others => '0');
else
if sinerr = '1' and sinerr_ctr_i /= X"ffff" then
sinerr_ctr_i <= sinerr_ctr_i + 1;
end if;
if dberr = '1' and dberr_ctr_i /= X"ffff" then
dberr_ctr_i <= dberr_ctr_i + 1;
end if;
end if;
end if;
end process;
sinerr_ctr <= std_logic_vector(sinerr_ctr_i);
dberr_ctr <= std_logic_vector(dberr_ctr_i);
end rtl;
ttc_cmd_ctrs.vhd 0000664 0000000 0000000 00000003512 13132146003 0033434 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_cmd_ctrs
--
-- Count the number of TTC commands of each type received
--
-- Dave Newbold, March 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.mp7_ttc_decl.all;
use work.top_decl.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
entity ttc_cmd_ctrs is
port(
clk: in std_logic; -- ipbus clock
rst: in std_logic;
ipb_in: in ipb_wbus; -- ipbus
ipb_out: out ipb_rbus;
ttc_clk: in std_logic;
clr: in std_logic; -- counter clear (ttc clock domain)
ttc_cmd: in ttc_cmd_t -- TTC command
);
end ttc_cmd_ctrs;
architecture rtl of ttc_cmd_ctrs is
constant ADDR_WIDTH: integer := calc_width(TTC_N_BCMD);
signal ri: ipb_reg_v(2 ** ADDR_WIDTH - 1 downto 0);
signal sel: integer range 0 to 2 ** ADDR_WIDTH - 1 := 0;
type ctr_array_t is array(TTC_N_BCMD - 1 downto 0) of unsigned(31 downto 0);
signal ctr_array: ctr_array_t;
type bcmd_array_t is array(TTC_N_BCMD - 1 downto 0) of ttc_cmd_t;
constant bcmd_array: bcmd_array_t := (
TTC_BCMD_STOP,
TTC_BCMD_START,
TTC_BCMD_TEST_SYNC,
TTC_BCMD_OC0,
TTC_BCMD_RESYNC,
TTC_BCMD_EC0,
TTC_BCMD_BC0
);
begin
process(ttc_clk)
begin
if rising_edge(ttc_clk) then
if clr = '1' then
ctr_array <= (others => (others => '0'));
else
for i in TTC_N_BCMD - 1 downto 0 loop
if ttc_cmd = bcmd_array(i) and ctr_array(i) /= X"ffffffff" then
ctr_array(i) <= ctr_array(i) + 1;
end if;
end loop;
end if;
end if;
end process;
rgen: for i in TTC_N_BCMD - 1 downto 0 generate
ri(i) <= std_logic_vector(ctr_array(i));
end generate;
ri(2 ** ADDR_WIDTH - 1 downto TTC_N_BCMD) <= (others => (others => '0'));
sel <= to_integer(unsigned(ipb_in.ipb_addr(ADDR_WIDTH - 1 downto 0))) when ADDR_WIDTH > 0 else 0;
ipb_out.ipb_rdata <= ri(sel);
ipb_out.ipb_ack <= ipb_in.ipb_strobe;
ipb_out.ipb_err <= '0';
end rtl;
ttc_ctrs.vhd 0000664 0000000 0000000 00000003553 13132146003 0032616 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_ctrs
--
-- Bunch / orbit / event counters
--
-- Dave Newbold, March 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.mp7_ttc_decl.all;
use work.top_decl.all;
entity ttc_ctrs is
port(
clk: in std_logic; -- Main TTC clock
rst: in std_logic;
ttc_cmd: in ttc_cmd_t;
l1a: in std_logic;
clr: in std_logic;
en_int_bc0: in std_logic;
bc0_lock: out std_logic;
bc0_fr: out std_logic;
ttc_cmd_out: out ttc_cmd_t;
l1a_out: out std_logic;
bunch_ctr: out bctr_t; -- TTC counters
orb_ctr: out eoctr_t
);
end ttc_ctrs;
architecture rtl of ttc_ctrs is
signal cmd_d: ttc_cmd_t;
signal bunch_ctr_i: bctr_t;
signal evt_ctr_i: unsigned(eoctr_t'range);
signal orb_ctr_i: std_logic_vector(eoctr_t'range);
signal bc0, oc0, bmax, l1a_i, bc0_lock_i: std_logic;
begin
ctrdel: entity work.del_array
generic map(
DWIDTH => ttc_cmd_t'length + 1,
DELAY => TTC_DEL + 1
)
port map(
clk => clk,
d(ttc_cmd_t'length - 1 downto 0) => ttc_cmd,
d(ttc_cmd_t'length) => l1a,
q(ttc_cmd_t'length - 1 downto 0) => cmd_d,
q(ttc_cmd_t'length) => l1a_i
);
ttc_cmd_out <= cmd_d;
l1a_out <= l1a_i;
bc0 <= '1' when cmd_d = TTC_BCMD_BC0 and en_int_bc0 = '0' else '0';
oc0 <= '1' when cmd_d = TTC_BCMD_OC0 else '0';
bctr: entity work.bunch_ctr
generic map(
CLOCK_RATIO => 1,
CTR_WIDTH => 12,
OCTR_WIDTH => eoctr_t'length,
LHC_BUNCH_COUNT => LHC_BUNCH_COUNT,
BC0_BX => TTC_BC0_BX
)
port map(
clk => clk,
rst => rst,
clr => clr,
bc0 => bc0,
oc0 => oc0,
bctr => bunch_ctr_i,
bmax => bmax,
octr => orb_ctr_i,
lock => bc0_lock_i
);
bc0_lock <= bc0_lock_i or en_int_bc0;
bunch_ctr <= bunch_ctr_i;
bc0_fr <= '1' when bunch_ctr_i = std_logic_vector(to_unsigned(TTC_BC0_BX - TTC_DEL - 1, bunch_ctr'length)) and en_int_bc0 = '1' else '0';
orb_ctr <= eoctr_t(orb_ctr_i);
end rtl;
ttc_decoder.vhd 0000664 0000000 0000000 00000007425 13132146003 0033252 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_decoder
--
-- Takes the TTC bistream, outputs L1A and broadcast commands
-- Modified from Mr Wu's original by Dave, June 2013
--
-------------------------------------------------------------------------------
-- Company: EDF Boston University
-- Engineer: Shouxiang Wu
--
-- Create Date: 14:53:20 05/24/2010
-- Design Name:
-- Module Name: TTC_decoder - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- TTC Hamming encoding
-- hmg[0] = d[0]^d[1]^d[2]^d[3];
-- hmg[1] = d[0]^d[4]^d[5]^d[6];
-- hmg[2] = d[1]^d[2]^d[4]^d[5]^d[7];
-- hmg[3] = d[1]^d[3]^d[4]^d[6]^d[7];
-- hmg[4] = d[0]^d[2]^d[3]^d[5]^d[6]^d[7];
--
-- As no detailed timing of TTCrx chip is available, L1A may need to add
-- several clocks of delay pending test results -- May 27 2010
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.std_logic_misc.all;
library UNISIM;
use UNISIM.VComponents.all;
entity ttc_decoder is
port(
ttc_clk: in std_logic;
ttc_data: in std_logic_vector(1 downto 0);
l1accept: out std_logic;
brcststr: out std_logic;
brcst: out std_logic_vector(7 downto 0);
sinerrstr: out std_logic;
dberrstr: out std_logic
);
end ttc_decoder;
architecture Behavioral of TTC_decoder is
signal sr : std_logic_vector(12 downto 0) := (others => '0');
signal rec_cntr : std_logic_vector(5 downto 0) := (others => '0');
signal rec_cmd : std_logic := '0';
signal FMT : std_logic := '0';
signal brcst_str : std_logic_vector(3 downto 0) := (others => '0');
signal brcst_data : std_logic_vector(7 downto 0) := (others => '0');
signal brcst_syn : std_logic_vector(4 downto 0) := (others => '0');
signal frame_err : std_logic := '0';
signal single_err : std_logic := '0';
signal double_err : std_logic := '0';
begin
process(TTC_CLK)
begin
if(TTC_CLK'event and TTC_CLK = '1')then
l1accept <= TTC_data(0);
if(rec_cmd = '0')then
rec_cntr <= (others => '0');
else
rec_cntr <= rec_cntr + 1;
end if;
if(rec_cntr(5 downto 3) = "101" or (FMT = '0' and rec_cntr(3 downto 0) = x"d"))then
rec_cmd <= '0';
elsif(TTC_data(1) = '0')then
rec_cmd <= '1';
end if;
if(or_reduce(rec_cntr) = '0')then
FMT <= TTC_data(1);
end if;
sr <= sr(11 downto 0) & TTC_data(1);
if(FMT = '0' and rec_cntr(3 downto 0) = x"e")then
brcst_data <= sr(12 downto 5);
brcst_syn(0) <= sr(0) xor sr(5) xor sr(6) xor sr(7) xor sr(8);
brcst_syn(1) <= sr(1) xor sr(5) xor sr(9) xor sr(10) xor sr(11);
brcst_syn(2) <= sr(2) xor sr(6) xor sr(7) xor sr(9) xor sr(10) xor sr(12);
brcst_syn(3) <= sr(3) xor sr(6) xor sr(8) xor sr(9) xor sr(11) xor sr(12);
brcst_syn(4) <= xor_reduce(sr);
frame_err <= not TTC_data(1);
brcst_str(0) <= '1';
else
brcst_str(0) <= '0';
end if;
single_err <= xor_reduce(brcst_syn) and not frame_err;
if((or_reduce(brcst_syn) = '1' and xor_reduce(brcst_syn) = '0') or frame_err = '1')then
double_err <= '1';
else
double_err <= '0';
end if;
SinErrStr <= single_err and brcst_str(1);
DbErrStr <= double_err and brcst_str(1);
brcst_str(2) <= brcst_str(1) and not double_err;
brcst <= brcst_data;
BrcstStr <= brcst_str(2) and or_reduce(brcst_data);
end if;
end process;
i_brcst_str1 : SRL16E
port map (
Q => brcst_str(1), -- SRL data output
A0 => '0', -- Select[0] input
A1 => '1', -- Select[1] input
A2 => '0', -- Select[2] input
A3 => '0', -- Select[3] input
CE => '1', -- Clock enable input
CLK => TTC_CLK, -- Clock input
D => brcst_str(0) -- SRL data input
);
end Behavioral;
ttc_del.vhd 0000664 0000000 0000000 00000001652 13132146003 0032405 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_del
--
-- Fine delay element for incoming TTC data
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity ttc_del is
port(
i: in std_logic;
o: out std_logic;
refclk: in std_logic;
rst: in std_logic;
rdy: out std_logic;
clk: in std_logic;
inc: in std_logic
);
end ttc_del;
architecture rtl of ttc_del is
attribute IODELAY_GROUP: string;
attribute IODELAY_GROUP of ctrl: label is "ttc_del";
attribute IODELAY_GROUP of idel: label is "ttc_del";
begin
ctrl: IDELAYCTRL
port map(
refclk => refclk,
rst => rst,
rdy => rdy
);
idel: IDELAYE2
generic map(IDELAY_TYPE => "VARIABLE")
port map(
c => clk,
regrst => '0',
ld => rst,
ce => inc,
inc => '1',
cinvctrl => '0',
cntvaluein => "00000",
idatain => i,
datain => '0',
ldpipeen => '0',
dataout => o,
cntvalueout => open
);
end rtl;
ttc_del_v6.vhd 0000664 0000000 0000000 00000001667 13132146003 0033026 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_del
--
-- Fine delay element for incoming TTC data
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity ttc_del is
port(
i: in std_logic;
o: out std_logic;
refclk: in std_logic;
rst: in std_logic;
rdy: out std_logic;
clk: in std_logic;
inc: in std_logic
);
end ttc_del;
architecture rtl of ttc_del is
attribute IODELAY_GROUP: string;
attribute IODELAY_GROUP of ctrl: label is "ttc_del";
attribute IODELAY_GROUP of idel: label is "ttc_del";
begin
ctrl: IDELAYCTRL
port map(
refclk => refclk,
rst => rst,
rdy => rdy
);
idel: IODELAYE1
generic map(IDELAY_TYPE => "VARIABLE")
port map(
c => clk,
t => '0',
rst => rst,
ce => inc,
inc => '1',
cinvctrl => '0',
cntvaluein => "00000",
clkin => '0',
idatain => i,
datain => '0',
odatain => '0',
dataout => o,
cntvalueout => open
);
end rtl;
ttc_history.vhd 0000664 0000000 0000000 00000004141 13132146003 0033336 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_history
--
-- Stores the history of TTC A/B commands for debugging
--
-- FIFO is cleared and then filled when 'go' is asserted
--
-- Dave Newbold, July 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.mp7_ttc_decl.all;
entity ttc_history is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
ttc_clk: in std_logic; -- TTC clk40
go: in std_logic; -- Start signal (ttc_clk domain)
mask_bc0: in std_logic;
mask_l1a: in std_logic;
ttc_l1a: in std_logic;
ttc_cmd: in ttc_cmd_t;
ttc_bx: in bctr_t;
ttc_orb: in eoctr_t
);
end ttc_history;
architecture rtl of ttc_history is
COMPONENT ttc_history_fifo
PORT (
rst : IN STD_LOGIC;
wr_clk : IN STD_LOGIC;
rd_clk : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(40 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
dout : OUT STD_LOGIC_VECTOR(40 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC
);
END COMPONENT;
signal full, valid, wen, ren, ipb_ren, fifo_rst, go_d: std_logic;
signal d, q: std_logic_vector(40 downto 0);
begin
process(ttc_clk)
begin
if rising_edge(ttc_clk) then
go_d <= go;
end if;
end process;
fifo_rst <= rst or (go and not go_d); -- CDC (unrelated clocks, async)
d(3 downto 0) <= ttc_cmd;
d(15 downto 4) <= ttc_bx;
d(39 downto 16) <= ttc_orb;
d(40) <= ttc_l1a;
wen <= '1' when ((ttc_l1a = '1' and mask_l1a = '0') or (ttc_cmd /= (ttc_cmd'range => '0') and not (ttc_cmd = TTC_BCMD_BC0 and mask_bc0 = '1')))
and go = '1' else '0';
fifo: ttc_history_fifo
port map(
rst => fifo_rst,
wr_clk => ttc_clk,
rd_clk => clk,
din => d,
wr_en => wen,
rd_en => ren,
dout => q,
full => full,
empty => open,
valid => valid
);
ipb_ren <= ipb_in.ipb_strobe and not ipb_in.ipb_write;
ren <= ipb_ren and ipb_in.ipb_addr(0);
ipb_out.ipb_rdata <= X"00" & q(39 downto 16) when ipb_in.ipb_addr(0) = '1' else
valid & "000" & X"00" & "000" & q(40) & q(15 downto 4) & q(3 downto 0);
ipb_out.ipb_ack <= ipb_ren;
ipb_out.ipb_err <= '0';
end rtl;
ttc_history_new.vhd 0000664 0000000 0000000 00000002461 13132146003 0034212 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/hdl -- ttc_history
--
-- Stores the history of TTC A/B commands for debugging
--
-- mask bits are:
-- 0: mask bc0
-- 1: mask l1a
--
-- Dave Newbold, August 2015
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.mp7_ttc_decl.all;
entity ttc_history_new is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
ttc_clk: in std_logic; -- TTC clk40
ttc_rst: in std_logic;
ttc_l1a: in std_logic;
ttc_cmd: in ttc_cmd_t;
ttc_bx: in bctr_t;
ttc_orb: in eoctr_t;
ttc_evt: in eoctr_t
);
end ttc_history_new;
architecture rtl of ttc_history_new is
signal mask: std_logic_vector(7 downto 0);
signal state: std_logic_vector(15 downto 0);
signal strobe: std_logic;
begin
state_buf: entity work.state_history
port map(
clk => clk,
rst => rst,
ipb_in => ipb_in,
ipb_out => ipb_out,
ttc_clk => ttc_clk,
ttc_rst => ttc_rst,
ttc_bx => ttc_bx,
ttc_orb => ttc_orb,
ttc_evt => ttc_evt,
-- mask_ctrl => mask,
state => state
-- strobe => strobe
);
state <= X"0" & ttc_l1a & "000" & ttc_cmd; -- should be indepedent of ttc_cmd_length; fix later
strobe <= '1' when (ttc_l1a = '1' and mask(1) = '0') or (ttc_cmd /= TTC_BCMD_NULL and not (ttc_cmd = TTC_BCMD_BC0 and mask(0) = '1')) else '0';
end rtl;
sim_hdl/ 0000775 0000000 0000000 00000000000 13132146003 0031130 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware mp7_ttc_sim.vhd 0000664 0000000 0000000 00000017160 13132146003 0034065 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/sim_hdl -- mp7_ttc
--
-- TTC decoder, counters, LHC clock distribution, etc
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_mp7_ttc.all;
use work.mp7_ttc_decl.all;
use work.top_decl.all;
entity mp7_ttc_sim is
port(
clk: in std_logic; -- ipbus clock & rst
rst: in std_logic;
mmcm_rst: in std_logic; -- clock domain full reset
sel: in std_logic; -- TTC clock / internal clock select
lock: out std_logic; -- MMCM lock status
stop: out std_logic; -- MMCM clock status
ipb_in: in ipb_wbus; -- ipbus
ipb_out: out ipb_rbus;
clk40: out std_logic; -- clock outputs
rsto40: out std_logic; -- clock domain reset outputs
clk_p: out std_logic;
rst_p: out std_logic;
clk_payload: out std_logic;
rst_payload: out std_logic;
ttc_cmd: out ttc_cmd_t; -- TTC b command output
ttc_cmd_dist: out ttc_cmd_t;
ttc_l1a: out std_logic; -- L1A output
ttc_l1a_flag: out std_logic; -- L1A qualifier output
l1a_throttle: in std_logic;
dist_lock: in std_logic;
bunch_ctr: out bctr_t;
evt_ctr: in eoctr_t;
orb_ctr: out eoctr_t;
oc_flag: out std_logic;
ec_flag: out std_logic;
tmt_sync: out tmt_sync_t;
monclk: in std_logic_vector(2 downto 0) -- clock monitoring inputs from MGTs
);
end mp7_ttc_sim;
architecture rtl of mp7_ttc_sim is
signal clk40_i, rst40_i, clk40_div, rsti, clk40_a, rst40_a: std_logic;
signal clk80_i, rst80_i, clk160_i, rst160_i, clk240_i, rst240_i: std_logic;
signal l1a, l1a_ttc, l1a_int, l1a_del, l1a_pend, cmd_bx, cmd_pend, l1a_issue, cmd_issue: std_logic;
signal psok, bc0_fr, ctr_clr, err_rst: std_logic;
signal cmd, cmd_ttc, cmd_del: ttc_cmd_t;
signal bunch_ctr_i: bctr_t;
signal req_bx: unsigned(bctr_t'range);
signal orb_ctr_i: eoctr_t;
signal sinerr_ctr, dberr_ctr: std_logic_vector(15 downto 0);
signal stat: ipb_reg_v(3 downto 0);
signal ctrl: ipb_reg_v(1 downto 0);
signal stb: std_logic_vector(1 downto 0);
signal bc0_lock: std_logic;
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal tmt_ctrl: ipb_reg_v(0 downto 0);
signal wtf: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_mp7_ttc(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- TTC control registers
reg: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 2,
N_STAT => 4
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CSR),
ipb_out => ipbr(N_SLV_CSR),
slv_clk => clk40_a,
d => stat,
q => ctrl,
stb => stb
);
-- MMCM for clock multiplication / phase adjustment
rsti <= rst or ctrl(0)(2); -- CDC, unrelated clocks
clocks: entity work.ttc_clocks_sim
port map(
clko_40 => clk40_i,
clko_80 => clk80_i,
clko_160 => clk160_i,
clko_240 => clk240_i,
rsto_40 => rst40_i,
rsto_80 => rst80_i,
rsto_160 => rst160_i,
rsto_240 => rst240_i,
stopped => stop,
locked => lock,
rst_mmcm => mmcm_rst,
rsti => rsti
);
clk40_a <= clk40_i; -- Needed to make sure delta delays line up in simulation!
rst40_a <= rst40_i;
clk40 <= clk40_i;
rsto40 <= rst40_i;
with CLOCK_RATIO select clk_p <=
clk40_i when 1,
clk80_i when 2,
clk160_i when 4,
clk240_i when others;
with CLOCK_RATIO select rst_p <=
rst40_i when 1,
rst80_i when 2,
rst160_i when 4,
rst240_i when others;
with CLOCK_RATIO_PAYLOAD select clk_payload <=
clk40_i when 1,
clk80_i when 2,
clk160_i when 4,
clk240_i when others;
with CLOCK_RATIO_PAYLOAD select rst_payload <=
rst40_i when 1,
rst80_i when 2,
rst160_i when 4,
rst240_i when others;
-- TTC protocol decoder
err_rst <= ctrl(0)(1) and stb(0);
ttccmd: entity work.ttc_cmd
generic map(
LHC_BUNCH_COUNT => LHC_BUNCH_COUNT
)
port map(
clk => clk40_a,
rst => rst40_a,
sclk => '0',
ttc_in_p => '0',
ttc_in_n => '1',
l1a => l1a_ttc,
cmd => cmd_ttc,
sinerr_ctr => sinerr_ctr,
dberr_ctr => dberr_ctr,
c_delay => ctrl(1)(20 downto 16),
en_ttc => ctrl(0)(0),
err_rst => err_rst
);
-- L1A generation
l1agen: entity work.l1a_gen
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_L1_GEN),
ipb_out => ipbr(N_SLV_L1_GEN),
tclk => clk40_a,
trst => rst40_a,
l1a => l1a_int
);
l1a <= l1a_ttc or (l1a_int and not (ctrl(0)(8) and l1a_throttle)) or (l1a_pend and (cmd_bx or not ctrl(0)(10)) ); -- Note that internal throttle only applies to random trigger source
l1a_issue <= l1a and not l1a_ttc and not l1a_int;
-- TTC command generation
req_bx <= unsigned(ctrl(0)(23 downto 12)) - TTC_DEL - 1 when unsigned(ctrl(0)(23 downto 12)) > TTC_DEL else LHC_BUNCH_COUNT + unsigned(ctrl(0)(23 downto 12)) - TTC_DEL - 1;
cmd_bx <= '1' when std_logic_vector(req_bx) = bunch_ctr_i else '0';
process(cmd_ttc, bc0_fr, cmd_pend, cmd_bx, ctrl(0)(10))
begin
cmd_issue <= '0';
if cmd_ttc /= TTC_BCMD_NULL then
cmd <= cmd_ttc;
elsif bc0_fr = '1' then
cmd <= TTC_BCMD_BC0;
elsif cmd_pend = '1' and (cmd_bx = '1' or ctrl(0)(10) = '0') then
cmd <= ctrl(0)(31 downto 24);
cmd_issue <= '1';
else
cmd <= TTC_BCMD_NULL;
end if;
end process;
process(clk40_a)
begin
if rising_edge(clk40_a) then
cmd_pend <= (cmd_pend or (ctrl(0)(9) and stb(0))) and not (rst40_a or cmd_issue);
l1a_pend <= (l1a_pend or (ctrl(0)(7) and stb(0))) and not (rst40_a or l1a_issue);
ttc_cmd_dist <= cmd;
end if;
end process;
-- Counters
ctr_clr <= ctrl(0)(6) and stb(0);
ttcctr: entity work.ttc_ctrs
port map(
clk => clk40_a,
rst => rst40_a,
ttc_cmd => cmd,
l1a => l1a,
clr => '0',
en_int_bc0 => ctrl(0)(3),
bc0_lock => bc0_lock,
bc0_fr => bc0_fr,
ttc_cmd_out => cmd_del,
l1a_out => l1a_del,
bunch_ctr => bunch_ctr_i,
orb_ctr => orb_ctr_i
);
ttc_cmd <= cmd_del;
ttc_l1a <= l1a_del;
bunch_ctr <= bunch_ctr_i;
orb_ctr <= orb_ctr_i;
oc_flag <= '1' when orb_ctr_i(13 downto 0) = (13 downto 0 => '0') and bc0_lock = '1' else '0';
ec_flag <= '1' when evt_ctr(16 downto 0) = (16 downto 0 => '0') else '0';
-- Status reg
stat(0) <= std_logic_vector(to_unsigned(LHC_BUNCH_COUNT, 12)) & (l1a_pend or cmd_pend) & '1' & dist_lock & bc0_lock & X"0" & bunch_ctr_i;
stat(1) <= evt_ctr;
stat(2) <= orb_ctr_i;
stat(3) <= dberr_ctr & sinerr_ctr;
-- clk40 frequency monitoring
div: entity work.freq_ctr_div
port map(
clk(0) => clk40_a,
clkdiv(0) => clk40_div
);
-- Clock frequency monitor
ctr: entity work.freq_ctr
generic map(
N_CLK => 4
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_FREQ),
ipb_out => ipbr(N_SLV_FREQ),
clkdiv(0) => clk40_div,
clkdiv(3 downto 1) => monclk
);
-- TTC history buffer
hist: entity work.ttc_history_new
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_HIST),
ipb_out => ipbr(N_SLV_HIST),
ttc_clk => clk40_a,
ttc_rst => rst40_a,
ttc_l1a => l1a_del,
ttc_cmd => cmd_del,
ttc_bx => bunch_ctr_i,
ttc_orb => orb_ctr_i,
ttc_evt => evt_ctr
);
-- Command counters
cmdctrs: entity work.ttc_cmd_ctrs
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CMD_CTRS),
ipb_out => ipbr(N_SLV_CMD_CTRS),
ttc_clk => clk40_a,
clr => ctr_clr,
ttc_cmd => cmd_del
);
-- TMT stuff
tmt: entity work.tmt_sync
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_TMT),
ipb_out => ipbr(N_SLV_TMT),
ttc_clk => clk40_a,
bctr => bunch_ctr_i,
tmt_l1a_sync => ttc_l1a_flag,
tmt_pkt_sync => tmt_sync(0)
);
end rtl;
ttc_clocks_sim.vhd 0000664 0000000 0000000 00000001722 13132146003 0034635 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/mp7_ttc/firmware/sim_hdl -- ttc_clocks
--
-- Clock generation for LHC clocks
--
-- Dave Newbold, June 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ttc_clocks_sim is
port(
clko_40: out std_logic;
clko_80: out std_logic;
clko_160: out std_logic;
clko_240: out std_logic;
rsto_40: out std_logic;
rsto_80: out std_logic;
rsto_160: out std_logic;
rsto_240: out std_logic;
stopped: out std_logic;
locked: out std_logic;
rst_mmcm: in std_logic;
rsti: in std_logic
);
end ttc_clocks_sim;
architecture rtl of ttc_clocks_sim is
signal clk40, clk80, clk160, clk240: std_logic := '1';
begin
clk40 <= not clk40 after 12 ns;
clk80 <= not clk80 after 6 ns;
clk160 <= not clk160 after 3 ns;
clk240 <= not clk240 after 2 ns;
clko_40 <= clk40;
clko_80 <= clk80;
clko_160 <= clk160;
clko_240 <= clk240;
rsto_40 <= rsti or rst_mmcm;
rsto_80 <= rsti or rst_mmcm;
rsto_160 <= rsti or rst_mmcm;
rsto_240 <= rsti or rst_mmcm;
stopped <= '0';
locked <= '1';
end rtl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/ 0000775 0000000 0000000 00000000000 13132146003 0025511 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table/ 0000775 0000000 0000000 00000000000 13132146003 0027572 5 ustar 00root root 0000000 0000000 sc_chan.xml 0000664 0000000 0000000 00000002714 13132146003 0031637 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_chan_standalone.xml 0000664 0000000 0000000 00000001112 13132146003 0034036 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_daq.xml 0000664 0000000 0000000 00000000763 13132146003 0031475 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_fake.xml 0000664 0000000 0000000 00000001276 13132146003 0031636 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_io.xml 0000664 0000000 0000000 00000001473 13132146003 0031336 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_io_64chan.xml 0000664 0000000 0000000 00000001025 13132146003 0032472 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_roc.xml 0000664 0000000 0000000 00000001300 13132146003 0031477 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_seq.xml 0000664 0000000 0000000 00000001161 13132146003 0031511 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_timing.xml 0000664 0000000 0000000 00000001725 13132146003 0032216 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
sc_trig.xml 0000664 0000000 0000000 00000002035 13132146003 0031667 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/ 0000775 0000000 0000000 00000000000 13132146003 0027325 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg/ 0000775 0000000 0000000 00000000000 13132146003 0030064 5 ustar 00root root 0000000 0000000 sc_chan.dep 0000664 0000000 0000000 00000000704 13132146003 0032076 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_channels.vhd sc_chan.vhd sc_input_serdes.vhd sc_chan_buf.vhd sc_derand.vhd
src sc_chan_trig.vhd sc_ctrig_npeaks.vhd sc_ctrig_tot.vhd sc_ctrig_window.vhd sc_ctrig_thresh.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_ported_dpram.vhd
src ipbus_decode_sc_chan.vhd
addrtab -t sc_chan.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd ipbus_reg_types.vhd
sc_chan_standalone.dep 0000664 0000000 0000000 00000000665 13132146003 0034314 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_channels_standalone.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src sc_chan_standalone.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_sc_chan_standalone.vhd
addrtab -t sc_chan_standalone.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
src sc_input_serdes.vhd sc_cap_fifo_16.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_daq.dep 0000664 0000000 0000000 00000000346 13132146003 0031734 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_daq.vhd
src ipbus_decode_sc_daq.vhd
addrtab -t sc_daq.xml
src sc_rtrig.vhd
include sc_timing.dep sc_fake.dep sc_chan.dep sc_trig.dep sc_trig_link.dep sc_roc.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
sc_daq_sim.dep 0000664 0000000 0000000 00000000352 13132146003 0032601 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_daq.vhd
src ipbus_decode_sc_daq.vhd
addrtab -t sc_daq.xml
src sc_rtrig.vhd
include sc_timing_sim.dep sc_fake.dep sc_chan.dep sc_trig.dep sc_trig_link.dep sc_roc.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
sc_fake.dep 0000664 0000000 0000000 00000000404 13132146003 0032070 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_fake.vhd
addrtab -t sc_fake.xml
src ipbus_decode_sc_fake.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_v.vhd
include -c ipbus-firmware:components/ipbus_slaves syncreg_v.dep
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_io.dep 0000664 0000000 0000000 00000000715 13132146003 0031576 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_io.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_sc_io.vhd
addrtab -t sc_io.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
include -c ipbus-firmware:components/opencores_i2c
include -c ipbus-firmware:components/opencores_spi
src -c components/mp7_ttc freq_ctr.vhd freq_ctr_div.vhd
addrtab -c components/mp7_ttc freq_ctr.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_io_64chan.dep 0000664 0000000 0000000 00000000742 13132146003 0032741 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_io_64chan.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_sc_io_64chan.vhd
addrtab -t sc_io_64chan.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
include -c ipbus-firmware:components/opencores_i2c
include -c ipbus-firmware:components/opencores_spi
src -c components/mp7_ttc freq_ctr.vhd freq_ctr_div.vhd
addrtab -c components/mp7_ttc freq_ctr.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_roc.dep 0000664 0000000 0000000 00000000471 13132146003 0031751 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_roc.vhd occ_histo_unscaled.vhd sc_derand.vhd
src -c ipbus-firmware:components/ipbus_util big_fifo_36.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_sc_roc.vhd
addrtab -t sc_roc.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd ipbus_reg_types.vhd
sc_seq.dep 0000664 0000000 0000000 00000000420 13132146003 0031750 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_seq.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_ported_dpram.vhd
include -c ipbus-firmware:components/ipbus_slaves ipbus_ctrs_ported.dep
src ipbus_decode_sc_seq.vhd
addrtab -t sc_seq.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_timing.dep 0000664 0000000 0000000 00000000433 13132146003 0032453 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_timing.vhd sc_timing_startup.vhd
addrtab sc_timing.xml
src sc_clocks.vhd
include -c ipbus-firmware:components/ipbus_slaves syncreg_v.dep
src -c components/mp7_ttc rng_wrapper.vhd rng_n1024_r32_t5_k32_s1c48.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_timing_sim.dep 0000664 0000000 0000000 00000000452 13132146003 0033324 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_timing.vhd sc_timing_startup.vhd
addrtab sc_timing.xml
src ../sim_hdl/sc_clocks_sim.vhd
include -c ipbus-firmware:components/ipbus_slaves syncreg_v.dep
src -c components/mp7_ttc rng_wrapper.vhd rng_n1024_r32_t5_k32_s1c48.vhd
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
sc_trig.dep 0000664 0000000 0000000 00000000610 13132146003 0032126 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_trig.vhd sc_local_trig.vhd sc_zs_sel.vhd sc_trig_ro_block.vhd sc_deadtime_mon.vhd
src sc_trig_gen.vhd sc_trig_gen_or.vhd
include sc_seq.dep
src ipbus_decode_sc_trig.vhd
addrtab -t sc_trig.xml
include -c ipbus-firmware:components/ipbus_slaves syncreg_v.dep
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
sc_trig_link.dep 0000664 0000000 0000000 00000000025 13132146003 0033143 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/cfg src sc_trig_link.vhd
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl/ 0000775 0000000 0000000 00000000000 13132146003 0030074 5 ustar 00root root 0000000 0000000 ipbus_decode_sc_chan.vhd 0000664 0000000 0000000 00000004111 13132146003 0034620 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_chan is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_chan(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Thu Jun 15 20:45:58 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_BUF: integer := 1;
constant N_SLV_ZS_THRESH: integer := 2;
constant N_SLV_TRIG_THRESH: integer := 3;
constant N_SLAVES: integer := 4;
-- END automatically generated VHDL
end ipbus_decode_sc_chan;
package body ipbus_decode_sc_chan is
function ipbus_sel_sc_chan(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Thu Jun 15 20:45:58 2017
if std_match(addr, "----------------------------000-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x0000000e
elsif std_match(addr, "----------------------------001-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_BUF, IPBUS_SEL_WIDTH)); -- buf / base 0x00000002 / mask 0x0000000e
elsif std_match(addr, "----------------------------01--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_ZS_THRESH, IPBUS_SEL_WIDTH)); -- zs_thresh / base 0x00000004 / mask 0x0000000c
elsif std_match(addr, "----------------------------10--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TRIG_THRESH, IPBUS_SEL_WIDTH)); -- trig_thresh / base 0x00000008 / mask 0x0000000c
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_chan;
end ipbus_decode_sc_chan;
ipbus_decode_sc_chan_standalone.vhd 0000664 0000000 0000000 00000003305 13132146003 0037034 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_chan_standalone is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_chan_standalone(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Wed Feb 17 16:06:58 2016
constant N_SLV_CSR: integer := 0;
constant N_SLV_FIFO: integer := 1;
constant N_SLAVES: integer := 2;
-- END automatically generated VHDL
end ipbus_decode_sc_chan_standalone;
package body ipbus_decode_sc_chan_standalone is
function ipbus_sel_sc_chan_standalone(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Wed Feb 17 16:06:58 2016
if std_match(addr, "------------------------------0-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000002
elsif std_match(addr, "------------------------------1-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FIFO, IPBUS_SEL_WIDTH)); -- fifo / base 0x00000002 / mask 0x00000002
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_chan_standalone;
end ipbus_decode_sc_chan_standalone;
ipbus_decode_sc_daq.vhd 0000664 0000000 0000000 00000005265 13132146003 0034467 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_daq is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_daq(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Thu Jun 15 20:45:58 2017
constant N_SLV_CHAN: integer := 0;
constant N_SLV_TIMING: integer := 1;
constant N_SLV_FAKE: integer := 2;
constant N_SLV_RTRIG: integer := 3;
constant N_SLV_TLINK: integer := 4;
constant N_SLV_TRIG: integer := 5;
constant N_SLV_ROC: integer := 6;
constant N_SLAVES: integer := 7;
-- END automatically generated VHDL
end ipbus_decode_sc_daq;
package body ipbus_decode_sc_daq is
function ipbus_sel_sc_daq(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Thu Jun 15 20:45:58 2017
if std_match(addr, "-------------------------000----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CHAN, IPBUS_SEL_WIDTH)); -- chan / base 0x00000000 / mask 0x00000070
elsif std_match(addr, "-------------------------0010---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TIMING, IPBUS_SEL_WIDTH)); -- timing / base 0x00000010 / mask 0x00000078
elsif std_match(addr, "-------------------------0100---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FAKE, IPBUS_SEL_WIDTH)); -- fake / base 0x00000020 / mask 0x00000078
elsif std_match(addr, "-------------------------0101---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_RTRIG, IPBUS_SEL_WIDTH)); -- rtrig / base 0x00000028 / mask 0x00000078
elsif std_match(addr, "-------------------------0110---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TLINK, IPBUS_SEL_WIDTH)); -- tlink / base 0x00000030 / mask 0x00000078
elsif std_match(addr, "-------------------------10-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TRIG, IPBUS_SEL_WIDTH)); -- trig / base 0x00000040 / mask 0x00000060
elsif std_match(addr, "-------------------------11-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_ROC, IPBUS_SEL_WIDTH)); -- roc / base 0x00000060 / mask 0x00000060
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_daq;
end ipbus_decode_sc_daq;
ipbus_decode_sc_fake.vhd 0000664 0000000 0000000 00000003201 13132146003 0034614 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_fake is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_fake(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Mon Jun 5 23:01:57 2017
constant N_SLV_CTRL: integer := 0;
constant N_SLV_PARAMS: integer := 1;
constant N_SLAVES: integer := 2;
-- END automatically generated VHDL
end ipbus_decode_sc_fake;
package body ipbus_decode_sc_fake is
function ipbus_sel_sc_fake(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Mon Jun 5 23:01:57 2017
if std_match(addr, "------------------------------0-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CTRL, IPBUS_SEL_WIDTH)); -- ctrl / base 0x00000000 / mask 0x00000002
elsif std_match(addr, "------------------------------1-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_PARAMS, IPBUS_SEL_WIDTH)); -- params / base 0x00000002 / mask 0x00000002
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_fake;
end ipbus_decode_sc_fake;
ipbus_decode_sc_io.vhd 0000664 0000000 0000000 00000004434 13132146003 0034326 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_io is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_io(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_FREQ_CTR: integer := 1;
constant N_SLV_CLOCK_I2C: integer := 2;
constant N_SLV_SPI: integer := 3;
constant N_SLV_ANALOG_I2C: integer := 4;
constant N_SLAVES: integer := 5;
-- END automatically generated VHDL
end ipbus_decode_sc_io;
package body ipbus_decode_sc_io is
function ipbus_sel_sc_io(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
if std_match(addr, "---------------------------000--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x0000001c
elsif std_match(addr, "---------------------------001--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FREQ_CTR, IPBUS_SEL_WIDTH)); -- freq_ctr / base 0x00000004 / mask 0x0000001c
elsif std_match(addr, "---------------------------01---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CLOCK_I2C, IPBUS_SEL_WIDTH)); -- clock_i2c / base 0x00000008 / mask 0x00000018
elsif std_match(addr, "---------------------------10---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_SPI, IPBUS_SEL_WIDTH)); -- spi / base 0x00000010 / mask 0x00000018
elsif std_match(addr, "---------------------------11---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_ANALOG_I2C, IPBUS_SEL_WIDTH)); -- analog_i2c / base 0x00000018 / mask 0x00000018
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_io;
end ipbus_decode_sc_io;
ipbus_decode_sc_io_64chan.vhd 0000664 0000000 0000000 00000004121 13132146003 0035462 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_io_64chan is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_io_64chan(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Fri Mar 17 13:57:18 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_FREQ_CTR: integer := 1;
constant N_SLV_I2C: integer := 2;
constant N_SLV_SPI: integer := 3;
constant N_SLAVES: integer := 4;
-- END automatically generated VHDL
end ipbus_decode_sc_io_64chan;
package body ipbus_decode_sc_io_64chan is
function ipbus_sel_sc_io_64chan(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Fri Mar 17 13:57:18 2017
if std_match(addr, "---------------------------000--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x0000001c
elsif std_match(addr, "---------------------------001--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FREQ_CTR, IPBUS_SEL_WIDTH)); -- freq_ctr / base 0x00000004 / mask 0x0000001c
elsif std_match(addr, "---------------------------01---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_I2C, IPBUS_SEL_WIDTH)); -- i2c / base 0x00000008 / mask 0x00000018
elsif std_match(addr, "---------------------------10---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_SPI, IPBUS_SEL_WIDTH)); -- spi / base 0x00000010 / mask 0x00000018
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_io_64chan;
end ipbus_decode_sc_io_64chan;
ipbus_decode_sc_roc.vhd 0000664 0000000 0000000 00000003503 13132146003 0034476 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_roc is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_roc(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_BUF: integer := 1;
constant N_SLV_OCC: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_sc_roc;
package body ipbus_decode_sc_roc is
function ipbus_sel_sc_roc(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
if std_match(addr, "---------------------------00---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000018
elsif std_match(addr, "---------------------------01---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_BUF, IPBUS_SEL_WIDTH)); -- buf / base 0x00000008 / mask 0x00000018
elsif std_match(addr, "---------------------------10---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_OCC, IPBUS_SEL_WIDTH)); -- occ / base 0x00000010 / mask 0x00000018
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_roc;
end ipbus_decode_sc_roc;
ipbus_decode_sc_seq.vhd 0000664 0000000 0000000 00000003511 13132146003 0034502 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_seq is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_seq(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
constant N_SLV_BUF: integer := 0;
constant N_SLV_CONF: integer := 1;
constant N_SLV_CTRS: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_sc_seq;
package body ipbus_decode_sc_seq is
function ipbus_sel_sc_seq(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Fri Mar 17 13:58:05 2017
if std_match(addr, "-----------------------------00-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_BUF, IPBUS_SEL_WIDTH)); -- buf / base 0x00000008 / mask 0x00000006
elsif std_match(addr, "-----------------------------01-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CONF, IPBUS_SEL_WIDTH)); -- conf / base 0x0000000a / mask 0x00000006
elsif std_match(addr, "-----------------------------10-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CTRS, IPBUS_SEL_WIDTH)); -- ctrs / base 0x0000000c / mask 0x00000006
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_seq;
end ipbus_decode_sc_seq;
ipbus_decode_sc_trig.vhd 0000664 0000000 0000000 00000004771 13132146003 0034670 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_sc_trig is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_sc_trig(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Fri Jul 14 14:14:53 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_LOC_MASK: integer := 1;
constant N_SLV_ZS_CFG: integer := 2;
constant N_SLV_DTMON: integer := 3;
constant N_SLV_SEQ: integer := 4;
constant N_SLV_CHAN_MASK: integer := 5;
constant N_SLAVES: integer := 6;
-- END automatically generated VHDL
end ipbus_decode_sc_trig;
package body ipbus_decode_sc_trig is
function ipbus_sel_sc_trig(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Fri Jul 14 14:14:53 2017
if std_match(addr, "---------------------------000--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x0000001c
elsif std_match(addr, "---------------------------00100") then
sel := ipbus_sel_t(to_unsigned(N_SLV_LOC_MASK, IPBUS_SEL_WIDTH)); -- loc_mask / base 0x00000004 / mask 0x0000001f
elsif std_match(addr, "---------------------------00101") then
sel := ipbus_sel_t(to_unsigned(N_SLV_ZS_CFG, IPBUS_SEL_WIDTH)); -- zs_cfg / base 0x00000005 / mask 0x0000001f
elsif std_match(addr, "---------------------------0011-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_DTMON, IPBUS_SEL_WIDTH)); -- dtmon / base 0x00000006 / mask 0x0000001e
elsif std_match(addr, "---------------------------01---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_SEQ, IPBUS_SEL_WIDTH)); -- seq / base 0x00000008 / mask 0x00000018
elsif std_match(addr, "---------------------------1----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CHAN_MASK, IPBUS_SEL_WIDTH)); -- chan_mask / base 0x00000010 / mask 0x00000010
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_sc_trig;
end ipbus_decode_sc_trig;
occ_histo.vhd 0000664 0000000 0000000 00000002736 13132146003 0032502 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- occ_histo
--
-- A simple histogrammer of buffer occupancy
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
entity occ_histo is
generic(
BINS_RADIX: natural := 4; -- Number of bins (0 = 1, 1 = 2, etc)
OCC_WIDTH: natural := 8 -- Occupancy counter width
);
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk_s: in std_logic;
rst_s: in std_logic;
occ: in std_logic_vector(OCC_WIDTH - 1 downto 0);
freeze: in std_logic
);
end occ_histo;
architecture rtl of occ_histo is
type c_array_t is array(2 ** BINS_RADIX - 1 downto 0) of std_logic_vector(7 downto 0);
signal m_array, e_array: c_array_t;
signal sel: integer range 2 ** BINS_RADIX - 1 downto 0 := 0;
begin
-- ipbus
sel <= to_integer(unsigned(ipb_in.ipb_addr(BINS_RADIX - 1 downto 0)));
ipb_out.ipb_rdata <= X"0000" & std_logic_vector(e_array(sel)) & std_logic_vector(m_array(sel)); -- CDC
ipb_out.ipb_ack <= ipb_in.ipb_strobe;
ipb_out.ipb_err <= '0';
-- Bins
bgen: for i in 2 ** BINS_RADIX - 1 downto 0 generate
signal inc: std_logic;
begin
inc <= '1' when to_integer(unsigned(occ(OCC_WIDTH - 1 downto OCC_WIDTH - BINS_RADIX - 1))) = i and freeze = '0' else '0';
sctr: entity work.scaled_ctr
port map(
clk => clk_s,
rst => rst_s,
inc => inc,
m => m_array(i),
e => e_array(i)
);
end generate;
end rtl;
occ_histo_unscaled.vhd 0000664 0000000 0000000 00000002624 13132146003 0034354 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- occ_histo
--
-- A simple histogrammer of buffer occupancy
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
entity occ_histo_unscaled is
generic(
BINS_RADIX: natural := 4; -- Number of bins (0 = 1, 1 = 2, etc)
OCC_WIDTH: natural := 8 -- Occupancy counter width
);
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk_s: in std_logic;
rst_s: in std_logic;
occ: in std_logic_vector(OCC_WIDTH - 1 downto 0);
freeze: in std_logic
);
end occ_histo_unscaled;
architecture rtl of occ_histo_unscaled is
type c_t is array(2 ** BINS_RADIX - 1 downto 0) of unsigned(31 downto 0);
signal c: c_t;
signal sel: integer range 2 ** BINS_RADIX - 1 downto 0 := 0;
begin
-- ipbus
sel <= to_integer(unsigned(ipb_in.ipb_addr(BINS_RADIX - 1 downto 0)));
ipb_out.ipb_rdata <= std_logic_vector(c(sel)); -- CDC
ipb_out.ipb_ack <= ipb_in.ipb_strobe;
ipb_out.ipb_err <= '0';
-- Bins
process(clk_s)
begin
if rising_edge(clk_s) then
if rst_s = '1' then
c <= (others => (others => '0'));
else
for i in 2 ** BINS_RADIX - 1 downto 0 loop
if to_integer(unsigned(occ(OCC_WIDTH - 1 downto OCC_WIDTH - BINS_RADIX - 1))) = i and freeze = '0' then
c(i) <= c(i) + 1;
end if;
end loop;
end if;
end if;
end process;
end rtl;
peakcount_directcomparison.vhd 0000664 0000000 0000000 00000005033 13132146003 0036137 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 2 May 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
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 peakcount is
generic(windowlength: natural := 7; -- bits
adc_max: integer := 14 -- bits
);
port( rst: in std_logic;
clk: in std_logic;
data_in: in std_logic_vector(adc_max-1 DOWNTO 0);
threshold: in std_logic_vector(adc_max-1 DOWNTO 0);
npeaks: out std_logic_vector(windowlength-1 DOWNTO 0)
);
end peakcount;
architecture rtl of peakcount is
signal delayed : integer range 0 to (2**adc_max)-1;
signal delayed_two : integer range 0 to (2**adc_max)-1;
signal shiftreg : std_logic_vector((2**windowlength)-2 DOWNTO 0);
signal npeaks_buf : integer range 0 to (2**windowlength)-1;
begin
process(rst,clk)
variable maximum : boolean := False;
variable maximum_start : integer range 0 to 1 := 0;
variable maximum_end : integer range 0 to 1 := 0;
begin
if rst='1' then
npeaks <= (others=>'0');
delayed <= 0;
delayes_two <= 0;
-- shiftreg <= (others => '0');
npeaks_buf <= 0;
elsif rising_edge(clk) then
--------------------------------
-- Find Maximum --
--------------------------------
delayed <= to_integer(unsigned(data_in));
delayed_two<= delayes;
--Conditions
maximum := (delayed > to_integer(unsigned(threshold)))AND (to_integer(unsigned(data_in))<=delayed) AND (delayed_two < delayed); --//1 clock cycle
--------------------------------
-- Count Maxima --
--------------------------------
case maximum is
when False => maximum_start := 0;
shiftreg(0) <= '0';
when True => maximum_start := 1;
shiftreg(0) <= '1';
end case;
case shiftreg((2**windowlength)-2) is
when '0' => maximum_end := 0;
when '1' => maximum_end := 1;
end case;
for i in 1 to ((2**windowlength)-2) loop -- not first element
shiftreg(i) <= shiftreg(i-1);
end loop;
npeaks_buf <= npeaks_buf + maximum_start - maximum_end; --//1 clock cycle
end if;
npeaks <= std_logic_vector(to_unsigned(npeaks_buf,windowlength)); --//1 clock cycle
end process;
end architecture rtl;
sc_cap_fifo_16.vhd 0000664 0000000 0000000 00000002563 13132146003 0033267 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_cap_fifo_16
--
-- Simple ipbus interface to a 16b wide FIFO
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
use work.ipbus.all;
entity sc_cap_fifo_16 is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk_p: in std_logic;
rst_p: in std_logic;
d: in std_logic_vector(15 downto 0);
we: in std_logic;
empty: out std_logic;
full: out std_logic;
frst: in std_logic -- Need at least three cycles long reset pulse
);
end sc_cap_fifo_16;
architecture rtl of sc_cap_fifo_16 is
signal clkn, empty_i, full_i, rden: std_logic;
signal fifo_q: std_logic_vector(63 downto 0);
begin
clkn <= not clk;
fifo: FIFO36E1
generic map(
DATA_WIDTH => 18
)
port map(
di(63 downto 16) => X"000000000000",
di(15 downto 0) => d,
dip => X"00",
do => fifo_q,
empty => empty_i,
full => full_i,
injectdbiterr => '0',
injectsbiterr => '0',
rdclk => clkn,
rden => rden,
regce => '1',
rst => frst,
rstreg => '0',
wrclk => clk_p,
wren => we
);
rden <= ipb_in.ipb_strobe and not ipb_in.ipb_write;
ipb_out.ipb_ack <= ipb_in.ipb_strobe;
ipb_out.ipb_err <= '0';
ipb_out.ipb_rdata <= X"000" & "00" & full_i & empty_i & fifo_q(15 downto 0);
empty <= empty_i;
full <= full_i;
end rtl;
sc_chan.vhd 0000664 0000000 0000000 00000013205 13132146003 0032117 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_chan.vhd
--
-- All the stuff belonging to one input channel
--
-- ctrl_mode: 0 normal; 1 playback; 2 capture; 3 reserved
-- ctrl_src: 0 external; 1 playback buffer; 2 counter; 3 fake data
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
library unisim;
use unisim.VComponents.all;
use work.ipbus.all;
use work.ipbus_decode_sc_chan.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_chan is
generic(
id: integer
);
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
clk280: in std_logic;
d_p: in std_logic;
d_n: in std_logic;
sync_ctrl: in std_logic_vector(3 downto 0);
zs_sel: in std_logic_vector(1 downto 0);
sctr: in std_logic_vector(47 downto 0);
fake: in std_logic_vector(13 downto 0);
nzs_en: in std_logic;
zs_en: in std_logic;
keep: in std_logic;
flush: in std_logic;
err: out std_logic;
veto: out std_logic;
trig: out std_logic_vector(N_CHAN_TRG - 1 downto 0);
clk_dr: in std_logic;
q: out std_logic_vector(31 downto 0);
q_blkend: out std_logic;
q_empty: out std_logic;
ren: in std_logic
);
end sc_chan;
architecture rtl of sc_chan is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(0 downto 0);
signal norm_mode, pb_mode, cap_mode: std_logic;
signal d_in, d_in_i, d_buf: std_logic_vector(13 downto 0);
signal d_c: std_logic_vector(1 downto 0);
signal slip, chan_rst, buf_we, inc: std_logic;
signal ctrl_en_sync, ctrl_en_buf, ctrl_invert: std_logic;
signal ctrl_mode, ctrl_src: std_logic_vector(1 downto 0);
signal cap_full, buf_full, dr_full, dr_warn: std_logic;
signal zs_thresh_v: ipb_reg_v(N_ZS_THRESH - 1 downto 0);
signal zs_sel_i: integer range 2 ** zs_sel'length - 1 downto 0 := 0;
signal zs_thresh: std_logic_vector(13 downto 0);
signal sctr_p: std_logic_vector(11 downto 0);
signal dr_d: std_logic_vector(31 downto 0);
signal ro_en, keep_i, flush_i, err_i, req, blkend, dr_blkend, dr_wen: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_chan(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl
);
ctrl_en_sync <= ctrl(0)(0);
ctrl_en_buf <= ctrl(0)(1);
ctrl_invert <= ctrl(0)(2);
ctrl_mode <= ctrl(0)(5 downto 4);
ctrl_src <= ctrl(0)(7 downto 6);
slip <= sync_ctrl(0) and ctrl_en_sync; -- CDC
chan_rst <= (sync_ctrl(1) and ctrl_en_sync) or rst40; -- CDC
buf_we <= sync_ctrl(2) and ctrl_en_sync; -- CDC
inc <= sync_ctrl(3) and ctrl_en_sync; -- CDC
stat(0) <= X"000000" & "000" & err_i & dr_warn & dr_full & buf_full & cap_full; -- CDC
norm_mode <= '1' when ctrl_mode = "00" else '0';
pb_mode <= '1' when ctrl_mode = "01" else '0';
cap_mode <= '1' when ctrl_mode = "10" else '0';
-- Input logic
io: entity work.sc_input_serdes
port map(
clk => clk40,
rst => rst40,
clk_s => clk280,
d_p => d_p,
d_n => d_n,
slip => slip,
inc => inc,
q => d_in
);
d_in_i <= d_in when ctrl_invert = '0' else not d_in;
with sctr(1 downto 0) select sctr_p <=
sctr(11 downto 0) when "00",
sctr(23 downto 12) when "01",
sctr(35 downto 24) when "10",
sctr(47 downto 36) when others;
with ctrl_src select d_buf <=
d_in_i when "00",
(others => '0') when "01",
"00" & sctr_p when "10",
fake when others;
-- Channel status
err_i <= buf_full or dr_full;
err <= err_i;
ro_en <= not (pb_mode or cap_mode or err_i) and ctrl_en_buf;
keep_i <= keep and ro_en;
flush_i <= flush and ro_en;
veto <= dr_warn or not ro_en;
-- ZS thresholds
zs_t: entity work.ipbus_reg_v
generic map(
N_REG => N_ZS_THRESH
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_ZS_THRESH),
ipbus_out => ipbr(N_SLV_ZS_THRESH),
q => zs_thresh_v,
qmask => (others => X"00003fff")
);
zs_sel_i <= to_integer(unsigned(zs_sel));
zs_thresh <= zs_thresh_v(zs_sel_i)(13 downto 0) when zs_sel_i < N_ZS_THRESH else (others => '0');
-- Buffers
blkend <= and_reduce(sctr(BLK_RADIX - 1 downto 0));
buf: entity work.sc_chan_buf
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_BUF),
ipb_out => ipbr(N_SLV_BUF),
mode => ctrl_mode,
clk40 => clk40,
clk160 => clk160,
buf_rst => chan_rst,
d => d_buf,
blkend => blkend,
nzs_en => nzs_en,
cap_full => cap_full,
zs_thresh => zs_thresh,
zs_en => zs_en,
buf_full => buf_full,
keep => keep_i,
flush => flush_i,
q => dr_d,
q_blkend => dr_blkend,
wen => dr_wen
);
-- Derandomiser
derand: entity work.sc_derand
port map(
clk_w => clk40,
rst_w => rst40,
d => dr_d,
d_blkend => dr_blkend,
wen => dr_wen,
clk_r => clk_dr,
q => q,
q_blkend => q_blkend,
empty => q_empty,
ren => ren,
warn => dr_warn,
full => dr_full
);
-- Local triggers
ctrig: entity work.sc_chan_trig
generic map(
VAL_WIDTH => 14
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_TRIG_THRESH),
ipb_out => ipbr(N_SLV_TRIG_THRESH),
clk40 => clk40,
rst40 => chan_rst,
mark => blkend,
en => nzs_en,
d => d_buf,
trig => trig
);
end rtl;
sc_chan_buf.vhd 0000664 0000000 0000000 00000013275 13132146003 0032762 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_chan_buf.vhd
--
-- The buffer chain for one input channel
--
-- Dave Newbold, May 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.top_decl.all;
entity sc_chan_buf is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus; -- clk dom
ipb_out: out ipb_rbus; -- clk dom
mode: in std_logic_vector(1 downto 0); -- buffer counter mode; clk dom
clk40: in std_logic;
clk160: in std_logic;
buf_rst: in std_logic; -- general reset; clk40 dom
d: in std_logic_vector(13 downto 0); -- data in; clk40 dom
blkend: in std_logic;
nzs_en: in std_logic; -- enable nzs buffer; clk40 dom
cap_full: out std_logic;
zs_thresh: in std_logic_vector(13 downto 0); -- ZS threshold; clk40 dom
zs_en: in std_logic; -- enable zs buffer; clk40 dom
buf_full: out std_logic; -- buffer err flag; clk40 dom
keep: in std_logic; -- block transfer cmd; clk40 dom
flush: in std_logic; -- block discard cmd; clk40 dom
q: out std_logic_vector(31 downto 0); -- output to derand; clk40 dom
q_blkend: out std_logic;
wen: out std_logic -- derand write enable
);
end sc_chan_buf;
architecture rtl of sc_chan_buf is
constant NZS_LAST_ADDR: integer := NZS_BLKS * 2 ** BLK_RADIX + ZS_DEL - 1;
constant ZS_FIRST_ADDR: integer := NZS_BLKS * 2 ** BLK_RADIX + ZS_DEL;
constant ZS_LAST_ADDR: integer := 2 ** BUF_RADIX - 1;
signal norm_mode, pb_mode, cap_mode: std_logic;
signal c: unsigned(1 downto 0);
signal we: std_logic;
signal d_ram, q_ram, d_nzs, q_nzs, d_zs, q_zs, q_zs_b: std_logic_vector(15 downto 0);
signal a_ram: std_logic_vector(BUF_RADIX - 1 downto 0);
signal pnz, pzw, pzr: unsigned(BUF_RADIX - 1 downto 0);
signal cap_done: std_logic;
signal zctr: unsigned(BLK_RADIX - 1 downto 0);
signal z0, z1: std_logic;
signal zs_en_d, zs_en_dd, nzs_en_d, wenz, wez, rez, wez_d: std_logic;
signal go, zs_run, zs_keep, buf_full_i, p, q_blkend_i: std_logic;
begin
norm_mode <= '1' when mode = "00" else '0';
pb_mode <= '1' when mode = "01" else '0';
cap_mode <= '1' when mode = "10" else '0';
-- NZS / ZS buffer
ram: entity work.ipbus_ported_dpram
generic map(
ADDR_WIDTH => BUF_RADIX,
DATA_WIDTH => 16
)
port map(
clk => clk,
rst => rst,
ipb_in => ipb_in,
ipb_out => ipb_out,
rclk => clk160,
we => we,
d => d_ram,
q => q_ram,
addr => a_ram
);
process(clk160)
begin
if rising_edge(clk160) then
if buf_rst = '1' then
c <= "00";
else
c <= c + 1;
end if;
end if;
end process;
with c select a_ram <=
std_logic_vector(pnz) when "11", -- data / to from nzs on 1st edge of clk160 (clk40 rising)
std_logic_vector(pzw) when "01", -- data to zs on 3rd edge of clk160
std_logic_vector(pzr) when others; -- data from zs on 4th edge of clk160
with c select d_ram <=
d_nzs when "11",
d_zs when others;
with c select we <=
wenz when "11",
wez when "01",
'0' when others;
-- NZS pointer control
process(clk40)
begin
if rising_edge(clk40) then
nzs_en_d <= nzs_en;
zs_en_d <= zs_en;
zs_en_dd <= zs_en_d;
end if;
end process;
process(clk40)
begin
if falling_edge(clk40) then
if (pb_mode = '1' and nzs_en = '0') or (pb_mode = '0' and nzs_en_d = '0') then
pnz <= to_unsigned(0, pnz'length);
cap_done <= '0';
else
if (norm_mode = '1' and pnz = NZS_LAST_ADDR) or pnz = ZS_LAST_ADDR then
pnz <= (others => '0');
if cap_mode = '1' then
cap_done <= '1';
end if;
else
pnz <= pnz + 1;
end if;
end if;
end if;
end process;
wenz <= (norm_mode or cap_mode) and nzs_en and not cap_done;
d_nzs <= blkend & '0' & d;
cap_full <= cap_done;
-- Zero suppression
z0 <= '1' when unsigned(q_ram(13 downto 0)) < unsigned(zs_thresh) and q_ram(15) = '0' else '0';
process(clk160)
begin
if rising_edge(clk160) and c = "00" then
if zs_en_d = '0' then
zctr <= (others => '0');
else
q_nzs <= q_ram(15) & '0' & q_ram(13 downto 0);
z1 <= z0;
if z0 = '0' then
zctr <= (others => '0');
else
zctr <= zctr + 1;
end if;
end if;
wez <= (not (z0 and z1)) and zs_en_dd and norm_mode and not buf_full_i;
if z1 = '1' and zctr /= 1 then
d_zs <= "01" & (13 - BLK_RADIX downto 0 => '0') & std_logic_vector(zctr);
else
d_zs <= q_nzs;
end if;
end if;
end process;
-- ZS pointer control
process(clk40)
begin
if rising_edge(clk40) then
if zs_en = '0' or norm_mode = '0' then
pzw <= to_unsigned(ZS_FIRST_ADDR, pzw'length);
pzr <= to_unsigned(ZS_FIRST_ADDR, pzr'length);
elsif buf_full_i = '0' then
if wez = '1' then
if pzw = ZS_LAST_ADDR then
pzw <= to_unsigned(ZS_FIRST_ADDR, pzw'length);
else
pzw <= pzw + 1;
end if;
end if;
if rez = '1' then
if pzr = ZS_LAST_ADDR then
pzr <= to_unsigned(ZS_FIRST_ADDR, pzr'length);
else
pzr <= pzr + 1;
end if;
end if;
end if;
end if;
end process;
process(clk40)
begin
if rising_edge(clk40) then
if zs_en = '0' then
buf_full_i <= '0';
elsif pzw = pzr and wez_d = '1' then
buf_full_i <= '1';
end if;
wez_d <= wez;
end if;
end process;
buf_full <= buf_full_i;
-- Readout to derand
go <= keep or flush;
process(clk40)
begin
if rising_edge(clk40) then
if zs_en = '0' then
zs_run <= '0';
p <= '0';
else
if go = '1' then
zs_run <= '1';
zs_keep <= keep;
elsif p = '1' and q_blkend_i = '1' then
zs_run <= '0';
end if;
p <= not p;
end if;
q_zs <= q_ram;
q_zs_b <= q_zs;
end if;
end process;
rez <= go or (zs_run and not (q_zs(15) or (q_zs_b(15) and p)));
q_blkend_i <= q_zs(15) or q_zs_b(15);
q <= q_zs & q_zs_b;
q_blkend <= q_blkend_i;
wen <= zs_run and zs_keep and p;
end rtl;
sc_chan_standalone.vhd 0000664 0000000 0000000 00000005710 13132146003 0034331 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_chan.vhd
--
-- All the stuff belonging to one input channel
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
use work.ipbus.all;
use work.ipbus_decode_sc_chan_standalone.all;
use work.ipbus_reg_types.all;
entity sc_chan_standalone is
generic(
id: integer
);
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
sync_ctrl: in std_logic_vector(3 downto 0);
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
clk280: in std_logic;
d_p: in std_logic;
d_n: in std_logic
);
end sc_chan_standalone;
architecture rtl of sc_chan_standalone is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(0 downto 0);
signal d_in: std_logic_vector(13 downto 0);
signal d_c: std_logic_vector(1 downto 0);
signal ctrl_en_sync, ctrl_en_comp, slip, chan_rst, buf_we, inc: std_logic;
signal we, empty, full: std_logic;
signal ctrl_patt: std_logic_vector(13 downto 0);
signal err_cnt: unsigned(15 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_chan_standalone(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl,
qmask(0) => X"3FFF0003"
);
ctrl_en_sync <= ctrl(0)(0);
ctrl_en_comp <= ctrl(0)(1);
ctrl_patt <= ctrl(0)(29 downto 16);
slip <= sync_ctrl(0) and ctrl_en_sync; -- CDC
chan_rst <= (sync_ctrl(1) and ctrl_en_sync) or rst40; -- CDC
buf_we <= sync_ctrl(2) and ctrl_en_sync; -- CDC
inc <= sync_ctrl(3) and ctrl_en_sync; -- CDC
stat(0) <= std_logic_vector(err_cnt) & X"000" & "00" & full & empty; -- CDC
io: entity work.sc_input_serdes
port map(
clk => clk40,
rst => rst40,
clk_s => clk280,
d_p => d_p,
d_n => d_n,
slip => slip,
inc => inc,
q => d_in
);
we <= (we or buf_we) and not (full or chan_rst) when rising_edge(clk40);
cap_buf: entity work.sc_cap_fifo_16
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_FIFO),
ipb_out => ipbr(N_SLV_FIFO),
clk_p => clk40,
rst_p => chan_rst,
d(13 downto 0) => d_in,
d(15 downto 14) => "00",
we => we,
empty => empty,
full => full,
frst => chan_rst
);
process(clk40)
begin
if rising_edge(clk40) then
if ctrl_en_comp = '0' then
err_cnt <= (others => '0');
elsif d_in /= ctrl_patt and err_cnt /= (err_cnt'range => '1') then
err_cnt <= err_cnt + 1;
end if;
end if;
end process;
end rtl;
sc_chan_trig.vhd 0000664 0000000 0000000 00000004143 13132146003 0033145 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_chan_trig.vhd
--
-- Per-channel trigger generator
-- Trigger flags for last block are valid 1 cycle after block end (i.e. sctr = 0x00)
--
-- Dave Newbold, July 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_chan_trig is
generic(
VAL_WIDTH: natural := 14 -- bit
);
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
mark: in std_logic;
en: in std_logic;
d: in std_logic_vector(13 downto 0);
trig: out std_logic_vector(N_CHAN_TRG - 1 downto 0)
);
end sc_chan_trig;
architecture rtl of sc_chan_trig is
signal ctrl: ipb_reg_v(2 downto 0);
signal dd: std_logic_vector(13 downto 0);
signal trig_i: std_logic_vector(N_CHAN_TRG - 1 downto 0);
begin
reg: entity work.ipbus_ctrlreg_v -- CDC between ctrl (ipb_clk) and (clk40)
generic map(
N_CTRL => 3,
N_STAT => 0
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipb_in,
ipbus_out => ipb_out,
q => ctrl
);
dd <= d when rising_edge(clk40); -- pipeline register
trg0: entity work.sc_ctrig_thresh -- direct threshold trigger, delay = 1
generic map(
VAL_WIDTH => VAL_WIDTH
)
port map(
clk => clk40,
d => dd,
threshold => ctrl(0)(VAL_WIDTH - 1 downto 0),
trig => trig_i(0)
);
trg1: entity work.sc_ctrig_npeaks -- peaks-above-threshold trigger, delay = 2
generic map(
VAL_WIDTH => VAL_WIDTH
)
port map(
clk => clk40,
rst => rst40,
en => en,
d => dd,
cthresh => ctrl(1)(24 downto 16),
wsize => ctrl(1)(31 downto 28),
pthresh => ctrl(1)(VAL_WIDTH - 1 downto 0),
trig => trig_i(1)
);
trg2: entity work.sc_ctrig_tot -- time-over-threshold trigger, delay = 1
generic map(
VAL_WIDTH => VAL_WIDTH
)
port map(
clk => clk40,
rst => rst40,
en => en,
d => dd,
cthresh => ctrl(2)(24 downto 16),
wsize => ctrl(2)(31 downto 28),
pthresh => ctrl(2)(VAL_WIDTH - 1 downto 0),
trig => trig_i(2)
);
trig <= trig_i when en = '1' else (others => '0');
end rtl;
sc_channels.vhd 0000664 0000000 0000000 00000006017 13132146003 0033004 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_channels.vhd
--
-- Groups the input channels
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.top_decl.all;
library unisim;
use unisim.VComponents.all;
entity sc_channels is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
chan: in std_logic_vector(7 downto 0);
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
clk280: in std_logic;
d_p: in std_logic_vector(N_CHAN - 1 downto 0);
d_n: in std_logic_vector(N_CHAN - 1 downto 0);
sync_ctrl: in std_logic_vector(3 downto 0);
zs_sel: in std_logic_vector(1 downto 0);
sctr: in std_logic_vector(47 downto 0);
fake: in std_logic_vector(13 downto 0);
nzs_en: in std_logic;
zs_en: in std_logic;
keep: in std_logic_vector(N_CHAN - 1 downto 0);
flush: in std_logic_vector(N_CHAN - 1 downto 0);
err: out std_logic;
veto: out std_logic_vector(N_CHAN - 1 downto 0);
trig: out sc_trig_array;
dr_chan: in std_logic_vector(7 downto 0);
clk_dr: in std_logic;
q: out std_logic_vector(31 downto 0);
q_blkend: out std_logic;
q_empty: out std_logic;
ren: in std_logic
);
end sc_channels;
architecture rtl of sc_channels is
signal ipbw: ipb_wbus_array(N_CHAN - 1 downto 0);
signal ipbr: ipb_rbus_array(N_CHAN - 1 downto 0);
signal chan_err: std_logic_vector(N_CHAN - 1 downto 0);
type chan_q_t is array(N_CHAN - 1 downto 0) of std_logic_vector(31 downto 0);
signal chan_q: chan_q_t;
signal chan_q_blkend, chan_q_empty, chan_ren: std_logic_vector(N_CHAN - 1 downto 0);
signal sel: integer range N_CHAN - 1 downto 0 := 0;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_CHAN,
SEL_WIDTH => 8
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => chan,
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- channels
sel <= to_integer(unsigned(dr_chan));
cgen: for i in N_CHAN - 1 downto 0 generate
signal ren_loc: std_logic;
signal ltrig: std_logic_vector(N_CHAN_TRG - 1 downto 0);
begin
ren_loc <= ren when sel = i else '0';
chan: entity work.sc_chan
generic map(
id => i
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(i),
ipb_out => ipbr(i),
clk40 => clk40,
rst40 => rst40,
clk160 => clk160,
clk280 => clk280,
d_p => d_p(i),
d_n => d_n(i),
sync_ctrl => sync_ctrl,
zs_sel => zs_sel,
sctr => sctr,
fake => fake,
nzs_en => nzs_en,
zs_en => zs_en,
keep => keep(i),
flush => flush(i),
err => chan_err(i),
veto => veto(i),
trig => ltrig,
clk_dr => clk_dr,
q => chan_q(i),
q_blkend => chan_q_blkend(i),
q_empty => chan_q_empty(i),
ren => ren_loc
);
tgen: for j in N_CHAN_TRG - 1 downto 0 generate
trig(j)(i) <= ltrig(j);
end generate;
end generate;
q <= chan_q(sel);
q_blkend <= chan_q_blkend(sel);
q_empty <= chan_q_empty(sel);
err <= or_reduce(chan_err);
end rtl;
sc_channels_standalone.vhd 0000664 0000000 0000000 00000002762 13132146003 0035217 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_channels.vhd
--
-- Groups the input channels
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.top_decl.all;
library unisim;
use unisim.VComponents.all;
entity sc_channels_standalone is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
chan: in std_logic_vector(7 downto 0);
sync_ctrl: in std_logic_vector(3 downto 0);
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
clk280: in std_logic;
d_p: in std_logic_vector(N_CHAN - 1 downto 0);
d_n: in std_logic_vector(N_CHAN - 1 downto 0)
);
end sc_channels_standalone;
architecture rtl of sc_channels_standalone is
signal ipbw: ipb_wbus_array(N_CHAN - 1 downto 0);
signal ipbr: ipb_rbus_array(N_CHAN - 1 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_CHAN,
SEL_WIDTH => 8
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => chan,
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- channels
cgen: for i in N_CHAN - 1 downto 0 generate
begin
chan: entity work.sc_chan_standalone
generic map(
id => i
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(i),
ipb_out => ipbr(i),
sync_ctrl => sync_ctrl,
clk40 => clk40,
rst40 => rst40,
clk160 => clk160,
clk280 => clk280,
d_p => d_p(i),
d_n => d_n(i)
);
end generate;
end rtl;
sc_clocks.vhd 0000664 0000000 0000000 00000003547 13132146003 0032474 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_clocks
--
-- Generates 40MHz sample clock and other related clocks for iserdes, etc.
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
entity sc_clocks is
port(
clk_in_p: in std_logic; -- Input clock (nominally 40MHz)
clk_in_n: in std_logic;
clk40: out std_logic; -- Sample clock (nominally 40MHz)
clk80: out std_logic; -- Processing clock (2 * clk_s)
clk160: out std_logic; -- Processing clock (4 * clk_s)
clk280: out std_logic; -- iserdes clock (7 * clk_s)
locked: out std_logic;
rst_mmcm: in std_logic;
rsti: in std_logic;
rst40: out std_logic
);
end sc_clocks;
architecture rtl of sc_clocks is
signal clk_in_ub, clk_in, clkfb: std_logic;
signal clk40_u, clk40_i, clk80_u, clk160_u, clk280_u: std_logic;
signal locked_i: std_logic;
begin
ibufgds0: IBUFGDS port map(
i => clk_in_p,
ib => clk_in_n,
o => clk_in_ub
);
bufg_clk_in: BUFG port map(
i => clk_in_ub,
o => clk_in
);
mmcm: MMCME2_BASE
generic map(
CLKIN1_PERIOD => 25.0,
CLKFBOUT_MULT_F => 28.0,
CLKOUT0_DIVIDE_F => 28.0,
CLKOUT1_DIVIDE => 14,
CLKOUT2_DIVIDE => 7,
CLKOUT3_DIVIDE => 4
)
port map(
clkin1 => clk_in,
clkfbin => clkfb,
clkout0 => clk40_u,
clkout1 => clk80_u,
clkout2 => clk160_u,
clkout3 => clk280_u,
clkfbout => clkfb,
locked => locked_i,
rst => rst_mmcm,
pwrdwn => '0'
);
locked <= locked_i;
bufg40: BUFG
port map(
i => clk40_u,
o => clk40_i
);
clk40 <= clk40_i;
process(clk40_i)
begin
if rising_edge(clk40_i) then
rst40 <= rsti or not locked_i;
end if;
end process;
bufg80: BUFG
port map(
i => clk80_u,
o => clk80
);
bufg160: BUFG
port map(
i => clk160_u,
o => clk160
);
bufg280: BUFG
port map(
i => clk280_u,
o => clk280
);
end rtl;
sc_ctrig_npeaks.vhd 0000664 0000000 0000000 00000002410 13132146003 0033653 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_ctrig_npeaks
--
-- Peaks-above-threshold trigger
--
-- Dave Newbold, May 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_ctrig_npeaks is
generic(
VAL_WIDTH: natural
);
port(
clk: in std_logic;
rst: in std_logic;
en: in std_logic;
d: in std_logic_vector(VAL_WIDTH - 1 downto 0);
cthresh: in std_logic_vector(8 downto 0);
wsize: in std_logic_vector(3 downto 0);
pthresh: in std_logic_vector(VAL_WIDTH - 1 downto 0);
trig: out std_logic
);
end sc_ctrig_npeaks;
architecture rtl of sc_ctrig_npeaks is
signal d1, d2: std_logic_vector(VAL_WIDTH - 1 downto 0);
signal p, rsti: std_logic;
signal count: std_logic_vector(cthresh'range);
begin
rsti <= rst or not en;
d1 <= d when rising_edge(clk);
d2 <= d1 when rising_edge(clk);
p <= '1' when unsigned(d1) > unsigned(pthresh) and unsigned(d2) < unsigned(d1) and unsigned(d) <= unsigned(d1) else '0';
cnt: entity work.sc_ctrig_window
generic map(
C_WIDTH => cthresh'length
)
port map(
clk => clk,
rst => rsti,
wsize => wsize,
p => p,
count => count
);
thresh: entity work.sc_ctrig_thresh
generic map(
VAL_WIDTH => cthresh'length
)
port map(
clk => clk,
d => count,
threshold => cthresh,
trig => trig
);
end rtl;
sc_ctrig_thresh.vhd 0000664 0000000 0000000 00000001120 13132146003 0033664 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_ctrig_thresh
--
-- Catch values above threshold within a block
--
-- Dave Newbold, April 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_ctrig_thresh is
generic(
VAL_WIDTH: natural
);
port(
clk: in std_logic;
d: in std_logic_vector(VAL_WIDTH - 1 downto 0);
threshold: in std_logic_vector(VAL_WIDTH - 1 downto 0);
trig: out std_logic
);
end sc_ctrig_thresh;
architecture rtl of sc_ctrig_thresh is
signal t: std_logic;
begin
t <= '1' when unsigned(d) > unsigned(threshold) else '0';
trig <= t when rising_edge(clk);
end rtl;
sc_ctrig_tot.vhd 0000664 0000000 0000000 00000002076 13132146003 0033210 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_ctrig_tot
--
-- Time-over-threshold trigger
--
-- Dave Newbold, May 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_ctrig_tot is
generic(
VAL_WIDTH: natural
);
port(
clk: in std_logic;
rst: in std_logic;
en: in std_logic;
d: in std_logic_vector(VAL_WIDTH - 1 downto 0);
cthresh: in std_logic_vector(8 downto 0);
wsize: in std_logic_vector(3 downto 0);
pthresh: in std_logic_vector(VAL_WIDTH - 1 downto 0);
trig: out std_logic
);
end sc_ctrig_tot;
architecture rtl of sc_ctrig_tot is
signal p, rsti: std_logic;
signal count: std_logic_vector(cthresh'range);
begin
rsti <= rst or not en;
p <= '1' when unsigned(d) > unsigned(pthresh) else '0';
cnt: entity work.sc_ctrig_window
generic map(
C_WIDTH => cthresh'length
)
port map(
clk => clk,
rst => rsti,
wsize => wsize,
p => p,
count => count
);
thresh: entity work.sc_ctrig_thresh
generic map(
VAL_WIDTH => cthresh'length
)
port map(
clk => clk,
d => count,
threshold => cthresh,
trig => trig
);
end rtl;
sc_ctrig_window.vhd 0000664 0000000 0000000 00000002401 13132146003 0033701 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_ctrig_window
--
-- Count features in sliding window
--
-- Dave Newbold, May 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
use work.top_decl.all;
entity sc_ctrig_window is
generic(
C_WIDTH: natural
);
port(
clk: in std_logic;
rst: in std_logic;
wsize: in std_logic_vector(3 downto 0);
p: in std_logic;
count: out std_logic_vector(C_WIDTH - 1 downto 0)
);
end sc_ctrig_window;
architecture rtl of sc_ctrig_window is
signal w, f: std_logic_vector(2 ** wsize'length downto 0);
signal r: std_logic;
signal count_i: unsigned(C_WIDTH - 1 downto 0);
begin
w(0) <= p and not rst;
dgen: for i in 2 ** wsize'length - 1 downto 0 generate
srl0: SRLC32E
port map(
clk => clk,
ce => '1',
a => "11111",
d => w(i),
q31 => w(i + 1),
q => f(i)
);
end generate;
r <= f(to_integer(unsigned(wsize)));
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
count_i <= (others => '0');
else
if p = '1' and r = '0' then
count_i <= count_i + 1;
elsif p = '0' and r = '1' and count_i /= 0 then
count_i <= count_i - 1;
end if;
end if;
end if;
end process;
count <= std_logic_vector(count_i);
end rtl;
sc_daq.vhd 0000664 0000000 0000000 00000012375 13132146003 0031762 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- daq.vhd
--
-- Core components of the DAQ, independent of board type
--
-- Dave Newbold, May 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.ipbus_decode_sc_daq.all;
use work.top_decl.all;
entity sc_daq is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
rst_mmcm: in std_logic;
locked: out std_logic;
clk_in_p: in std_logic;
clk_in_n: in std_logic;
clk40: out std_logic;
sync_in: in std_logic;
trig_in: in std_logic;
trig_out: out std_logic;
chan: in std_logic_vector(7 downto 0);
chan_err: out std_logic;
d_p: in std_logic_vector(N_CHAN - 1 downto 0);
d_n: in std_logic_vector(N_CHAN - 1 downto 0);
clk125: in std_logic;
rst125: in std_logic;
board_id: in std_logic_vector(7 downto 0)
);
end sc_daq;
architecture rtl of sc_daq is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal clk40_i, rst40_i, clk160, clk280: std_logic;
signal sync_ctrl: std_logic_vector(3 downto 0);
signal sctr: std_logic_vector(47 downto 0);
signal trig_en, nzs_en, zs_en: std_logic;
signal trig_keep, trig_flush, trig_veto: std_logic_vector(N_CHAN - 1 downto 0);
signal fake: std_logic_vector(13 downto 0);
signal force_trig, thresh_hit: std_logic;
signal zs_sel: std_logic_vector(1 downto 0);
signal chan_trig: sc_trig_array;
signal link_d, link_q: std_logic_vector(15 downto 0);
signal link_d_valid, link_q_valid, link_ack: std_logic;
signal ro_chan: std_logic_vector(7 downto 0);
signal ro_d, trig_d: std_logic_vector(31 downto 0);
signal ro_blkend, ro_empty, ro_ren, trig_sync, trig_blkend, trig_we, trig_roc_veto: std_logic;
signal rand: std_logic_vector(31 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_daq(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- Timing
timing: entity work.sc_timing
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_TIMING),
ipb_out => ipbr(N_SLV_TIMING),
rst_mmcm => rst_mmcm,
locked => locked,
clk_in_p => clk_in_p,
clk_in_n => clk_in_n,
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
clk280 => clk280,
sync_in => sync_in,
trig_in => trig_in,
sctr => sctr,
chan_sync_ctrl => sync_ctrl,
trig_en => trig_en,
nzs_en => nzs_en,
zs_en => zs_en,
rand => rand
);
clk40 <= clk40_i;
-- Fake data generator
faker: entity work.sc_fake
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_FAKE),
ipb_out => ipbr(N_SLV_FAKE),
clk40 => clk40_i,
rst40 => rst40_i,
rand => rand,
sctr => sctr(7 downto 0),
fake => fake
);
-- Random trigger generator
rtrig: entity work.sc_rtrig
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_RTRIG),
ipb_out => ipbr(N_SLV_RTRIG),
clk40 => clk40_i,
rst40 => rst40_i,
rand => rand,
sctr => sctr,
force => force_trig
);
-- Data channels
chans: entity work.sc_channels
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_CHAN),
ipb_out => ipbr(N_SLV_CHAN),
chan => chan,
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
clk280 => clk280,
d_p => d_p,
d_n => d_n,
sync_ctrl => sync_ctrl,
zs_sel => zs_sel,
sctr => sctr,
fake => fake,
nzs_en => nzs_en,
zs_en => zs_en,
keep => trig_keep,
flush => trig_flush,
err => chan_err,
veto => trig_veto,
trig => chan_trig,
dr_chan => ro_chan,
clk_dr => ipb_clk,
q => ro_d,
q_blkend => ro_blkend,
q_empty => ro_empty,
ren => ro_ren
);
-- Trigger
trig: entity work.sc_trig
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_TRIG),
ipb_out => ipbr(N_SLV_TRIG),
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
trig_en => trig_en,
zs_en => zs_en,
sctr => sctr,
rand => rand,
keep => trig_keep,
flush => trig_flush,
veto => trig_veto,
zs_sel => zs_sel,
trig => chan_trig,
force => force_trig,
ext_trig_in => trig_in,
ext_trig_out => trig_out,
ro_d => trig_d,
ro_blkend => trig_blkend,
ro_we => trig_we,
ro_veto => trig_roc_veto,
q => link_d,
q_valid => link_d_valid,
d => link_q,
d_valid => link_q_valid,
d_ack => link_ack
);
-- Trigger serial links
tlink: entity work.sc_trig_link
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_TLINK),
ipb_out => ipbr(N_SLV_TLINK),
clk125 => clk125,
rst125 => rst125,
clk40 => clk40_i,
rst40 => rst40_i,
d => link_d,
d_valid => link_d_valid,
q => link_q,
q_valid => link_q_valid,
ack => link_ack
);
-- Readout
roc: entity work.sc_roc
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_ROC),
ipb_out => ipbr(N_SLV_ROC),
board_id => board_id,
clk40 => clk40_i,
rst40 => rst40_i,
rand => rand,
d_trig => trig_d,
blkend_trig => trig_blkend,
we_trig => trig_we,
veto_trig => trig_roc_veto,
chan => ro_chan,
d => ro_d,
blkend => ro_blkend,
empty => ro_empty,
ren => ro_ren
);
end rtl;
sc_deadtime_mon.vhd 0000664 0000000 0000000 00000004661 13132146003 0033641 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_deadtime_mon
--
-- Deadtime counters
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_deadtime_mon is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
en: in std_logic;
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
mark: in std_logic;
sctr: in std_logic_vector(BLK_RADIX - 1 downto 0);
keep: in std_logic_vector(N_CHAN - 1 downto 0);
veto: in std_logic_vector(N_CHAN - 1 downto 0)
);
end sc_deadtime_mon;
architecture rtl of sc_deadtime_mon is
constant ADDR_BITS: integer := calc_width(N_CHAN) + 2;
signal c: unsigned(1 downto 0);
signal en_i, first: std_logic;
signal d_ram, q_ram: std_logic_vector(31 downto 0);
signal a_ram: std_logic_vector(ADDR_BITS - 1 downto 0);
signal we, inc, done, p: std_logic;
signal sel: integer range 2 ** (ADDR_BITS - 1) - 1 downto 0 := 0;
signal sel_c: integer range N_CHAN - 1 downto 0 := 0;
begin
-- Timing
process(clk160)
begin
if rising_edge(clk160) then
if rst40 = '1' then
c <= "00";
else
c <= c + 1;
end if;
end if;
end process;
-- Enable
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' then
first <= '0';
en_i <= '0';
done <= '1';
elsif mark = '1' then
en_i <= en;
first <= en and not en_i;
elsif and_reduce(sctr(BLK_RADIX - 2 downto 0)) = '1' then
done <= '0';
elsif sel = N_CHAN then
done <= '1';
end if;
end if;
end process;
-- RAM for counters
ram: entity work.ipbus_ported_dpram
generic map(
ADDR_WIDTH => ADDR_BITS,
DATA_WIDTH => 32
)
port map(
clk => clk,
rst => rst,
ipb_in => ipb_in,
ipb_out => ipb_out,
rclk => clk160,
we => we,
d => d_ram,
q => q_ram,
addr => a_ram
);
d_ram <= std_logic_vector(unsigned(q_ram) + unsigned(std_logic_vector'(0 => inc))) when first = '0' else (0 => inc, others => '0');
we <= c(0) and not done;
a_ram <= sctr(ADDR_BITS - 2 downto 0) & c(1);
-- Counter enables
sel <= to_integer(unsigned(sctr(ADDR_BITS - 1 downto 1)));
sel_c <= sel when sel < N_CHAN else 0;
with std_logic_vector'(sctr(0) & c(1)) select inc <=
'1' when "00",
keep(sel_c) when "01",
veto(sel_c) when "10",
keep(sel_c) and veto(sel_c) when others;
end rtl;
sc_derand.vhd 0000664 0000000 0000000 00000003267 13132146003 0032452 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_chan_buf.vhd
--
-- The buffer chain for one input channel
--
-- Dave Newbold, May 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
use work.top_decl.all;
entity sc_derand is
port(
clk_w: in std_logic;
rst_w: in std_logic;
d: in std_logic_vector(31 downto 0);
d_blkend: in std_logic;
wen: in std_logic;
clk_r: in std_logic;
q: out std_logic_vector(31 downto 0);
q_blkend: out std_logic;
empty: out std_logic;
ren: in std_logic;
warn: out std_logic;
full: out std_logic
);
end sc_derand;
architecture rtl of sc_derand is
signal rst_ctr: unsigned(3 downto 0);
signal rsti, fifo_rst, wen_i: std_logic;
signal di, qi: std_logic_vector(63 downto 0);
signal dip, qip: std_logic_vector(7 downto 0);
begin
process(clk_w)
begin
if rising_edge(clk_w) then
if rst_w = '1' then
rst_ctr <= "0000";
elsif rsti = '1' then
rst_ctr <= rst_ctr + 1;
end if;
end if;
end process;
rsti <= '0' when rst_ctr = "1111" else '1';
fifo_rst <= rsti and rst_ctr(3);
wen_i <= wen and not rsti;
di <= X"00000000" & d;
dip <= X"0" & "000" & d_blkend;
fifo: FIFO36E1
generic map(
DATA_WIDTH => 36,
FIRST_WORD_FALL_THROUGH => true,
ALMOST_FULL_OFFSET => to_bitvector(std_logic_vector(to_unsigned(2 ** (BLK_RADIX - 1) + 8, 16)))
)
port map(
di => di,
dip => dip,
do => qi,
dop => qip,
empty => empty,
full => full,
almostfull => warn,
injectdbiterr => '0',
injectsbiterr => '0',
rdclk => clk_r,
rden => ren,
regce => '1',
rst => rst_w,
rstreg => '0',
wrclk => clk_w,
wren => wen_i
);
q <= qi(31 downto 0);
q_blkend <= qip(0);
end rtl;
sc_fake.vhd 0000664 0000000 0000000 00000007103 13132146003 0032114 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_fake
--
-- Fake data generator for trigger testing
--
-- Dave Newbold, June 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_decode_sc_fake.all;
use work.ipbus_reg_types.all;
entity sc_fake is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
rand: in std_logic_vector(31 downto 0);
sctr: in std_logic_vector(7 downto 0);
fake: out std_logic_vector(13 downto 0)
);
end sc_fake;
architecture rtl of sc_fake is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stb: std_logic_vector(0 downto 0);
signal ctrl_en, ctrl_mode, ctrl_force, ctrl_samp_lock: std_logic;
signal params: ipb_reg_v(1 downto 0);
signal params_freq_div: std_logic_vector(3 downto 0);
signal params_n, params_gap, params_samp: std_logic_vector(7 downto 0);
signal params_level, params_ped: std_logic_vector(13 downto 0);
signal mask: std_logic_vector(15 downto 0);
signal pulse: std_logic_vector(13 downto 0);
signal p, go, samp, pend, act, done: std_logic;
signal pcnt, gcnt: unsigned(7 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_fake(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- Ctrl
csr: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 1
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CTRL),
ipb_out => ipbr(N_SLV_CTRL),
slv_clk => clk40,
q => ctrl,
stb => stb
);
ctrl_en <= ctrl(0)(0);
ctrl_mode <= ctrl(0)(1);
ctrl_force <= ctrl(0)(2) and stb(0);
ctrl_samp_lock <= ctrl(0)(3);
-- Parameters
params_csr: entity work.ipbus_reg_v
generic map(
N_REG => 2
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_PARAMS),
ipbus_out => ipbr(N_SLV_PARAMS),
q => params
);
params_freq_div <= params(0)(3 downto 0);
params_n <= params(0)(15 downto 8);
params_gap <= params(0)(23 downto 16);
params_samp <= params(0)(31 downto 24);
params_level <= params(1)(13 downto 0);
params_ped <= params(1)(29 downto 16);
-- Trigger
process(params_freq_div)
begin
for i in mask'range loop
if i > to_integer(unsigned(params_freq_div)) then
mask(i) <= '0';
else
mask(i) <= '1';
end if;
end loop;
end process;
go <= '1' when ctrl_force = '1' or (or_reduce(mask and rand(27 downto 12)) = '0' and or_reduce(rand(11 downto 0)) = '0') else '0';
samp <= '1' when ctrl_samp_lock = '0' or sctr = params_samp else '0';
pend <= (pend or (go and not act)) and not (rst40 or act) when rising_edge(clk40);
act <= (act or (pend and samp)) and not (rst40 or done) when rising_edge(clk40);
-- Pulse generator
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' or done = '1' then
pcnt <= (others => '0');
gcnt <= (others => '0');
p <= '0';
elsif act = '1' then
if gcnt = 0 then
gcnt <= unsigned(params_gap);
p <= '1';
pcnt <= pcnt + 1;
else
gcnt <= gcnt - 1;
p <= '0';
end if;
end if;
end if;
end process;
done <= '1' when pcnt = unsigned(params_n) else '0';
-- Output
pulse <= params_level when p = '1' else params_ped;
fake <= rand(13 downto 0) when ctrl_mode = '0' else pulse;
end rtl;
sc_input_serdes.vhd 0000664 0000000 0000000 00000004546 13132146003 0033722 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_input_serdes.vhd
--
-- Input logic for serial-parallel conversation of ADC data
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity sc_input_serdes is
port(
clk: in std_logic;
rst: in std_logic;
clk_s: in std_logic;
d_p: in std_logic;
d_n: in std_logic;
slip: in std_logic;
inc: in std_logic;
q: out std_logic_vector(13 downto 0)
);
end sc_input_serdes;
architecture rtl of sc_input_serdes is
signal d_b, d_d: std_logic;
signal d: std_logic_vector(13 downto 0);
signal s1, s2: std_logic;
signal clk_sb: std_logic;
begin
ibuf: IBUFDS
port map(
i => d_p,
ib => d_n,
o => d_b
);
idel: IDELAYE2
generic map(
IDELAY_TYPE => "VARIABLE"
)
port map(
c => clk,
regrst => '0',
ld => rst,
ce => inc,
inc => '1',
cinvctrl => '0',
cntvaluein => "00000",
idatain => d_b,
datain => '0',
ldpipeen => '0',
dataout => d_d
);
clk_sb <= not clk_s;
m_serdes: ISERDESE2
generic map(
DATA_WIDTH => 14,
INTERFACE_TYPE => "NETWORKING",
SERDES_MODE => "MASTER",
IOBDELAY => "BOTH" -- Essential. And undocumented.
)
port map(
q1 => q(0),
q2 => q(1),
q3 => q(2),
q4 => q(3),
q5 => q(4),
q6 => q(5),
q7 => q(6),
q8 => q(7),
shiftout1 => s1,
shiftout2 => s2,
d => '0',
ddly => d_d,
clk => clk_s,
clkb => clk_sb,
ce1 => '1',
ce2 => '1',
rst => rst,
clkdiv => clk,
clkdivp => '0', -- WTF is this? Not in the user guide
oclk => '0',
oclkb => '0',
bitslip => slip,
shiftin1 => '0',
shiftin2 => '0',
ofb => '0',
dynclkdivsel => '0',
dynclksel => '0'
);
s_serdes: ISERDESE2
generic map(
DATA_WIDTH => 14,
INTERFACE_TYPE => "NETWORKING",
SERDES_MODE => "SLAVE",
IOBDELAY => "BOTH" -- Essential. And undocumented.
)
port map(
q1 => open,
q2 => open,
q3 => q(8),
q4 => q(9),
q5 => q(10),
q6 => q(11),
q7 => q(12),
q8 => q(13),
shiftout1 => open,
shiftout2 => open,
d => '0',
ddly => '0',
clk => clk_s,
clkb => clk_sb,
ce1 => '1',
ce2 => '1',
rst => rst,
clkdiv => clk,
clkdivp => '0', -- WTF is this? Not in the user guide
oclk => '0',
oclkb => '0',
bitslip => slip,
shiftin1 => s1,
shiftin2 => s2,
ofb => '0',
dynclkdivsel => '0',
dynclksel => '0'
);
end rtl;
sc_io.vhd 0000664 0000000 0000000 00000006537 13132146003 0031627 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_io
--
-- Interfaces to board chipset
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_decode_sc_io.all;
use work.ipbus_reg_types.all;
entity sc_io is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
si5326_scl: out std_logic;
si5326_sda_o: out std_logic;
si5326_sda_i: in std_logic;
si5326_rstn: out std_logic;
si5326_phase_inc: out std_logic;
si5326_phase_dec: out std_logic;
si5326_clk1_validn: in std_logic;
si5326_clk2_validn: in std_logic;
si5326_lol: in std_logic;
si5326_clk_sel: out std_logic;
si5326_rate0: out std_logic;
si5326_rate1: out std_logic;
adc_cs: out std_logic_vector(1 downto 0);
adc_mosi: out std_logic;
adc_miso: in std_logic_vector(1 downto 0);
adc_sclk: out std_logic;
analog_scl: out std_logic;
analog_sda_o: out std_logic;
analog_sda_i: in std_logic
);
end sc_io;
architecture rtl of sc_io is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(0 downto 0);
signal clkdiv: std_logic_vector(0 downto 0);
signal adc_ss: std_logic_vector(1 downto 0);
signal adc_miso_i: std_logic;
signal adc_d: std_logic_vector(11 downto 0);
signal adc_v: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_io(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl,
qmask(0) => X"0000000F"
);
stat(0) <= X"0000000" & '0' & si5326_clk2_validn & si5326_clk1_validn & si5326_lol;
-- I2C master
i2c_clock: entity work.ipbus_i2c_master
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CLOCK_I2C),
ipb_out => ipbr(N_SLV_CLOCK_I2C),
scl => si5326_scl,
sda_o => si5326_sda_o,
sda_i => si5326_sda_i
);
si5326_rstn <= not ctrl(0)(0);
si5326_phase_inc <= '0';
si5326_phase_dec <= '0';
si5326_clk_sel <= ctrl(0)(1);
si5326_rate0 <= ctrl(0)(2);
si5326_rate1 <= ctrl(0)(3);
-- I2C master to analogue board
i2c_analog: entity work.ipbus_i2c_master
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_ANALOG_I2C),
ipb_out => ipbr(N_SLV_ANALOG_I2C),
scl => analog_scl,
sda_o => analog_sda_o,
sda_i => analog_sda_i
);
-- SPI master
spi: entity work.ipbus_spi
generic map(
N_SS => 2
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_SPI),
ipb_out => ipbr(N_SLV_SPI),
ss => adc_ss,
mosi => adc_mosi,
miso => adc_miso_i,
sclk => adc_sclk
);
adc_cs <= not adc_ss;
adc_miso_i <= and_reduce(adc_miso);
-- Clock frequency counter
div: entity work.freq_ctr_div
port map(
clk(0) => clk40,
clkdiv => clkdiv
);
ctr: entity work.freq_ctr
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_FREQ_CTR),
ipb_out => ipbr(N_SLV_FREQ_CTR),
clkdiv => clkdiv
);
end rtl;
sc_io_64chan.vhd 0000664 0000000 0000000 00000004655 13132146003 0032771 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_io
--
-- Interfaces to board chipset
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_decode_sc_io_64chan.all;
use work.ipbus_reg_types.all;
entity sc_io_64chan is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
i2c_scl: out std_logic; -- I2C bus via CPLD
i2c_sda_i: in std_logic;
i2c_sda_o: out std_logic;
spi_csn: out std_logic;
spi_mosi: out std_logic;
spi_miso: in std_logic;
spi_sclk: out std_logic;
clkgen_lol: in std_logic;
clkgen_rstn: out std_logic
);
end sc_io_64chan;
architecture rtl of sc_io_64chan is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(0 downto 0);
signal clkdiv: std_logic_vector(0 downto 0);
signal ss: std_logic_vector(0 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_io_64chan(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl,
qmask(0) => X"00000001"
);
stat(0) <= X"0000000" & "000" & clkgen_lol;
clkgen_rstn <= not ctrl(0)(0);
-- I2C master
i2c_clock: entity work.ipbus_i2c_master
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_I2C),
ipb_out => ipbr(N_SLV_I2C),
scl => i2c_scl,
sda_o => i2c_sda_o,
sda_i => i2c_sda_i
);
-- SPI master
spi: entity work.ipbus_spi
generic map(
N_SS => 1
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_SPI),
ipb_out => ipbr(N_SLV_SPI),
ss => ss,
mosi => spi_mosi,
miso => spi_miso,
sclk => spi_sclk
);
spi_csn <= not ss(0);
-- Clock frequency counter
div: entity work.freq_ctr_div
port map(
clk(0) => clk40,
clkdiv => clkdiv
);
ctr: entity work.freq_ctr
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_FREQ_CTR),
ipb_out => ipbr(N_SLV_FREQ_CTR),
clkdiv => clkdiv
);
end rtl;
sc_local_trig.vhd 0000664 0000000 0000000 00000010176 13132146003 0033331 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_local_trig
--
-- Generates local triggers based on channel trigger outputs
--
-- Send data to ROC on 32nd cycle of block
-- All channel trigger inputs must be frozen by then
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_local_trig is
port(
clk40: in std_logic;
rst40: in std_logic;
en: in std_logic;
mask: in std_logic_vector(N_TRG - 1 downto 0);
mark: in std_logic;
sctr: in std_logic_vector(47 downto 0);
rand: in std_logic_vector(31 downto 0);
chan_trig: in sc_trig_array;
trig_q: out std_logic_vector(15 downto 0);
trig_valid: out std_logic;
trig_ack: in std_logic;
force: in std_logic;
ext_trig_in: in std_logic;
ro_q: out std_logic_vector(31 downto 0);
ro_valid: out std_logic;
ro_blkend: out std_logic;
ro_go: in std_logic;
ro_ctr: in std_logic_vector(7 downto 0);
rveto: in std_logic
);
end sc_local_trig;
architecture rtl of sc_local_trig is
signal tv, te, ta, tc: std_logic_vector(N_TRG - 1 downto 0);
signal s: integer range N_TRG - 1 downto 0;
signal ch: integer range 2 ** ro_ctr'length - 1 downto 0;
signal ch_i: integer range N_CHAN - 1 downto 0 := 0;
signal cact: sc_ltrig_array;
signal go, blkend, rveto_d, last_gasp, hoorah: std_logic;
signal bi: std_logic_vector(63 downto 0);
signal b: std_logic_vector(31 downto 0);
begin
-- Threshold trigger generator
tg0: entity work.sc_trig_gen_or
generic map(
TBIT => 0,
DELAY => 2
)
port map(
clk => clk40,
en => en,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(0),
valid => tv(0),
ack => ta(0)
);
-- peaks-over-threshold trigger generator
tg1: entity work.sc_trig_gen_or
generic map(
TBIT => 1,
DELAY => 3
)
port map(
clk => clk40,
en => en,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(1),
valid => tv(1),
ack => ta(1)
);
-- time-over-threshold trigger generator
tg2: entity work.sc_trig_gen_or
generic map(
TBIT => 2,
DELAY => 2
)
port map(
clk => clk40,
en => en,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(2),
valid => tv(2),
ack => ta(2)
);
-- random / external trigger generator
tg3: entity work.sc_trig_gen
generic map(
DELAY => 2
)
port map(
clk => clk40,
en => en,
mark => mark,
trig => force,
valid => tv(3),
ack => ta(3)
);
cact(3) <= (others => '0');
-- Add more trigger generators here...
-- Priority encoder
te <= tv and mask;
process(te)
begin
s <= 0;
for i in te'reverse_range loop
if te(i) = '1' then
s <= i;
end if;
end loop;
end process;
trig_q <= X"00" & X"0" & std_logic_vector(to_unsigned(s, 4)); -- Hop count will go in 7:4 one day
trig_valid <= or_reduce(te) and not rveto;
process(s, trig_ack)
begin
for i in N_TRG - 1 downto 0 loop
if trig_ack = '1' and s = i then
ta(i) <= '1';
else
ta(i) <= '0';
end if;
end loop;
end process;
process(clk40)
begin
if rising_edge(clk40) then
if en = '0' or blkend = '1' then
tc <= (others => '0');
else
tc <= tc or ta;
end if;
end if;
end process;
-- Last gasp message flag
rveto_d <= rveto and en when rising_edge(clk40) and mark = '1';
last_gasp <= rveto and not rveto_d;
hoorah <= rveto_d and not rveto;
-- Trigger data to readout
go <= (go or (ro_go and ((or_reduce(tc) and not rveto) or last_gasp or hoorah))) and not blkend and en and not rst40 when rising_edge(clk40);
blkend <= '1' when unsigned(ro_ctr) = 3 + 2 * N_CHAN_TRG else '0';
ro_valid <= go;
ro_blkend <= blkend;
ch <= to_integer(unsigned(ro_ctr(ro_ctr'length - 1 downto 1)));
ch_i <= ch - 2 when ch > 1 and ch < N_CHAN_TRG else 0;
bi <= (63 downto N_CHAN => '0') & cact(ch_i);
b <= bi(63 downto 32) when ro_ctr(0) = '1' else bi(31 downto 0);
with ro_ctr select ro_q <=
X"100" & "00" & last_gasp & hoorah & (15 downto N_TRG => '0') & tc when X"00", -- Type 1
std_logic_vector(sctr(31 downto BLK_RADIX)) & (BLK_RADIX - 1 downto 0 => '0') when X"01",
X"0000" & std_logic_vector(sctr(47 downto 32)) when X"02",
X"00000000" when X"03",
b when others;
end rtl;
sc_ltrig_thresh.vhd 0000664 0000000 0000000 00000001354 13132146003 0033706 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_ctrig_thresh
--
-- Catch values above threshold within a block
--
-- Dave Newbold, April 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_ctrig_thresh is
generic(
VAL_WIDTH: natural
);
port(
clk: in std_logic;
rst: in std_logic;
req: in std_logic;
val: in std_logic_vector(VAL_WIDTH - 1 downto 0);
threshold: in std_logic_vector(VAL_WIDTH - 1 downto 0);
trig: out std_logic
);
end sc_ctrig_thresh;
architecture rtl of sc_ctrig_thresh is
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
trig <= '0';
elsif unsigned(val) > unsigned(threshold) then
trig <= '1';
elsif req = '1' then
trig <= '0';
end if;
end if;
end process;
end rtl;
sc_mon.vhd 0000664 0000000 0000000 00000003304 13132146003 0031776 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_mon.vhd
--
-- Monitors Temperature and Voltages using a Xilinx XADC IP Block
--
-- Lukas Arnold, September 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.top_decl.all;
library unisim;
use unisim.VComponents.all;
entity sc_mon is
port(
clk: in std_logic;
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
);
end sc_mon;
architecture rtl of sc_mon is
signal ipbw: ipb_wbus_array(N_CHAN - 1 downto 0);
signal ipbr: ipb_rbus_array(N_CHAN - 1 downto 0);
signal daddr: std_logic_vector(6 downto 0);
signal regcnt: integer(range 0 to 3);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_CHAN,
SEL_WIDTH => 8
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => chan,
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
process(clk40)
begin
if rst='1' then
regcnt=0;
elsif rising_edge(clk40) then
if regcnt = 3 then
regcnt <= 0;
else
regcnt <= regcnt + 1;
end if;
end if;
end process;
mon : xadc_wiz_0
port map (
di_in => (others => '0'),
daddr_in => std_logic_vector(to_unsigned(regcnt, 6)),
den_in => '1',
dwe_in => '0',
drdy_out => drdy_out,
do_out => do_out,
dclk_in => clk,
reset_in => rst,
vp_in => vp_in,
vn_in => vn_in,
vccaux_alarm_out => vccaux_alarm_out,
channel_out => channel_out,
eoc_out => eoc_out,
alarm_out => alarm_out,
eos_out => eos_out,
busy_out => busy_out
);
q <= chan_q(sel);
q_blkend <= chan_q_blkend(sel);
q_empty <= chan_q_empty(sel);
err <= or_reduce(chan_err);
end rtl;
sc_npeaks.vhd 0000664 0000000 0000000 00000004523 13132146003 0032472 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 2 May 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity sc_npeaks is
generic(windowlength: natural := 7; -- bits
VAL_WIDTH: integer := 14 -- bits
);
port( rst: in std_logic;
clk: in std_logic;
data_in: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
npeaks: out std_logic_vector(windowlength-1 DOWNTO 0)
);
end sc_npeaks;
architecture rtl of sc_npeaks is
signal delayed : integer range 0 to (2**VAL_WIDTH)-1;
signal delayed_two : integer range 0 to (2**VAL_WIDTH)-1;
signal shiftreg : std_logic_vector((2**windowlength)-2 DOWNTO 0);
signal npeaks_buf : integer range 0 to (2**windowlength)-1;
begin
process(rst,clk)
variable delta : integer range -(2**VAL_WIDTH)-1 to (2**VAL_WIDTH)-1 := 0;
variable maximum : boolean := False;
variable maximum_start : integer range 0 to 1 := 0;
variable maximum_end : integer range 0 to 1 := 0;
begin
if rst='1' then
npeaks <= (others=>'0');
delayed <= 0;
delayed_two<= 0;
-- shiftreg <= (others => '0');
npeaks_buf <= 0;
elsif rising_edge(clk) then
--------------------------------
-- Find Maximum --
--------------------------------
delayed <= to_integer(unsigned(data_in));
delayed_two<= delayed;
--Conditions
maximum := (delayed > to_integer(unsigned(threshold)))AND (to_integer(unsigned(data_in))<=delayed) AND (delayed_two < delayed); --//1 clock cycle
--------------------------------
-- Count Maxima --
--------------------------------
case maximum is
when False => maximum_start := 0;
shiftreg(0) <= '0';
when others => maximum_start := 1;
shiftreg(0) <= '1';
end case;
case shiftreg((2**windowlength)-2) is
when '0' => maximum_end := 0;
when others => maximum_end := 1;
end case;
for i in 1 to ((2**windowlength)-2) loop -- not first element
shiftreg(i) <= shiftreg(i-1);
end loop;
npeaks_buf <= npeaks_buf + maximum_start - maximum_end; --//1 clock cycle
end if;
npeaks <= std_logic_vector(to_unsigned(npeaks_buf,windowlength)); --//1 clock cycle
end process;
end architecture rtl;
sc_npeaks_thresh.vhd 0000664 0000000 0000000 00000002506 13132146003 0034046 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 21 September 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_npeaks_thresh is
generic( VAL_WIDTH: natural := 14 -- bit
);
port( rst: in std_logic;
clk: in std_logic;
req: in std_logic; -- request information
d: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold_trig: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold_fe: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
trig: out std_logic
);
end sc_npeaks_thresh;
architecture rtl of sc_npeaks_thresh is
signal feat_val : std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
begin
featextract: entity work.sc_npeaks
generic map (
windowlength => 14, -- bits
VAL_WIDTH => VAL_WIDTH -- bits
)
port map(
rst => rst,
clk => clk,
data_in => d,
threshold => threshold_fe,
npeaks => feat_val
);
thresh : entity work.sc_thresh
generic map (
VAL_WIDTH => VAL_WIDTH -- bits
)
port map(
rst => rst,
clk => clk,
req => req,
val => feat_val,
threshold => threshold_trig,
trig => trig
);
end architecture rtl;
sc_roc.vhd 0000664 0000000 0000000 00000017752 13132146003 0032004 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_roc
--
-- Readout controller and buffer
--
-- Dave Newbold, July 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
library unisim;
use unisim.VComponents.all;
use work.ipbus.all;
use work.ipbus_decode_sc_roc.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_roc is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
board_id: in std_logic_vector(7 downto 0);
clk40: in std_logic;
rst40: in std_logic;
rand: in std_logic_vector(31 downto 0);
d_trig: in std_logic_vector(31 downto 0);
blkend_trig: in std_logic;
we_trig: in std_logic;
veto_trig: out std_logic;
chan: out std_logic_vector(7 downto 0);
d: in std_logic_vector(31 downto 0);
blkend: in std_logic;
empty: in std_logic;
ren: out std_logic
);
end sc_roc;
architecture rtl of sc_roc is
constant CH_WORD: integer := 3;
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(2 downto 0);
signal ctrl_en, ctrl_en_auto, ctrl_occ_freeze, ctrl_occ_clr: std_logic;
signal rsti: std_logic;
signal hfifo_d, hfifo_q, fifo_d, fifo_q: std_logic_vector(35 downto 0);
signal hfifo_wen, hfifo_full, hfifo_empty, hfifo_ren, hfifo_valid: std_logic;
signal fifo_wen, fifo_full, fifo_empty, fifo_ren, fifo_valid: std_logic;
signal rctr, evtlen: unsigned(15 downto 0);
signal dctr: unsigned(31 downto 0);
signal cyc, brcyc, evtdone, evtdone_d, rsrc, err: std_logic;
signal rdata: std_logic_vector(31 downto 0);
signal chan_i: unsigned(7 downto 0);
signal ttype: unsigned(3 downto 0);
signal q_trig: std_logic_vector(31 downto 0);
signal mask: std_logic_vector(63 downto 0);
signal tfifo_full, tfifo_empty, tfifo_ren, tfifo_blkend, tfifo_warn: std_logic;
type state_t is (ST_IDLE, ST_TRIG, ST_DERAND);
signal state: state_t;
signal chandone, ren_i, occ_rst: std_logic;
signal werr, werrb: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_roc(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 3
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl
);
ctrl_en <= ctrl(0)(0);
ctrl_en_auto <= ctrl(0)(1);
ctrl_occ_freeze <= ctrl(0)(2);
ctrl_occ_clr <= ctrl(0)(3);
rsti <= not ctrl_en;
stat(0) <= X"0000" & werrb & werr & err & rsrc & tfifo_blkend & tfifo_warn & tfifo_full & tfifo_empty &
hfifo_q(32) & hfifo_valid & hfifo_full & hfifo_empty & fifo_q(32) & fifo_valid & fifo_full & fifo_empty;
stat(1) <= std_logic_vector(dctr);
stat(2) <= (others => '0'); -- Remove this
-- Buffer read side
cyc <= ipbw(N_SLV_BUF).ipb_strobe and not ipbw(N_SLV_BUF).ipb_write;
brcyc <= ((cyc and not ipbw(N_SLV_BUF).ipb_addr(0)) or (ctrl_en_auto and or_reduce(std_logic_vector(rctr)))) and not fifo_empty;
ipbr(N_SLV_BUF).ipb_rdata <= rdata when ipbw(N_SLV_BUF).ipb_addr(0) = '0' else X"0000" & std_logic_vector(rctr);
ipbr(N_SLV_BUF).ipb_ack <= cyc and not (fifo_empty and not ipbw(N_SLV_BUF).ipb_addr(0));
ipbr(N_SLV_BUF).ipb_err <= cyc and (fifo_empty and not ipbw(N_SLV_BUF).ipb_addr(0));
process(clk)
begin
if rising_edge(clk) then
if rsti = '1' then
rctr <= (others => '0');
dctr <= (others => '0');
elsif brcyc = '1' then
if evtdone_d = '1' then
rctr <= rctr + evtlen;
dctr <= dctr + evtlen;
else
rctr <= rctr - 1;
end if;
elsif evtdone_d = '1' then
rctr <= rctr + evtlen + 1;
dctr <= dctr + evtlen + 1;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if rsti = '1' then
rsrc <= '0';
elsif brcyc = '1' then
if rsrc = '0' then
rsrc <= '1';
elsif fifo_q(32) = '1' then
rsrc <= '0';
end if;
end if;
end if;
end process;
rdata <= hfifo_q(31 downto 0) when rsrc = '0' else fifo_q(31 downto 0);
-- Header buffer
hbuf: entity work.big_fifo_36
generic map(
N_FIFO => 1
)
port map(
clk => clk,
rst => rsti,
d => hfifo_d,
wen => hfifo_wen,
full => hfifo_full,
empty => hfifo_empty,
ctr => open,
ren => hfifo_ren,
q => hfifo_q,
valid => hfifo_valid
);
hfifo_ren <= brcyc and not rsrc;
hfifo_wen <= evtdone_d;
hfifo_d <= X"0AA" & board_id & std_logic_vector(evtlen);
-- Data buffer
dbuf: entity work.big_fifo_36
generic map(
N_FIFO => 2 ** FIFO_RADIX
)
port map(
clk => clk,
rst => rsti,
d => fifo_d,
wen => fifo_wen,
full => fifo_full,
empty => fifo_empty,
ctr => open,
ren => fifo_ren,
q => fifo_q,
valid => fifo_valid
);
fifo_ren <= brcyc and rsrc;
fifo_wen <= tfifo_ren or ren_i or (evtdone and not fifo_full);
fifo_d(35 downto 32) <= "000" & evtdone;
fifo_d(31 downto 0) <= d when state = ST_DERAND else q_trig;
werr <= (werr or (fifo_wen and fifo_full)) and not rsti when rising_edge(clk);
-- Trigger buffer
tbuf: entity work.sc_derand
port map(
clk_w => clk40,
rst_w => rst40,
d => d_trig,
d_blkend => blkend_trig,
wen => we_trig,
clk_r => clk,
q => q_trig,
q_blkend => tfifo_blkend,
empty => tfifo_empty,
ren => tfifo_ren,
warn => tfifo_warn,
full => tfifo_full
);
tfifo_ren <= '1' when state = ST_TRIG and tfifo_empty = '0' and fifo_full = '0' else '0';
veto_trig <= tfifo_warn;
err <= hfifo_full or tfifo_full;
werrb <= (werrb or (we_trig and tfifo_full)) and not rsti when rising_edge(clk40); -- CDC
-- State machine
process(clk)
begin
if rising_edge(clk) then
if rsti = '1' then
state <= ST_IDLE;
else
case state is
when ST_IDLE => -- Starting state
if tfifo_empty = '0' then
state <= ST_TRIG;
end if;
when ST_TRIG => -- Move trigger data
if tfifo_blkend = '1' and fifo_full = '0' then
if ttype /= X"0" or or_reduce(mask) = '0' then
state <= ST_IDLE;
else
state <= ST_DERAND;
end if;
end if;
when ST_DERAND => -- Move event data
if evtdone = '1' and fifo_full = '0' then
state <= ST_IDLE;
end if;
end case;
end if;
end if;
end process;
chandone <= '1' when mask(to_integer(chan_i)) = '0' or blkend = '1' else '0';
evtdone <= '1' when (chan_i = N_CHAN - 1 and chandone = '1' and state = ST_DERAND) or
((ttype /= X"0" or or_reduce(mask) = '0') and tfifo_blkend = '1' and state = ST_TRIG) else '0';
evtdone_d <= evtdone and not fifo_full when rising_edge(clk);
process(clk)
begin
if rising_edge(clk) then
if state = ST_IDLE then
chan_i <= (others => '0');
evtlen <= (others => '0');
else
if fifo_wen = '1' then
evtlen <= evtlen + 1;
end if;
if state = ST_DERAND and chandone = '1' and fifo_full = '0' and evtdone = '0' then
chan_i <= chan_i + 1;
end if;
if state = ST_TRIG then
if evtlen = to_unsigned(0, 16) then
ttype <= unsigned(q_trig(31 downto 28));
elsif evtlen = to_unsigned(CH_WORD, 16) then
mask(31 downto 0) <= q_trig;
elsif evtlen = to_unsigned(CH_WORD + 1, 16) then
mask(63 downto 32) <= q_trig;
end if;
end if;
end if;
end if;
end process;
ren_i <= '1' when state = ST_DERAND and mask(to_integer(chan_i)) = '1' and empty = '0' and fifo_full = '0' else '0';
ren <= ren_i;
chan <= std_logic_vector(chan_i);
-- Occupancy histogram
occ_rst <= ctrl_occ_clr or rsti;
occ: entity work.occ_histo_unscaled
generic map(
BINS_RADIX => 3,
OCC_WIDTH => 11 + FIFO_RADIX
)
port map(
clk => clk,
rst => rsti,
ipb_in => ipbw(N_SLV_OCC),
ipb_out => ipbr(N_SLV_OCC),
clk_s => clk,
rst_s => occ_rst,
occ => std_logic_vector(rctr(10 + FIFO_RADIX downto 0)),
freeze => ctrl_occ_freeze
);
end rtl;
sc_rtrig.vhd 0000664 0000000 0000000 00000001101 13132146003 0032325 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_rtrig
--
-- Random and external trigger generator
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity sc_rtrig is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
rand: in std_logic_vector(31 downto 0);
sctr: in std_logic_vector(47 downto 0);
force: out std_logic
);
end sc_rtrig;
architecture rtl of sc_rtrig is
begin
ipb_out <= IPB_RBUS_NULL;
force <= '0';
end rtl;
sc_seq.vhd 0000664 0000000 0000000 00000011143 13132146003 0031775 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_seq
--
-- Maintains list of future readouts and issues them
-- This implementation assumes all channels are read out or not
-- In the future, might have to split into regions with one sequence buffer per region
--
-- Keep and flush are high on mark
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_decode_sc_seq.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_seq is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
zs_en: in std_logic;
sctr: in std_logic_vector(31 downto 0);
d_loc: in std_logic_vector(15 downto 0);
valid_loc: in std_logic;
ack_loc: out std_logic;
d_ext: in std_logic_vector(15 downto 0);
valid_ext: in std_logic;
ack_ext: out std_logic;
keep: out std_logic_vector(N_CHAN - 1 downto 0);
flush: out std_logic_vector(N_CHAN - 1 downto 0);
err: out std_logic
);
end sc_seq;
architecture rtl of sc_seq is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal td: std_logic_vector(15 downto 0);
signal tv, terr: std_logic;
signal we: std_logic;
signal d_ram, q_ram: std_logic_vector(15 downto 0);
signal a_ram: std_logic_vector(BUF_RADIX - 1 downto 0);
signal ptr, ctr: unsigned(BUF_RADIX - 1 downto 0);
signal nclk40, rseq, keep_i: std_logic;
signal q_s_ram: std_logic_vector(31 downto 0);
type tctr_t is array(N_TRG - 1 downto 0) of unsigned(31 downto 0);
signal tctr: tctr_t;
signal crst: std_logic;
signal cinc: std_logic_vector(N_TRG - 1 downto 0);
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_seq(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- Trigger input
td <= d_loc when valid_loc = '1' else d_ext;
tv <= (valid_loc or valid_ext) and not rseq and zs_en;
ack_loc <= valid_loc;
ack_ext <= valid_ext and not valid_loc;
process(clk40)
begin
if rising_edge(clk40) then
terr <= (terr or ((valid_loc or valid_ext) and rseq)) and zs_en;
end if;
end process;
err <= terr;
-- Trigger counters
process(td, tv) -- Encoded -> one hot. God dammit VHDL.
begin
for i in N_TRG - 1 downto 0 loop
if tv = '1' and to_integer(unsigned(td(3 downto 0))) = i then
cinc(i) <= '1';
else
cinc(i) <= '0';
end if;
end loop;
end process;
crst <= not zs_en;
cnt: entity work.ipbus_ctrs_ported
generic map(
N_CTRS => N_TRG
)
port map(
ipb_clk => clk,
ipb_rst => rst,
ipb_in => ipbw(N_SLV_CTRS),
ipb_out => ipbr(N_SLV_CTRS),
clk => clk40,
rst => crst,
inc => cinc
);
-- Trigger offset / length table
nclk40 <= not clk40;
sram: entity work.ipbus_ported_dpram
generic map(
ADDR_WIDTH => 4,
DATA_WIDTH => 32
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CONF),
ipb_out => ipbr(N_SLV_CONF),
rclk => nclk40,
we => '0',
d => (others => '0'),
q => q_s_ram,
addr => td(3 downto 0)
);
-- Current block pointer
ptr <= unsigned(sctr(BLK_RADIX + BUF_RADIX - 1 downto BLK_RADIX));
rseq <= and_reduce(sctr(BLK_RADIX - 1 downto 2));
-- Sequence RAM
ram: entity work.ipbus_ported_dpram
generic map(
ADDR_WIDTH => BUF_RADIX,
DATA_WIDTH => 16
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_BUF),
ipb_out => ipbr(N_SLV_BUF),
rclk => clk40,
we => we,
d => d_ram,
q => q_ram,
addr => a_ram
);
we <= '1' when (tv = '1' and unsigned(d_ram) > unsigned(q_ram)) or (rseq = '1' and sctr(1 downto 0) = "11") else '0';
a_ram <= std_logic_vector(ptr + unsigned(q_s_ram(BUF_RADIX - 1 downto 0))) when rseq = '0' else std_logic_vector(ptr);
d_ram <= q_s_ram(31 downto 16) when rseq = '0' else (others => '0');
-- Pending blocks counter
process(clk40)
begin
if rising_edge(clk40) then
if zs_en = '0' then
ctr <= (others => '0');
keep_i <= '0';
elsif rseq = '1' then
if sctr(1 downto 0) = "01" then
if unsigned(q_ram(ctr'range)) > ctr then
ctr <= unsigned(q_ram(ctr'range));
end if;
elsif sctr(1 downto 0) = "10" then
if ctr /= (ctr'range => '0') then
ctr <= ctr - 1;
keep_i <= '1';
else
keep_i <= '0';
end if;
end if;
end if;
end if;
end process;
keep <= (keep'range => keep_i);
flush <= not (flush'range => keep_i);
end rtl;
sc_thresh.vhd 0000664 0000000 0000000 00000002752 13132146003 0032510 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 2 May 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
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 sc_thresh is
generic( VAL_WIDTH: natural := 8 -- bit
);
port( rst: in std_logic;
clk: in std_logic;
req: in std_logic; -- request information
val: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
trig: out std_logic
);
end sc_thresh;
architecture rtl of sc_thresh is
signal triggered : std_logic;
begin
process(rst,clk)
variable abovethreshold : boolean := False;
begin
if rst='1' then
trig <= '0';
triggered <= '0';
abovethreshold := False;
elsif rising_edge(clk) then
abovethreshold := to_integer(unsigned(val))>=to_integer(unsigned(threshold));
if abovethreshold = True then
triggered <= '1';
end if;
if req='1' then
triggered <= '0';
end if;
if req='1' and triggered='1' then
trig <= '1';
else
trig <= '0';
end if;
end if;
end process;
end architecture rtl;
sc_timing.vhd 0000664 0000000 0000000 00000012477 13132146003 0032507 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_timing
--
-- MMCM, sample counters and synchronous control
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_timing is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
rst_mmcm: in std_logic; -- MMCM reset
locked: out std_logic; -- MMCM locked signal
clk_in_p: in std_logic; -- 40MHz clock from pins
clk_in_n: in std_logic;
clk40: out std_logic; -- chip 40MHz clock
rst40: out std_logic; -- clk40 domain reset
clk160: out std_logic; -- chip 160MHz clock
clk280: out std_logic; -- chip 280MHz clock
sync_in: in std_logic; -- external sync signal in
trig_in: in std_logic; -- external trigger in
sctr: out std_logic_vector(47 downto 0); -- sample counter
chan_sync_ctrl: out std_logic_vector(3 downto 0); -- Timing signals to channels
trig_en: out std_logic;
nzs_en: out std_logic;
zs_en: out std_logic;
rand: out std_logic_vector(31 downto 0)
);
end sc_timing;
architecture rtl of sc_timing is
signal clk40_a, rst40_a, clk160_a, clk280_a, clk40_i, rst40_i: std_logic;
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(4 downto 0);
signal stb: std_logic_vector(0 downto 0);
signal sctr_i, sctr_s: unsigned(47 downto 0);
signal rst_ctr: unsigned(3 downto 0);
signal ctrl_rst_ctr, ctrl_cap_ctr, ctrl_en_sync, ctrl_force_sync, ctrl_pipeline_en, ctrl_send_sync: std_logic;
signal ctrl_chan_slip, ctrl_chan_rst_buf, ctrl_chan_cap, ctrl_chan_inc: std_logic;
signal frst, sync, sync_f, wait_sync, sync_err, io_err: std_logic;
signal sync_in_r, trig_in_r, trig_in_r_d: std_logic;
signal sync_ctr, trig_ctr: unsigned(31 downto 0);
begin
-- Clock generation
mmcm: entity work.sc_clocks
port map(
clk_in_p => clk_in_p,
clk_in_n => clk_in_n,
clk40 => clk40_a,
clk160 => clk160_a,
clk280 => clk280_a,
locked => locked,
rst_mmcm => rst_mmcm,
rsti => ctrl(0)(0),
rst40 => rst40_a
);
clk40_i <= clk40_a;
clk40 <= clk40_a;
rst40_i <= rst40_a;
rst40 <= rst40_a;
clk160 <= clk160_a;
clk280 <= clk280_a;
-- Control register
csr: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 1,
N_STAT => 5
)
port map(
clk => clk,
rst => rst,
ipb_in => ipb_in,
ipb_out => ipb_out,
slv_clk => clk40_i,
d => stat,
q => ctrl,
stb => stb
);
ctrl_rst_ctr <= ctrl(0)(1);
ctrl_cap_ctr <= ctrl(0)(2);
ctrl_en_sync <= ctrl(0)(3);
ctrl_force_sync <= ctrl(0)(4);
ctrl_pipeline_en <= ctrl(0)(5);
ctrl_send_sync <= ctrl(0)(6);
ctrl_chan_slip <= ctrl(0)(12);
ctrl_chan_rst_buf <= ctrl(0)(13);
ctrl_chan_cap <= ctrl(0)(14);
ctrl_chan_inc <= ctrl(0)(15);
stat(0) <= X"0000000" & '0' & io_err & sync_err & wait_sync;
stat(1) <= std_logic_vector(sctr_s(31 downto 0));
stat(2) <= X"0000" & std_logic_vector(sctr_s(47 downto 32));
stat(3) <= std_logic_vector(sync_ctr);
stat(4) <= std_logic_vector(trig_ctr);
-- External timing signals
sync_in_r <= sync_in when rising_edge(clk40_i); -- Should be IOB reg
trig_in_r <= trig_in when rising_edge(clk40_i); -- Should be IOB reg
trig_in_r_d <= trig_in_r when rising_edge(clk40_i);
process(clk40_i)
begin
if rising_edge(clk40_i) then
if rst40_i = '1' then
sync_ctr <= (others => '0');
trig_ctr <= (others => '0');
else
if sync_in_r = '1' then
sync_ctr <= sync_ctr + 1;
end if;
if trig_in_r = '1' and trig_in_r_d = '0' then
trig_ctr <= trig_ctr + 1;
end if;
end if;
end if;
end process;
-- Sync signals
sync <= (sync_in_r and ctrl_en_sync) or (ctrl_force_sync and stb(0));
sync_f <= sync and wait_sync;
process(clk40_i)
begin
if rising_edge(clk40_i) then
if rst40_i = '1' then
wait_sync <= '1';
sync_err <= '0';
else
if sync = '1' then
wait_sync <= '0';
if wait_sync = '0' and or_reduce(std_logic_vector(sctr_i(BLK_RADIX - 1 downto 0))) /= '0' then
sync_err <= '1';
end if;
end if;
end if;
end if;
end process;
io_err <= '1';
-- Sample counter
process(clk40_i)
begin
if rising_edge(clk40_i) then
if rst40_i = '1' or sync_f = '1' then
sctr_i <= (others => '0');
else
sctr_i <= sctr_i + 1;
end if;
if stb(0) = '1' and ctrl_cap_ctr = '1' then
sctr_s <= sctr_i;
end if;
end if;
end process;
sctr <= std_logic_vector(sctr_i);
-- Random number gen
rng: entity work.rng_wrapper
port map(
clk => clk40_i,
rst => wait_sync,
random => rand
);
-- System enables
timing: entity work.sc_timing_startup
port map(
clk40 => clk40_i,
rst40 => rst40_i,
en => ctrl_pipeline_en,
sync => sync_f,
sctr => sctr_i,
nzs_en => nzs_en,
zs_en => zs_en,
trig_en => trig_en
);
-- Channel sync control
process(clk40_i)
begin
if rising_edge(clk40_i) then
if rst40_i = '1' then
rst_ctr <= "0000";
elsif frst = '1' or (ctrl_chan_rst_buf = '1' and stb(0) = '1') then
rst_ctr <= rst_ctr + 1;
end if;
end if;
end process;
frst <= '1' when rst_ctr /= "1111" else '0';
chan_sync_ctrl(0) <= ctrl_chan_slip and stb(0); -- bitslip for serdes
chan_sync_ctrl(1) <= frst; -- reset channel
chan_sync_ctrl(2) <= ctrl_chan_cap and stb(0); -- cap start
chan_sync_ctrl(3) <= ctrl_chan_inc and stb(0); -- cap start
end rtl;
sc_timing_startup.vhd 0000664 0000000 0000000 00000002400 13132146003 0034252 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_timing_startup
--
-- Controls various enables to set up data flow through buffers, etc
--
-- Dave Newbold, July 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_timing_startup is
port(
clk40: in std_logic;
rst40: in std_logic;
en: in std_logic;
sync: in std_logic;
sctr: in unsigned(47 downto 0);
nzs_en: out std_logic;
zs_en: out std_logic;
trig_en: out std_logic
);
end sc_timing_startup;
architecture rtl of sc_timing_startup is
signal up: std_logic;
begin
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' or en = '0' then
up <= '0';
nzs_en <= '0';
zs_en <= '0';
trig_en <= '0';
else
if sync = '1' then
up <= '1';
end if;
if up = '1' then
if and_reduce(std_logic_vector(sctr(BLK_RADIX - 1 downto 0))) = '1' then
if unsigned(sctr(3 + BLK_RADIX downto BLK_RADIX)) = 8 then
nzs_en <= '1';
elsif unsigned(sctr(3 + BLK_RADIX downto BLK_RADIX)) = 8 + NZS_BLKS then
zs_en <= '1';
elsif unsigned(sctr(7 + BLK_RADIX downto BLK_RADIX)) = 7 + NZS_BLKS + ZS_BLKS then
trig_en <= '1';
end if;
end if;
end if;
end if;
end if;
end process;
end rtl;
sc_tot.vhd 0000664 0000000 0000000 00000004317 13132146003 0032020 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 2 May 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
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 sc_tot is
generic(windowlength: natural := 7; --bit
VAL_WIDTH: integer := 14 --bit
); -- -1
port( rst: in std_logic;
clk: in std_logic;
data_in: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
totval: out std_logic_vector(windowlength-1 DOWNTO 0)
);
end sc_tot;
architecture rtl of sc_tot is
signal totbuff : integer range 0 to (2**VAL_WIDTH)-1;
signal shiftreg : std_logic_vector((2**windowlength)-1 DOWNTO 0);
-- Shift register from 0-1 (current) to windowlength-1
-- = 0 to windowlength-2
begin
process(rst,clk)
variable val : boolean := False;
variable val_start : integer range 0 to 1 := 0;
variable val_end : integer range 0 to 1 := 0;
begin
if rst='1' then
totval<= (others=>'0');
totbuff<= 0;
--shiftreg <= (others => '0');
elsif rising_edge(clk) then
--------------------------------
-- Find Maximum --
--------------------------------
val := to_integer(unsigned(data_in)) >= to_integer(unsigned(threshold));
--------------------------------
-- Count ToT --
--------------------------------
case val is
when False => val_start := 0;
shiftreg(0) <= '0';
when others => val_start := 1;
shiftreg(0) <= '1';
end case;
case shiftreg(windowlength-1) is
when '0' => val_end := 0;
when others => val_end := 1;
end case;
for i in 1 to windowlength-1 loop -- not first element
shiftreg(i) <= shiftreg(i-1);
end loop;
totbuff <= totbuff + val_start - val_end;
end if;
totval <= std_logic_vector(to_unsigned(totbuff,windowlength));
end process;
end architecture rtl;
sc_tot_thresh.vhd 0000664 0000000 0000000 00000002473 13132146003 0033376 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl ----------------------------------------------------------------------------------
-- Lukas Arnold, University of Bristol
-- 21 September 2016
-- SoLid Experiment
-- r0.01
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_tot_thresh is
generic( VAL_WIDTH: natural := 14 -- bit
);
port( rst: in std_logic;
clk: in std_logic;
req: in std_logic; -- request information
d: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold_trig: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
threshold_fe: in std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
trig: out std_logic
);
end sc_tot_thresh;
architecture rtl of sc_tot_thresh is
signal feat_val : std_logic_vector(VAL_WIDTH-1 DOWNTO 0);
begin
featextract: entity work.sc_tot
generic map (
windowlength => 14, -- bits
VAL_WIDTH => VAL_WIDTH -- bits
)
port map(
rst => rst,
clk => clk,
data_in => d,
threshold => threshold_fe,
totval => feat_val
);
thresh : entity work.sc_thresh
generic map (
VAL_WIDTH => VAL_WIDTH -- bits
)
port map(
rst => rst,
clk => clk,
req => req,
val => feat_val,
threshold => threshold_trig,
trig => trig
);
end architecture rtl;
sc_trig.vhd 0000664 0000000 0000000 00000016146 13132146003 0032162 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig
--
-- Trigger generation
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_decode_sc_trig.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_trig is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
clk160: in std_logic;
trig_en: in std_logic;
zs_en: in std_logic;
sctr: in std_logic_vector(47 downto 0);
rand: in std_logic_vector(31 downto 0);
keep: out std_logic_vector(N_CHAN - 1 downto 0);
flush: out std_logic_vector(N_CHAN - 1 downto 0);
veto: in std_logic_vector(N_CHAN - 1 downto 0);
zs_sel: out std_logic_vector(1 downto 0);
trig: in sc_trig_array;
force: in std_logic;
ext_trig_in: in std_logic;
ext_trig_out: out std_logic;
ro_d: out std_logic_vector(31 downto 0);
ro_blkend: out std_logic;
ro_we: out std_logic;
ro_veto: in std_logic;
q: out std_logic_vector(15 downto 0);
q_valid: out std_logic;
d: in std_logic_vector(15 downto 0);
d_valid: in std_logic;
d_ack: out std_logic
);
end sc_trig;
architecture rtl of sc_trig is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl, ctrl_mask: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(1 downto 0);
signal stb: std_logic_vector(0 downto 0);
signal ctrl_dtmon_en, ctrl_trig_in_en, ctrl_trig_out_force: std_logic;
signal masks: ipb_reg_v(N_CHAN_TRG * 2 - 1 downto 0);
signal trig_mask: std_logic_vector(N_TRG - 1 downto 0);
signal ctrig: sc_trig_array;
signal lq: std_logic_vector(15 downto 0);
signal rveto, lvalid, lack, mark, err: std_logic;
signal zs_cfg: std_logic_vector(31 downto 0);
signal veto_p, veto_i, keep_i, flush_i: std_logic_vector(N_CHAN - 1 downto 0);
signal b_q, t_q: std_logic_vector(31 downto 0);
signal b_go, t_go, b_valid, t_valid, b_blkend, t_blkend, blkend: std_logic;
signal tctr: std_logic_vector(27 downto 0);
signal ro_ctr: std_logic_vector(7 downto 0);
signal trig_in, trig_out: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_sc_trig(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- Control register
csr: entity work.ipbus_syncreg_v
generic map(
N_CTRL => 1,
N_STAT => 2
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_CSR),
ipb_out => ipbr(N_SLV_CSR),
slv_clk => clk40,
d => stat,
q => ctrl,
stb => stb
);
ctrl_dtmon_en <= ctrl(0)(0);
ctrl_trig_in_en <= ctrl(0)(1);
ctrl_trig_out_force <= ctrl(0)(2) and stb(0);
stat(0) <= X"0" & tctr;
stat(1) <= X"0000000" & "00" & rveto & err;
-- Readout veto (eventually also set under error conditions
-- on trigger links, dtmon, etc)
mark <= trig_en and and_reduce(sctr(BLK_RADIX - 1 downto 0));
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' then
rveto <= '0';
elsif mark = '1' then
rveto <= ro_veto;
end if;
end if;
end process;
-- Channel trigger masks
mask: entity work.ipbus_reg_v
generic map(
N_REG => N_CHAN_TRG * 2
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_CHAN_MASK),
ipbus_out => ipbr(N_SLV_CHAN_MASK),
q => masks
);
mgen: for i in N_CHAN_TRG - 1 downto 0 generate
signal m: std_logic_vector(63 downto 0);
begin
m <= masks(i * 2 + 1) & masks(i * 2);
ctrig(i) <= trig(i) and m(N_CHAN - 1 downto 0);
end generate;
-- Local trigger logic
ltrig_reg: entity work.ipbus_reg_v
generic map(
N_REG => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_LOC_MASK),
ipbus_out => ipbr(N_SLV_LOC_MASK),
q => ctrl_mask,
qmask(0) => (N_TRG - 1 downto 0 => '1', others => '0')
);
trig_mask <= ctrl_mask(0)(N_TRG - 1 downto 0);
ltrig: entity work.sc_local_trig
port map(
clk40 => clk40,
rst40 => rst40,
en => trig_en,
mask => trig_mask,
mark => mark,
sctr => sctr,
rand => rand,
chan_trig => ctrig,
trig_q => lq,
trig_valid => lvalid,
trig_ack => lack,
force => force,
ext_trig_in => ext_trig_in,
ro_q => t_q,
ro_valid => t_valid,
ro_blkend => t_blkend,
ro_go => t_go,
ro_ctr => ro_ctr,
rveto => rveto
);
q <= lq;
q_valid <= lvalid;
-- ZS threshold select
zsreg: entity work.ipbus_reg_v
generic map(
N_REG => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_ZS_CFG),
ipbus_out => ipbr(N_SLV_ZS_CFG),
q(0) => zs_cfg
);
zssel: entity work.sc_zs_sel
port map(
clk40 => clk40,
rst40 => rst40,
mark => mark,
zscfg => zs_cfg,
trig => lq,
trig_valid => lvalid,
sel => zs_sel
);
-- Readout sequencer
seq: entity work.sc_seq
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_SEQ),
ipb_out => ipbr(N_SLV_SEQ),
clk40 => clk40,
rst40 => rst40,
zs_en => zs_en,
sctr => sctr(31 downto 0),
d_loc => lq,
valid_loc => lvalid,
ack_loc => lack,
d_ext => d,
valid_ext => d_valid,
ack_ext => d_ack,
keep => keep_i,
flush => flush_i,
err => err
);
-- Channel interface
veto_p <= veto or (veto'range => rveto);
keep <= keep_i and not veto_p when mark = '1' else (others => '0');
flush <= not keep_i or veto_p when mark = '1' else (others => '0');
process(clk40)
begin
if rising_edge(clk40) then
if trig_en = '0' then
veto_i <= (others => '0');
elsif mark = '1' then
veto_i <= veto_p;
end if;
end if;
end process;
-- Readout header to ROC
rdata: entity work.sc_trig_ro_block
port map(
clk40 => clk40,
rst40 => rst40,
trig_en => trig_en,
sctr => sctr,
mark => mark,
keep => keep_i,
veto => veto_i,
tctr => tctr,
ro_q => b_q,
ro_valid => b_valid,
ro_blkend => b_blkend,
ro_go => b_go,
ro_ctr => ro_ctr,
rveto => rveto
);
-- ROC output
b_go <= mark;
t_go <= and_reduce(sctr(4 downto 0)) and not or_reduce(sctr(BLK_RADIX - 1 downto 5));
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' or blkend = '1' then
ro_ctr <= (others => '0');
elsif b_valid = '1' or t_valid = '1' then
ro_ctr <= std_logic_vector(unsigned(ro_ctr) + 1);
end if;
end if;
end process;
ro_d <= t_q when t_valid = '1' else b_q;
ro_we <= b_valid or t_valid;
blkend <= (b_blkend and b_valid) or (t_blkend and t_valid);
ro_blkend <= blkend;
-- Deadtime monitor
dmon: entity work.sc_deadtime_mon
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_DTMON),
ipb_out => ipbr(N_SLV_DTMON),
en => ctrl_dtmon_en,
clk40 => clk40,
rst40 => rst40,
clk160 => clk160,
mark => mark,
sctr => sctr(BLK_RADIX - 1 downto 0),
keep => keep_i,
veto => veto_i
);
-- Ext trigger
trig_in <= ext_trig_in when rising_edge(clk40); -- Should be IOB reg
trig_out <= '0';
ext_trig_out <= trig_out or ctrl_trig_out_force when falling_edge(clk40); -- Should be IOB reg
end rtl;
sc_trig_dummy.vhd 0000664 0000000 0000000 00000001363 13132146003 0033370 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_dummy.vhd
--
-- Threshold-based placeholder for trigger generator block
--
-- Dave Newbold, July 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_trig_dummy is
generic(
VAL_WIDTH: natural
);
port(
clk: in std_logic;
rst: in std_logic;
req: in std_logic;
val: in std_logic_vector(VAL_WIDTH - 1 downto 0);
threshold: in std_logic_vector(VAL_WIDTH - 1 downto 0);
trig: out std_logic
);
end sc_trig_dummy;
architecture rtl of sc_trig_dummy is
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
trig <= '0';
elsif unsigned(val) > unsigned(threshold) then
trig <= '1';
elsif req = '1' then
trig <= '0';
end if;
end if;
end process;
end rtl;
sc_trig_gen.vhd 0000664 0000000 0000000 00000002165 13132146003 0033007 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_gen
--
-- Local trigger module based on an incoming bit
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_trig_gen is
generic(
DELAY: positive := 1
);
port(
clk: in std_logic;
en: in std_logic;
mark: in std_logic;
trig: in std_logic;
hit: out std_logic;
valid: out std_logic;
ack: in std_logic
);
end sc_trig_gen;
architecture rtl of sc_trig_gen is
signal t, m, tc, v: std_logic;
signal mark_del: std_logic_vector(DELAY - 1 downto 0);
begin
-- Define the trigger condition and block boundary
t <= trig;
mark_del <= mark_del(DELAY - 2 downto 0) & mark when rising_edge(clk);
m <= mark_del(DELAY - 1);
-- Catch a trigger feature with the block
process(clk)
begin
if rising_edge(clk) then
if en = '0' then
tc <= '0';
elsif t = '1' then
tc <= '1';
elsif m = '1' then
tc <= '0';
end if;
end if;
end process;
-- Trigger request output
hit <= t;
v <= (v or (tc and m)) and not (mark or ack or not en) when rising_edge(clk);
valid <= v;
end rtl;
sc_trig_gen_or.vhd 0000664 0000000 0000000 00000003076 13132146003 0033511 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_gen_or
--
-- Local trigger module for simple 'ored' threshold triggers
-- This trigger will fire if any channel has a high bit in a given block
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_trig_gen_or is
generic(
TBIT: natural := 0;
DELAY: positive := 1
);
port(
clk: in std_logic;
en: in std_logic;
mark: in std_logic;
chan_trig: in sc_trig_array;
hit: out std_logic;
chan_act: out std_logic_vector(N_CHAN - 1 downto 0);
valid: out std_logic;
ack: in std_logic
);
end sc_trig_gen_or;
architecture rtl of sc_trig_gen_or is
signal t, m, tc, v: std_logic;
signal mark_del: std_logic_vector(DELAY - 1 downto 0);
signal c: std_logic_vector(N_CHAN - 1 downto 0);
begin
-- Define the trigger condition and block boundary
t <= or_reduce(chan_trig(TBIT));
mark_del <= mark_del(DELAY - 2 downto 0) & mark when rising_edge(clk);
m <= mark_del(DELAY - 1);
-- Catch a trigger feature with the block
process(clk)
begin
if rising_edge(clk) then
if en = '0' then
tc <= '0';
c <= (others => '0');
elsif t = '1' then
tc <= '1';
if m = '0' then
c <= c or chan_trig(TBIT);
else
c <= chan_trig(TBIT);
end if;
elsif m = '1' then
tc <= '0';
c <= (others => '0');
end if;
end if;
end process;
-- Trigger request output
hit <= t;
v <= (v or (tc and m)) and not (mark or ack or not en) when rising_edge(clk);
valid <= v;
chan_act <= c when m = '1' and rising_edge(clk);
end rtl;
sc_trig_gen_random.vhd 0000664 0000000 0000000 00000002674 13132146003 0034354 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_gen_random
--
-- Local trigger module for random / regular triggers
--
-- We produce valid signal on cycle after mark
--
-- mode(1): enable random / seq triggers
-- mode(0): 0: random; 1: seq
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_trig_gen_random is
port(
clk: in std_logic;
en: in std_logic;
mode: in std_logic_vector(1 downto 0);
sctr: in std_logic_vector(31 downto 0);
rand: in std_logic_vector(31 downto 0);
div: in std_logic_vector(5 downto 0);
mark: in std_logic;
force: in std_logic;
valid: out std_logic;
ack: in std_logic
);
end sc_trig_gen_random;
architecture rtl of sc_trig_gen_random is
signal mask: std_logic_vector(23 downto 0);
signal rtrig, force_c, force_d: std_logic;
signal v: std_logic;
begin
mgen: for i in mask'range generate
mask(i) <= '0' when i > to_integer(unsigned(div)) else '1';
end generate;
process(clk)
begin
if rising_edge(clk) then
force_d <= force;
force_c <= (force_c or (force and not force_d)) and not mark and en;
end if;
end process;
rtrig <= ((not mode(0) and not or_reduce(rand(mask'range) and mask)) or
(mode(0) and not or_reduce(sctr(BLK_RADIX + mask'left downto BLK_RADIX) and mask))) and mode(1);
v <= ((v and not mark) or ((rtrig or force_c) and mark)) and not (ack or not en) when rising_edge(clk);
valid <= v;
end rtl;
sc_trig_link.vhd 0000664 0000000 0000000 00000001304 13132146003 0033165 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_link
--
-- Trigger communication between planes
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity sc_trig_link is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk125: in std_logic;
rst125: in std_logic;
clk40: in std_logic;
rst40: in std_logic;
d: in std_logic_vector(15 downto 0);
d_valid: in std_logic;
q: out std_logic_vector(15 downto 0);
q_valid: out std_logic;
ack: in std_logic
);
end sc_trig_link;
architecture rtl of sc_trig_link is
begin
ipb_out <= IPB_RBUS_NULL;
q <= (others => '0');
q_valid <= '0';
end rtl;
sc_trig_ro_block.vhd 0000664 0000000 0000000 00000004101 13132146003 0034020 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_trig_ro_block
--
-- Header data to ROC for each readout
-- Sends data at block start
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_trig_ro_block is
port(
clk40: in std_logic;
rst40: in std_logic;
trig_en: in std_logic;
sctr: in std_logic_vector(47 downto 0);
mark: in std_logic;
keep: in std_logic_vector(N_CHAN - 1 downto 0);
veto: in std_logic_vector(N_CHAN - 1 downto 0);
tctr: out std_logic_vector(27 downto 0);
ro_q: out std_logic_vector(31 downto 0);
ro_valid: out std_logic;
ro_blkend: out std_logic;
ro_go: in std_logic;
ro_ctr: in std_logic_vector(7 downto 0);
rveto: in std_logic
);
end sc_trig_ro_block;
architecture rtl of sc_trig_ro_block is
constant OFFSET: integer := (NZS_BLKS + ZS_BLKS) * 2 ** BLK_RADIX;
signal tctr_i: unsigned(27 downto 0);
signal go, blkend: std_logic;
signal chen, keep_c: std_logic_vector(63 downto 0);
begin
-- Trigger counter
process(clk40)
begin
if rising_edge(clk40) then
if trig_en = '0' then
tctr_i <= (others => '0');
elsif mark = '1' and or_reduce(keep) = '1' then
tctr_i <= tctr_i + 1;
end if;
end if;
end process;
tctr <= std_logic_vector(tctr_i);
-- Block data to ROC
chen <= (63 downto N_CHAN => '0') & (keep and not veto); -- Assumption on 64 channels max here...
keep_c <= (63 downto N_CHAN => '0') & keep;
go <= (go or (ro_go and or_reduce(keep) and not rveto)) and not blkend and trig_en when rising_edge(clk40);
blkend <= '1' when ro_ctr = X"06" else '0';
ro_valid <= go;
ro_blkend <= blkend;
with ro_ctr select ro_q <=
X"0" & std_logic_vector(tctr_i) when X"00", -- Type 0
std_logic_vector(unsigned(sctr(31 downto 1) & '0') - OFFSET) when X"01", -- Hack so that counter is taken at start-of-block
X"0000" & std_logic_vector(sctr(47 downto 32)) when X"02",
chen(31 downto 0) when X"03", -- Corresponds to CH_WORD = 3 in sc_roc
chen(63 downto 32) when X"04",
keep_c(31 downto 0) when X"05",
keep_c(63 downto 32) when others;
end rtl;
sc_zs_sel.vhd 0000664 0000000 0000000 00000002307 13132146003 0032506 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- sc_zs_sel
--
-- Random and external trigger generator
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.top_decl.all;
entity sc_zs_sel is
port(
clk40: in std_logic;
rst40: in std_logic;
mark: in std_logic;
zscfg: in std_logic_vector(31 downto 0);
trig: in std_logic_vector(15 downto 0);
trig_valid: in std_logic;
sel: out std_logic_vector(1 downto 0)
);
end sc_zs_sel;
architecture rtl of sc_zs_sel is
signal mark_del: std_logic_vector(ZS_DEL - 1 downto 0);
signal m, g: std_logic;
signal t: unsigned(3 downto 0);
begin
mark_del <= mark_del(ZS_DEL - 2 downto 0) & mark when rising_edge(clk40);
m <= mark_del(ZS_DEL - 1);
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' or m = '1' then
t <= (others => '0');
g <= '0';
elsif trig_valid = '1' then
g <= '1';
if unsigned(trig(3 downto 0)) > t then
t <= unsigned(trig(3 downto 0));
end if;
end if;
if rst40 = '1' then
sel <= "00";
elsif m = '1' then
if g = '0' then
sel <= "00";
else
sel <= zscfg(to_integer(t) * 2 + 1 downto to_integer(t) * 2);
end if;
end if;
end if;
end process;
end rtl;
scaled_ctr.vhd 0000664 0000000 0000000 00000002136 13132146003 0032625 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/hdl -- scaled_ctr
--
-- Exponent + mantissa counter for large values
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity scaled_ctr is
generic(
MANTISSA_BITS: natural := 8;
EXPONENT_BITS: natural := 8
);
port(
clk: in std_logic;
rst: in std_logic;
inc: in std_logic;
m: out std_logic_vector(MANTISSA_BITS - 1 downto 0);
e: out std_logic_vector(EXPONENT_BITS - 1 downto 0)
);
end scaled_ctr;
architecture rtl of scaled_ctr is
signal mctr: unsigned(MANTISSA_BITS - 1 downto 0);
signal ectr: unsigned(EXPONENT_BITS - 1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
mctr <= (others => '0');
ectr <= (others => '0');
elsif inc = '1' then
if mctr = (mctr'range => '1') then
if ectr /= (ectr'range => '1') then
mctr(mctr'left) <= '1';
mctr(mctr'left - 1 downto 0) <= (others => '0');
ectr <= ectr + 1;
end if;
else
mctr <= mctr + 1;
end if;
end if;
end if;
end process;
m <= std_logic_vector(mctr);
e <= std_logic_vector(ectr);
end rtl;
sim_hdl/ 0000775 0000000 0000000 00000000000 13132146003 0030665 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware sc_clocks_sim.vhd 0000664 0000000 0000000 00000003036 13132146003 0034205 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/sim_hdl -- sc_clocks_sim
--
-- Simulation of clock generation; should be OK for delta delays
--
-- Dave Newbold, July 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.VComponents.all;
entity sc_clocks is
port(
clk_in_p: in std_logic; -- Input clock (nominally 40MHz)
clk_in_n: in std_logic;
clk40: out std_logic; -- Sample clock (nominally 40MHz)
clk80: out std_logic; -- Processing clock (2 * clk_s)
clk160: out std_logic; -- Processing clock (4 * clk_s)
clk280: out std_logic; -- iserdes clock (7 * clk_s)
locked: out std_logic;
rst_mmcm: in std_logic;
rsti: in std_logic;
rst40: out std_logic
);
end sc_clocks;
architecture rtl of sc_clocks is
signal clk_master: std_logic := '0';
signal ctr: unsigned(4 downto 0) := "00000";
signal clk40_u, clk40_i, clk80_u, clk160_u, clk280_u: std_logic := '1';
signal locked_i: std_logic := '0';
begin
process
begin
if ctr = 27 then
ctr <= "00000";
else
ctr <= ctr + 1;
end if;
wait for 0.5 ns;
end process;
clk40_u <= not clk40_u when ctr'event and ctr mod 28 = 0;
clk80_u <= not clk80_u when ctr'event and ctr mod 14 = 0;
clk160_u <= not clk160_u when ctr'event and ctr mod 7 = 0;
clk280_u <= not clk280_u when ctr'event and ctr mod 4 = 0;
clk40 <= clk40_u;
clk40_i <= clk40_u;
clk80 <= clk80_u;
clk160 <= clk160_u;
clk280 <= clk280_u;
locked_i <= '1' after 200 ns;
locked <= locked_i;
process(clk40_i)
begin
if rising_edge(clk40_i) then
rst40 <= rsti or not locked_i;
end if;
end process;
end rtl;
sc_daq_sim.vhd 0000664 0000000 0000000 00000010406 13132146003 0033473 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/firmware/sim_hdl -- daq.vhd
--
-- Core components of the DAQ, independent of board type
--
-- Dave Newbold, May 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
use work.top_decl.all;
entity sc_daq_sim is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in_timing: in ipb_wbus;
ipb_out_timing: out ipb_rbus;
ipb_in_chan: in ipb_wbus;
ipb_out_chan: out ipb_rbus;
ipb_in_trig: in ipb_wbus;
ipb_out_trig: out ipb_rbus;
ipb_in_tlink: in ipb_wbus;
ipb_out_tlink: out ipb_rbus;
ipb_in_roc: in ipb_wbus;
ipb_out_roc: out ipb_rbus;
rst_mmcm: in std_logic;
locked: out std_logic;
clk_in_p: in std_logic;
clk_in_n: in std_logic;
clk40: out std_logic;
sync_in: in std_logic;
sync_out: out std_logic;
trig_in: in std_logic;
chan: in std_logic_vector(7 downto 0);
d_p: in std_logic_vector(N_CHAN - 1 downto 0);
d_n: in std_logic_vector(N_CHAN - 1 downto 0);
clk125: in std_logic;
rst125: in std_logic;
board_id: in std_logic_vector(7 downto 0)
);
end sc_daq_sim;
architecture rtl of sc_daq_sim is
signal clk40_i, rst40_i, clk160, clk280: std_logic;
signal sync_ctrl: std_logic_vector(3 downto 0);
signal sctr: std_logic_vector(47 downto 0);
signal trig_en, nzs_en, zs_en, chan_err: std_logic;
signal trig_keep, trig_flush, trig_veto: std_logic_vector(N_CHAN - 1 downto 0);
signal chan_trig: sc_trig_array;
signal link_d, link_q: std_logic_vector(15 downto 0);
signal link_d_valid, link_q_valid, link_ack: std_logic;
signal ro_chan: std_logic_vector(7 downto 0);
signal ro_d, trig_d: std_logic_vector(31 downto 0);
signal ro_blkend, ro_empty, ro_ren, en_ro, trig_sync, trig_blkend, trig_we, trig_roc_veto: std_logic;
signal rand: std_logic_vector(31 downto 0);
begin
-- Timing
timing: entity work.sc_timing
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipb_in_timing,
ipb_out => ipb_out_timing,
rst_mmcm => rst_mmcm,
locked => locked,
clk_in_p => clk_in_p,
clk_in_n => clk_out_n,
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
clk280 => clk280,
sync_in => sync_in,
sync_out => sync_out,
ext_trig_in => trig_in,
sctr => sctr,
chan_sync_ctrl => sync_ctrl,
trig_en => trig_en,
nzs_en => nzs_en,
zs_en => zs_en,
rand => rand
);
clk40 <= clk40_i;
-- Data channels
chans: entity work.sc_channels
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipb_in_chan,
ipb_out => ipb_out_chan,
chan => chan,
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
clk280 => clk280,
d_p => adc_d_p,
d_n => adc_d_n,
sync_ctrl => sync_ctrl,
sctr => sctr(13 downto 0),
rand => rand(13 downto 0),
nzs_en => nzs_en,
zs_en => zs_en,
keep => trig_keep,
flush => trig_flush,
err => chan_err,
veto => trig_veto,
trig => chan_trig,
dr_chan => ro_chan,
clk_dr => ipb_clk,
q => ro_d,
q_blkend => ro_blkend,
q_empty => ro_empty,
ren => ro_ren
);
-- Trigger
trig: entity work.sc_trig
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipb_in_trig,
ipb_out => ipb_out_trig,
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
trig_en => trig_en,
zs_en => zs_en,
sctr => sctr,
rand => rand,
keep => trig_keep,
flush => trig_flush,
veto => trig_veto,
trig => chan_trig,
ro_d => trig_d,
ro_blkend => trig_blkend,
ro_we => trig_we,
ro_veto => trig_roc_veto,
q => link_d,
q_valid => link_d_valid,
d => link_q,
d_valid => link_q_valid,
d_ack => link_ack
);
-- Trigger serial links
tlink: entity work.sc_trig_link
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipb_in_tlink,
ipb_out => ipb_out_tlink,
clk125 => clk125,
rst125 => rst125,
clk40 => clk40_i,
rst40 => rst40_i,
d => link_d,
d_valid => link_d_valid,
q => link_q,
q_valid => link_q_valid,
ack => link_ack
);
-- Readout
roc: entity work.sc_roc
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipb_in_roc,
ipb_out => ipb_out_roc,
board_id => board_id,
clk40 => clk40_i,
rst40 => rst40_i,
rand => rand,
d_trig => trig_d,
blkend_trig => trig_blkend,
we_trig => trig_we,
veto_trig => trig_roc_veto,
chan => ro_chan,
d => ro_d,
blkend => ro_blkend,
empty => ro_empty,
ren => ro_ren
);
end rtl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/software/ 0000775 0000000 0000000 00000000000 13132146003 0027343 5 ustar 00root root 0000000 0000000 I2CuHal.py 0000664 0000000 0000000 00000022271 13132146003 0031031 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/software # -*- coding: utf-8 -*-
"""
"""
import time
import uhal
verbose = True
################################################################################
# /*
# I2C CORE
# */
################################################################################
class I2CCore:
"""I2C communication block."""
# Define bits in cmd_stat register
startcmd = 0x1 << 7
stopcmd = 0x1 << 6
readcmd = 0x1 << 5
writecmd = 0x1 << 4
ack = 0x1 << 3
intack = 0x1
recvdack = 0x1 << 7
busy = 0x1 << 6
arblost = 0x1 << 5
inprogress = 0x1 << 1
interrupt = 0x1
def __init__(self, target, wclk, i2cclk, name="i2c", delay=None):
self.target = target
self.name = name
self.delay = delay
self.prescale_low = self.target.getNode("%s.ps_lo" % name)
self.prescale_high = self.target.getNode("%s.ps_hi" % name)
self.ctrl = self.target.getNode("%s.ctrl" % name)
self.data = self.target.getNode("%s.data" % name)
self.cmd_stat = self.target.getNode("%s.cmd_stat" % name)
self.wishboneclock = wclk
self.i2cclock = i2cclk
self.config()
def state(self):
status = {}
status["ps_low"] = self.prescale_low.read()
status["ps_hi"] = self.prescale_high.read()
status["ctrl"] = self.ctrl.read()
status["data"] = self.data.read()
status["cmd_stat"] = self.cmd_stat.read()
self.target.dispatch()
status["prescale"] = status["ps_hi"] << 8
status["prescale"] |= status["ps_low"]
for reg in status:
val = status[reg]
bval = bin(int(val))
if verbose:
print "\treg %s = %d, 0x%x, %s" % (reg, val, val, bval)
def clearint(self):
self.ctrl.write(0x1)
self.target.dispatch()
def config(self):
#INITIALIZATION OF THE I2S MASTER CORE
#Disable core
self.ctrl.write(0x0 << 7)
self.target.dispatch()
#Write pre-scale register
#prescale = int(self.wishboneclock / (5.0 * self.i2cclock)) - 1
prescale = 0x0100 #FOR NOW HARDWIRED, TO BE MODIFIED
#prescale = 0x2710 #FOR NOW HARDWIRED, TO BE MODIFIED
self.prescale_low.write(prescale & 0xff)
self.prescale_high.write((prescale & 0xff00) >> 8)
#Enable core
self.ctrl.write(0x1 << 7)
self.target.dispatch()
def checkack(self):
inprogress = True
ack = False
while inprogress:
cmd_stat = self.cmd_stat.read()
self.target.dispatch()
inprogress = (cmd_stat & I2CCore.inprogress) > 0
ack = (cmd_stat & I2CCore.recvdack) == 0
return ack
def delayorcheckack(self):
ack = True
if self.delay is None:
ack = self.checkack()
else:
time.sleep(self.delay)
ack = self.checkack()#Remove this?
return ack
################################################################################
# /*
# I2C WRITE
# */
################################################################################
def write(self, addr, data, stop=True):
"""Write data to the device with the given address."""
# Start transfer with 7 bit address and write bit (0)
nwritten = -1
addr &= 0x7f
addr = addr << 1
startcmd = 0x1 << 7
stopcmd = 0x1 << 6
writecmd = 0x1 << 4
#Set transmit register (write operation, LSB=0)
self.data.write(addr)
#Set Command Register to 0x90 (write, start)
self.cmd_stat.write(I2CCore.startcmd | I2CCore.writecmd)
self.target.dispatch()
ack = self.delayorcheckack()
if not ack:
self.cmd_stat.write(I2CCore.stopcmd)
self.target.dispatch()
return nwritten
nwritten += 1
for val in data:
val &= 0xff
#Write slave memory address
self.data.write(val)
#Set Command Register to 0x10 (write)
self.cmd_stat.write(I2CCore.writecmd)
self.target.dispatch()
ack = self.delayorcheckack()
if not ack:
self.cmd_stat.write(I2CCore.stopcmd)
self.target.dispatch()
return nwritten
nwritten += 1
if stop:
self.cmd_stat.write(I2CCore.stopcmd)
self.target.dispatch()
return nwritten
################################################################################
# /*
# I2C READ
# */
################################################################################
def read(self, addr, n):
"""Read n bytes of data from the device with the given address."""
# Start transfer with 7 bit address and read bit (1)
data = []
addr &= 0x7f
addr = addr << 1
addr |= 0x1 # read bit
self.data.write(addr)
self.cmd_stat.write(I2CCore.startcmd | I2CCore.writecmd)
self.target.dispatch()
ack = self.delayorcheckack()
if not ack:
self.cmd_stat.write(I2CCore.stopcmd)
self.target.dispatch()
return data
for i in range(n):
if i < (n-1):
self.cmd_stat.write(I2CCore.readcmd) # <---
else:
self.cmd_stat.write(I2CCore.readcmd | I2CCore.ack | I2CCore.stopcmd) # <--- This tells the slave that it is the last word
self.target.dispatch()
ack = self.delayorcheckack()
val = self.data.read()
self.target.dispatch()
data.append(val & 0xff)
#self.cmd_stat.write(I2CCore.stopcmd)
#self.target.dispatch()
return data
################################################################################
# /*
# I2C WRITE-READ
# */
################################################################################
# def writeread(self, addr, data, n):
# """Write data to device, then read n bytes back from it."""
# nwritten = self.write(addr, data, stop=False)
# readdata = []
# if nwritten == len(data):
# readdata = self.read(addr, n)
# return nwritten, readdata
"""
SPI core XML:
"""
class SPICore:
go_busy = 0x1 << 8
rising = 1
falling = 0
def __init__(self, target, wclk, spiclk, basename="io.spi"):
self.target = target
# Only a single data register is required since all transfers are
# 16 bit long
self.data = target.getNode("%s.d0" % basename)
self.control = target.getNode("%s.ctrl" % basename)
self.control_val = 0b0
self.divider = target.getNode("%s.divider" % basename)
self.slaveselect = target.getNode("%s.ss" % basename)
self.divider_val = int(wclk / spiclk / 2.0 - 1.0)
self.divider_val = 0x7f
self.configured = False
def config(self):
"Configure SPI interace for communicating with ADCs."
self.divider_val = int(self.divider_val) % 0xffff
if verbose:
print "Configuring SPI core, divider = 0x%x" % self.divider_val
self.divider.write(self.divider_val)
self.target.dispatch()
self.control_val = 0x0
self.control_val |= 0x0 << 13 # Automatic slave select
self.control_val |= 0x0 << 12 # No interrupt
self.control_val |= 0x0 << 11 # MSB first
# ADC samples data on rising edge of SCK
self.control_val |= 0x1 << 10 # change ouput on falling edge of SCK
# ADC changes output shortly after falling edge of SCK
self.control_val |= 0x0 << 9 # read input on rising edge
self.control_val |= 0x10 # 16 bit transfers
if verbose:
print "SPI control val = 0x%x = %s" % (self.control_val, bin(self.control_val))
self.configured = True
def transmit(self, chip, value):
if not self.configured:
self.config()
assert chip >= 0 and chip < 8
value &= 0xffff
self.data.write(value)
checkdata = self.data.read()
self.target.dispatch()
assert checkdata == value
self.control.write(self.control_val)
self.slaveselect.write(0xff ^ (0x1 << chip))
self.target.dispatch()
self.control.write(self.control_val | SPICore.go_busy)
self.target.dispatch()
busy = True
while busy:
status = self.control.read()
self.target.dispatch()
busy = status & SPICore.go_busy > 0
self.slaveselect.write(0xff)
data = self.data.read()
ss = self.slaveselect.read()
status = self.control.read()
self.target.dispatch()
#print "Received data: 0x%x, status = 0x%x, ss = 0x%x" % (data, status, ss)
return data
si5344.py 0000664 0000000 0000000 00000010623 13132146003 0030573 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/components/solid/software import time
import uhal
from I2CuHal import I2CCore
import StringIO
import csv
class si5344:
#Class to configure the Si5344 clock generator
def __init__(self, i2c, slaveaddr=0x68):
self.i2c = i2c
self.slaveaddr = slaveaddr
#self.configList=
#def writeReg(self, address, data):
def readRegister(self, myaddr, nwords):
### Read a specific register on the Si5344 chip. There is not check on the validity of the address but
### the code sets the correct page before reading.
#First make sure we are on the correct page
currentPg= self.getPage()
requirePg= (myaddr & 0xFF00) >> 8
# print "REG", hex(myaddr), "CURR PG" , hex(currentPg[0]), "REQ PG", hex(requirePg)
if currentPg[0] != requirePg:
self.setPage(requirePg)
#Now read from register.
addr=[]
addr.append(myaddr)
mystop=False
self.i2c.write( self.slaveaddr, addr, mystop)
# time.sleep(0.1)
res= self.i2c.read( self.slaveaddr, nwords)
return res
def writeRegister(self, myaddr, data, verbose=False):
### Write a specific register on the Si5344 chip. There is not check on the validity of the address but
### the code sets the correct page before reading.
### myaddr is an int
### data is a list of ints
#First make sure we are on the correct page
myaddr= myaddr & 0xFFFF
currentPg= self.getPage()
requirePg= (myaddr & 0xFF00) >> 8
# print "REG", hex(myaddr), "CURR PG" , currentPg, "REQ PG", hex(requirePg)
if currentPg[0] != requirePg:
self.setPage(requirePg)
#Now write to register.
data.insert(0, myaddr)
if verbose:
print " Writing: "
result="\t "
for iaddr in data:
result+="%#02x "%(iaddr)
print result
self.i2c.write( self.slaveaddr, data)
#time.sleep(0.01)
def setPage(self, page, verbose=False):
#Configure the chip to perform operations on the specified address page.
mystop=True
myaddr= [0x01, page]
self.i2c.write( self.slaveaddr, myaddr, mystop)
#time.sleep(0.01)
if verbose:
print "Si5344 Set Reg Page:", page
def getPage(self, verbose=False):
#Read the current address page
mystop=False
myaddr= [0x01]
self.i2c.write( self.slaveaddr, myaddr, mystop)
rPage= self.i2c.read( self.slaveaddr, 1)
#time.sleep(0.1)
if verbose:
print " Page read:", rPage
return rPage
def getDeviceVersion(self):
#Read registers containing chip information
mystop=False
nwords=2
myaddr= [0x02 ]#0xfa
self.setPage(0)
self.i2c.write( self.slaveaddr, myaddr, mystop)
#time.sleep(0.1)
res= self.i2c.read( self.slaveaddr, nwords)
print " CLOCK EPROM: "
result="\t "
for iaddr in res:
result+="%#02x "%(iaddr)
print result
return res
def parse_clk(self, filename):
#Parse the configuration file produced by Clockbuilder Pro (Silicon Labs)
deletedcomments=""""""
print "\tParsing file", filename
with open(filename, 'rb') as configfile:
for i, line in enumerate(configfile):
if not line.startswith('#') :
if not line.startswith('Address'):
deletedcomments+=line
csvfile = StringIO.StringIO(deletedcomments)
cvr= csv.reader(csvfile, delimiter=',', quotechar='|')
#print "\tN elements parser:", sum(1 for row in cvr)
#return [addr_list,data_list]
# for item in cvr:
# print "rere"
# regAddr= int(item[0], 16)
# regData[0]= int(item[1], 16)
# print "\t ", hex(regAddr), hex(regData[0])
#self.configList= cvr
regSettingList= list(cvr)
print "\t ", len(regSettingList), "elements"
return regSettingList
def writeConfiguration(self, regSettingList):
print "\tWrite configuration:"
#regSettingList= list(regSettingCsv)
counter=0
for item in regSettingList:
regAddr= int(item[0], 16)
regData=[0]
regData[0]= int(item[1], 16)
# print "\t ", counter, "Reg:", hex(regAddr), "Data:", regData
counter += 1
self.writeRegister(regAddr, regData)
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/ 0000775 0000000 0000000 00000000000 13132146003 0024043 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/ 0000775 0000000 0000000 00000000000 13132146003 0024607 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/addr_table/ 0000775 0000000 0000000 00000000000 13132146003 0026670 5 ustar 00root root 0000000 0000000 payload.xml 0000664 0000000 0000000 00000001211 13132146003 0030757 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/addr_table/top.xml 0000664 0000000 0000000 00000000322 13132146003 0030211 0 ustar 00root root 0000000 0000000
top_sim.xml 0000664 0000000 0000000 00000000221 13132146003 0031000 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/ 0000775 0000000 0000000 00000000000 13132146003 0026423 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/cfg/ 0000775 0000000 0000000 00000000000 13132146003 0027162 5 ustar 00root root 0000000 0000000 payload.dep 0000664 0000000 0000000 00000000613 13132146003 0031226 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/cfg src payload.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_top.vhd
addrtab -t top.xml
addrtab payload.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
include -c components/solid sc_io_64chan.dep sc_daq.dep
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
top.dep 0000664 0000000 0000000 00000000127 13132146003 0030377 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/cfg include -c boards/pc051b/base_fw/synth pc051b.dep
include payload.dep
src top_decl.vhd
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl/ 0000775 0000000 0000000 00000000000 13132146003 0027172 5 ustar 00root root 0000000 0000000 ipbus_decode_top.vhd 0000664 0000000 0000000 00000003453 13132146003 0033132 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_top is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_top(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Thu Jun 15 21:26:57 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_IO: integer := 1;
constant N_SLV_DAQ: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_top;
package body ipbus_decode_top is
function ipbus_sel_top(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Thu Jun 15 21:26:57 2017
if std_match(addr, "-----------------------0--0-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000120
elsif std_match(addr, "-----------------------0--1-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_IO, IPBUS_SEL_WIDTH)); -- io / base 0x00000020 / mask 0x00000120
elsif std_match(addr, "-----------------------1--------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_DAQ, IPBUS_SEL_WIDTH)); -- daq / base 0x00000100 / mask 0x00000100
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_top;
end ipbus_decode_top;
ipbus_decode_top_sim.vhd 0000664 0000000 0000000 00000004736 13132146003 0034007 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_top_sim is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_top_sim(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Sat Aug 20 17:42:19 2016
constant N_SLV_CSR: integer := 0;
constant N_SLV_CHAN: integer := 1;
constant N_SLV_TIMING: integer := 2;
constant N_SLV_TLINK: integer := 3;
constant N_SLV_TRIG: integer := 4;
constant N_SLV_ROC: integer := 5;
constant N_SLAVES: integer := 6;
-- END automatically generated VHDL
end ipbus_decode_top_sim;
package body ipbus_decode_top_sim is
function ipbus_sel_top_sim(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Sat Aug 20 17:42:19 2016
if std_match(addr, "------------------------00000---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x000000f8
elsif std_match(addr, "------------------------00001---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CHAN, IPBUS_SEL_WIDTH)); -- chan / base 0x00000008 / mask 0x000000f8
elsif std_match(addr, "------------------------01000---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TIMING, IPBUS_SEL_WIDTH)); -- timing / base 0x00000040 / mask 0x000000f8
elsif std_match(addr, "------------------------01010---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TLINK, IPBUS_SEL_WIDTH)); -- tlink / base 0x00000050 / mask 0x000000f8
elsif std_match(addr, "------------------------0110----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_TRIG, IPBUS_SEL_WIDTH)); -- trig / base 0x00000060 / mask 0x000000f0
elsif std_match(addr, "------------------------1000----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_ROC, IPBUS_SEL_WIDTH)); -- roc / base 0x00000080 / mask 0x000000f0
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_top_sim;
end ipbus_decode_top_sim;
payload.vhd 0000664 0000000 0000000 00000007441 13132146003 0031255 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl -- payload.vhd
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_top.all;
use work.top_decl.all;
library unisim;
use unisim.VComponents.all;
entity payload is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk125: in std_logic;
rst125: in std_logic;
clk200: in std_logic;
nuke: out std_logic;
soft_rst: out std_logic;
userleds: out std_logic_vector(2 downto 0);
addr: in std_logic_vector(7 downto 0);
sel: out std_logic_vector(4 downto 0);
i2c_scl: out std_logic; -- I2C bus via CPLD
i2c_sda_i: in std_logic;
i2c_sda_o: out std_logic;
spi_csn: out std_logic;
spi_mosi: out std_logic;
spi_miso: in std_logic;
spi_sclk: out std_logic;
clkgen_lol: in std_logic;
clkgen_rstn: out std_logic;
clk_p: in std_logic;
clk_n: in std_logic;
sync_in: in std_logic;
trig_in: in std_logic;
trig_out: out std_logic;
adc_d_p: in std_logic_vector(63 downto 0);
adc_d_n: in std_logic_vector(63 downto 0)
);
end payload;
architecture rtl of payload is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(1 downto 0);
signal clk40: std_logic;
signal ctrl_rst_mmcm, locked, idelayctrl_rdy, ctrl_rst_idelayctrl: std_logic;
signal ctrl_chan: std_logic_vector(7 downto 0);
signal chan_err: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_top(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 2
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl
);
stat(0) <= X"a753" & FW_REV;
stat(1) <= X"00000" & addr & '0' & chan_err & idelayctrl_rdy & locked;
soft_rst <= ctrl(0)(0);
nuke <= ctrl(0)(1);
ctrl_rst_mmcm <= ctrl(0)(2);
ctrl_rst_idelayctrl <= ctrl(0)(3);
ctrl_chan <= ctrl(0)(15 downto 8);
sel <= ctrl(0)(28 downto 24);
userleds <= ctrl(0)(31 downto 29);
-- Required for timing alignment at inputs
idelctrl: IDELAYCTRL -- Docs claim this should be replicated as necessary
port map(
rdy => idelayctrl_rdy,
refclk => clk200,
rst => ctrl_rst_idelayctrl -- Careful, need at least 50ns reset pulse here
);
-- Board IO
io: entity work.sc_io_64chan
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_IO),
ipb_out => ipbr(N_SLV_IO),
clk40 => clk40,
i2c_scl => i2c_scl,
i2c_sda_i => i2c_sda_i,
i2c_sda_o => i2c_sda_o,
spi_csn => spi_csn,
spi_mosi => spi_mosi,
spi_miso => spi_miso,
spi_sclk => spi_sclk,
clkgen_lol => clkgen_lol,
clkgen_rstn => clkgen_rstn
);
-- DAQ core
daq: entity work.sc_daq
port map(
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipbw(N_SLV_DAQ),
ipb_out => ipbr(N_SLV_DAQ),
rst_mmcm => ctrl_rst_mmcm,
locked => locked,
clk_in_p => clk_p,
clk_in_n => clk_n,
clk40 => clk40,
sync_in => sync_in,
trig_in => trig_in,
trig_out => trig_out,
chan => ctrl_chan,
chan_err => chan_err,
d_p => adc_d_p,
d_n => adc_d_n,
clk125 => clk125,
rst125 => rst125,
board_id => addr
);
-- Unused channels
cgen: for i in 63 downto N_CHAN generate
attribute DONT_TOUCH: string;
attribute DONT_TOUCH of buf: label is "TRUE";
begin
buf: IBUFDS
port map(
i => adc_d_p(i),
ib => adc_d_n(i),
o => open
);
end generate;
end rtl;
sync_routing.vhd 0000664 0000000 0000000 00000002511 13132146003 0032340 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl -- sync_routing
--
-- Switchyard for the various ways of using the HDMI connector
--
-- sync_a input is always routed to clk_pll, but might be unused at PLL end
-- sync_a output is always crappy clk40
-- sync_b is an output for ctrl = '0', but an input for ctrl = '1'
-- sync_c exists on the cable but is not used
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity sync_routing is
port(
clk40: in std_logic;
ctrl: in std_logic;
sync_out: out std_logic;
sync_in: in std_logic;
sync_a_p: inout std_logic;
sync_a_n: inout std_logic;
sync_b_p: inout std_logic;
sync_b_n: inout std_logic;
clk_pll_p: out std_logic;
clk_pll_n: out std_logic
);
end sync_routing;
architecture rtl of sync_routing is
signal sync_a_i, sync_a_o: std_logic;
begin
oclk: ODDR
port map(
q => sync_a_o,
c => clk40,
ce => '1',
d1 => '0',
d2 => '1',
r => '0',
s => '0'
); -- DDR register for clock forwarding
ia: IOBUFDS
port map(
O => sync_a_i,
IO => sync_a_p,
IOB => sync_a_n,
I => sync_a_o,
T => '0'
);
obclk: OBUFDS
port map(
i => sync_a_i,
o => clk_pll_p,
ob => clk_pll_n
);
ib: IOBUFDS
port map(
O => sync_out,
IO => sync_b_p,
IOB => sync_b_n,
I => sync_in,
T => ctrl
);
end rtl;
top_decl.vhd 0000664 0000000 0000000 00000002461 13132146003 0031412 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/64ch/firmware/hdl -- top_decl
--
-- Defines constants for the whole device
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package top_decl is
constant MAC_ADDR: std_logic_vector(47 downto 0) := X"020ddba11500"; -- last byte from local addr
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb00"; -- last byte from local addr
constant FW_REV: std_logic_vector(15 downto 0) := X"000d";
constant N_CHAN: integer := 64;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
constant SUPERBLK_RADIX: integer := 16; -- Superblock is 64k blocks
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/ 0000775 0000000 0000000 00000000000 13132146003 0024525 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/addr_table/ 0000775 0000000 0000000 00000000000 13132146003 0026606 5 ustar 00root root 0000000 0000000 payload.xml 0000664 0000000 0000000 00000001101 13132146003 0030673 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/addr_table/top.xml 0000664 0000000 0000000 00000000420 13132146003 0030126 0 ustar 00root root 0000000 0000000
top_sim.xml 0000664 0000000 0000000 00000000222 13132146003 0030717 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/addr_table
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/ 0000775 0000000 0000000 00000000000 13132146003 0026341 5 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/cfg/ 0000775 0000000 0000000 00000000000 13132146003 0027100 5 ustar 00root root 0000000 0000000 payload.dep 0000664 0000000 0000000 00000000625 13132146003 0031147 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/cfg src payload.vhd sync_routing.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_top.vhd
addrtab -t top.xml
addrtab payload.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
include -c components/solid sc_io.dep sc_daq.dep
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
payload_sim.dep 0000664 0000000 0000000 00000000625 13132146003 0032017 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/cfg src ../sim_hdl/payload_sim.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
src ipbus_decode_top_sim.vhd
addrtab -t top_sim.xml
addrtab payload.xml
src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd
include -c components/solid sc_daq_sim.dep
src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/cfg/top.dep0000664 0000000 0000000 00000000127 13132146003 0030374 0 ustar 00root root 0000000 0000000 include -c boards/pc051a/base_fw/synth pc051a.dep
include payload.dep
src top_decl.vhd
top_sim.dep 0000664 0000000 0000000 00000000150 13132146003 0031161 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/cfg include -c boards/pc051a/base_fw/sim pc051a_sim.dep
include payload_sim.dep
src ../sim_hdl/top_decl.vhd
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl/ 0000775 0000000 0000000 00000000000 13132146003 0027110 5 ustar 00root root 0000000 0000000 ipbus_decode_top.vhd 0000664 0000000 0000000 00000003453 13132146003 0033050 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_top is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_top(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Thu Jun 15 21:26:11 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_IO: integer := 1;
constant N_SLV_DAQ: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_top;
package body ipbus_decode_top is
function ipbus_sel_top(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Thu Jun 15 21:26:11 2017
if std_match(addr, "-----------------------0--0-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000120
elsif std_match(addr, "-----------------------0--1-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_IO, IPBUS_SEL_WIDTH)); -- io / base 0x00000020 / mask 0x00000120
elsif std_match(addr, "-----------------------1--------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_DAQ, IPBUS_SEL_WIDTH)); -- daq / base 0x00000100 / mask 0x00000100
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_top;
end ipbus_decode_top;
ipbus_decode_top_sim.vhd 0000664 0000000 0000000 00000003165 13132146003 0033720 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl -- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_top_sim is
constant IPBUS_SEL_WIDTH: positive := 5; -- Should be enough for now?
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_top_sim(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL the Thu Jun 15 20:48:09 2017
constant N_SLV_CSR: integer := 0;
constant N_SLV_DAQ: integer := 1;
constant N_SLAVES: integer := 2;
-- END automatically generated VHDL
end ipbus_decode_top_sim;
package body ipbus_decode_top_sim is
function ipbus_sel_top_sim(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL the Thu Jun 15 20:48:09 2017
if std_match(addr, "-----------------------0--------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000000 / mask 0x00000100
elsif std_match(addr, "-----------------------1--------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_DAQ, IPBUS_SEL_WIDTH)); -- daq / base 0x00000100 / mask 0x00000100
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_top_sim;
end ipbus_decode_top_sim;
payload.vhd 0000664 0000000 0000000 00000011560 13132146003 0031170 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl -- payload.vhd
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_top.all;
use work.top_decl.all;
library unisim;
use unisim.VComponents.all;
entity payload is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk125: in std_logic;
rst125: in std_logic;
clk200: in std_logic;
nuke: out std_logic;
soft_rst: out std_logic;
userleds: out std_logic_vector(3 downto 0);
si5326_scl: out std_logic;
si5326_sda_o: out std_logic;
si5326_sda_i: in std_logic;
si5326_rstn: out std_logic;
si5326_phase_inc: out std_logic;
si5326_phase_dec: out std_logic;
si5326_clk1_validn: in std_logic;
si5326_clk2_validn: in std_logic;
si5326_lol: in std_logic;
si5326_clk_sel: out std_logic;
si5326_rate0: out std_logic;
si5326_rate1: out std_logic;
clk40_p: in std_logic;
clk40_n: in std_logic;
adc_cs: out std_logic_vector(1 downto 0);
adc_mosi: out std_logic;
adc_miso: in std_logic_vector(1 downto 0);
adc_sclk: out std_logic;
adc_d_p: in std_logic_vector(N_CHAN - 1 downto 0);
adc_d_n: in std_logic_vector(N_CHAN - 1 downto 0);
analog_scl: out std_logic;
analog_sda_i: in std_logic;
analog_sda_o: out std_logic;
sync_in_p: in std_logic;
sync_in_n: in std_logic;
trig_in_p: in std_logic;
trig_in_n: in std_logic;
trig_out_p: out std_logic;
trig_out_n: out std_logic;
clk_pll_p: out std_logic;
clk_pll_n: out std_logic
);
end payload;
architecture rtl of payload is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(1 downto 0);
signal clk40: std_logic;
signal sync_in, trig_in, trig_out: std_logic;
signal ctrl_rst_mmcm, locked, idelayctrl_rdy, ctrl_rst_idelayctrl, ctrl_sync_mode: std_logic;
signal ctrl_chan: std_logic_vector(7 downto 0);
signal ctrl_board_id: std_logic_vector(7 downto 0);
signal chan_err: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_top(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 2
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl
);
stat(0) <= X"a753" & FW_REV;
stat(1) <= X"0000000" & "0" & chan_err & idelayctrl_rdy & locked;
soft_rst <= ctrl(0)(0);
nuke <= ctrl(0)(1);
ctrl_rst_mmcm <= ctrl(0)(2);
ctrl_rst_idelayctrl <= ctrl(0)(3);
ctrl_sync_mode <= ctrl(0)(4);
ctrl_chan <= ctrl(0)(15 downto 8);
ctrl_board_id <= ctrl(0)(23 downto 16);
userleds <= "0000";
-- Required for timing alignment at inputs
idelctrl: IDELAYCTRL -- Docs claim this should be replicated as necessary
port map(
rdy => idelayctrl_rdy,
refclk => clk200,
rst => ctrl_rst_idelayctrl -- Careful, need at least 50ns reset pulse here
);
-- Board IO
io: entity work.sc_io
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_in => ipbw(N_SLV_IO),
ipb_out => ipbr(N_SLV_IO),
clk40 => clk40,
si5326_scl => si5326_scl,
si5326_sda_o => si5326_sda_o,
si5326_sda_i => si5326_sda_i,
si5326_rstn => si5326_rstn,
si5326_phase_inc => si5326_phase_inc,
si5326_phase_dec => si5326_phase_dec,
si5326_clk1_validn => si5326_clk1_validn,
si5326_clk2_validn => si5326_clk2_validn,
si5326_lol => si5326_lol,
si5326_clk_sel => si5326_clk_sel,
si5326_rate0 => si5326_rate0,
si5326_rate1 => si5326_rate1,
adc_cs => adc_cs,
adc_mosi => adc_mosi,
adc_miso => adc_miso,
adc_sclk => adc_sclk,
analog_scl => analog_scl,
analog_sda_o => analog_sda_o,
analog_sda_i => analog_sda_i
);
-- iobufs
ibuf_sync_in: IBUFDS
port map(
i => sync_in_p,
ib => sync_in_n,
o => sync_in
);
ibuf_trig_in: IBUFDS
port map(
i => trig_in_p,
ib => trig_in_n,
o => trig_in
);
obuf_trig_out: OBUFDS
port map(
i => trig_out,
o => trig_out_p,
ob => trig_out_n
);
obuf_clk_pll: OBUFDS
port map(
i => '0',
o => clk_pll_p,
ob => clk_pll_n
);
-- DAQ core
daq: entity work.sc_daq
port map(
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipbw(N_SLV_DAQ),
ipb_out => ipbr(N_SLV_DAQ),
rst_mmcm => ctrl_rst_mmcm,
locked => locked,
clk_in_p => clk40_p,
clk_in_n => clk40_n,
clk40 => clk40,
sync_in => sync_in,
trig_in => trig_in,
trig_out => trig_out,
chan => ctrl_chan,
chan_err => chan_err,
d_p => adc_d_p,
d_n => adc_d_n,
clk125 => clk125,
rst125 => rst125,
board_id => ctrl_board_id
);
end rtl;
sync_routing.vhd 0000664 0000000 0000000 00000002511 13132146003 0032256 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl -- sync_routing
--
-- Switchyard for the various ways of using the HDMI connector
--
-- sync_a input is always routed to clk_pll, but might be unused at PLL end
-- sync_a output is always crappy clk40
-- sync_b is an output for ctrl = '0', but an input for ctrl = '1'
-- sync_c exists on the cable but is not used
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.VComponents.all;
entity sync_routing is
port(
clk40: in std_logic;
ctrl: in std_logic;
sync_out: out std_logic;
sync_in: in std_logic;
sync_a_p: inout std_logic;
sync_a_n: inout std_logic;
sync_b_p: inout std_logic;
sync_b_n: inout std_logic;
clk_pll_p: out std_logic;
clk_pll_n: out std_logic
);
end sync_routing;
architecture rtl of sync_routing is
signal sync_a_i, sync_a_o: std_logic;
begin
oclk: ODDR
port map(
q => sync_a_o,
c => clk40,
ce => '1',
d1 => '0',
d2 => '1',
r => '0',
s => '0'
); -- DDR register for clock forwarding
ia: IOBUFDS
port map(
O => sync_a_i,
IO => sync_a_p,
IOB => sync_a_n,
I => sync_a_o,
T => '0'
);
obclk: OBUFDS
port map(
i => sync_a_i,
o => clk_pll_p,
ob => clk_pll_n
);
ib: IOBUFDS
port map(
O => sync_out,
IO => sync_b_p,
IOB => sync_b_n,
I => sync_in,
T => ctrl
);
end rtl;
top_decl.vhd 0000664 0000000 0000000 00000002366 13132146003 0031334 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/hdl -- top_decl
--
-- Defines constants for the whole device
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package top_decl is
constant MAC_ADDR: std_logic_vector(47 downto 0) := X"020ddba11503";
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb00";
constant FW_REV: std_logic_vector(15 downto 0) := X"000d";
constant N_CHAN: integer := 8;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
constant SUPERBLK_RADIX: integer := 16; -- Superblock is 64k blocks
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/sim_hdl/ 0000775 0000000 0000000 00000000000 13132146003 0027760 5 ustar 00root root 0000000 0000000 payload_sim.vhd 0000664 0000000 0000000 00000004510 13132146003 0032705 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/sim_hdl -- payload.vhd
--
-- Dave Newbold, February 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_top_sim.all;
use work.top_decl.all;
entity payload_sim is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk125: in std_logic;
rst125: in std_logic;
nuke: out std_logic;
soft_rst: out std_logic
);
end payload_sim;
architecture rtl of payload_sim is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(1 downto 0);
signal clk40, rst40, clk160, clk280: std_logic;
signal ctrl_rst_mmcm, locked, idelayctrl_rdy, ctrl_rst_idelayctrl: std_logic;
signal ctrl_chan: std_logic_vector(7 downto 0);
signal ctrl_board_id: std_logic_vector(7 downto 0);
signal chan_err: std_logic;
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_top_sim(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- CSR
csr: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => 1,
N_STAT => 2
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipbw(N_SLV_CSR),
ipbus_out => ipbr(N_SLV_CSR),
d => stat,
q => ctrl
);
stat(0) <= X"a754" & FW_REV;
stat(1) <= X"0000000" & "0" & chan_err & idelayctrl_rdy & locked;
soft_rst <= ctrl(0)(0);
nuke <= ctrl(0)(1);
ctrl_rst_mmcm <= ctrl(0)(2);
ctrl_rst_idelayctrl <= ctrl(0)(3);
ctrl_chan <= ctrl(0)(15 downto 8);
ctrl_board_id <= ctrl(0)(23 downto 16);
-- Board IO
idelayctrl_rdy <= '1';
-- DAQ core
daq: entity work.sc_daq
port map(
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipbw(N_SLV_DAQ),
ipb_out => ipbr(N_SLV_DAQ),
rst_mmcm => ctrl_rst_mmcm,
locked => locked,
clk_in_p => '0',
clk_in_n => '1',
clk40 => clk40,
sync_in => '0',
sync_out => open,
trig_in => '0',
chan => ctrl_chan,
chan_err => chan_err,
d_p => (others => '0'),
d_n => (others => '1'),
clk125 => clk125,
rst125 => rst125,
board_id => ctrl_board_id
);
end rtl;
top_decl.vhd 0000664 0000000 0000000 00000002364 13132146003 0032202 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/firmware/sim_hdl -- top_decl
--
-- Defines constants for the whole device
--
-- Dave Newbold, September 2014
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package top_decl is
constant MAC_ADDR: std_logic_vector(47 downto 0) := X"020ddba11503";
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb10";
constant FW_REV: std_logic_vector(15 downto 0) := X"010d";
constant N_CHAN: integer := 2;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
constant SUPERBLK_RADIX: integer := 5; -- Superblock is 32 blocks
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software/ 0000775 0000000 0000000 00000000000 13132146003 0026357 5 ustar 00root root 0000000 0000000 fill_test.py 0000775 0000000 0000000 00000004517 13132146003 0030651 0 ustar 00root root 0000000 0000000 euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software #!/usr/bin/python
import uhal
from time import sleep
import sys
import collections
def zsdot(i):
return ' ' if i == 0 else '!'
def zsfmt(i):
return "%s%s%04x %s%s%04x" % (zsdot(i & 0x8000), zsdot(i & 0x4000), i & 0x3fff,
zsdot(i & 0x80000000), zsdot(i & 0x40000000), (i & 0x3fff0000) >> 16)
uhal.setLogLevelTo(uhal.LogLevel.ERROR)
board = uhal.getDevice("board", "ipbusudp-2.0://192.168.235.1:50001", "file://addr_tab/top.xml")
#board.getClient().setTimeoutPeriod(10000)
v = board.getNode("csr.id").read()
board.dispatch()
print hex(v)
board.getNode("timing.csr.ctrl.rst").write(1)
board.dispatch()
board.getNode("csr.ctrl.soft_rst").write(1)
board.dispatch()
board.getNode("csr.ctrl.soft_rst").write(0)
board.dispatch()
sleep(1)
board.getNode("csr.ctrl.chan").write(0x0)
board.getNode("chan.csr.ctrl.mode").write(0x0)
board.getNode("chan.csr.ctrl.src").write(0x3)
board.getNode("chan.csr.ctrl.zs_thresh").write(0x2fff)
board.getNode("chan.csr.ctrl.en_buf").write(0x1)
board.getNode("csr.ctrl.chan").write(0x1)
board.getNode("chan.csr.ctrl.mode").write(0x0)
board.getNode("chan.csr.ctrl.src").write(0x3)
board.getNode("chan.csr.ctrl.zs_thresh").write(0x1fff)
board.getNode("chan.csr.ctrl.en_buf").write(0x1)
board.getNode("trig.loc.rnd_mode").write(0x0)
board.getNode("trig.loc.rnd_div").write(0x2)
board.getNode("trig.loc.trig_en").write(0x1)
board.getNode("trig.seq.conf.addr").write(0x0)
board.getNode("trig.seq.conf.data").write(0x00020000)
board.getNode("trig.csr.ctrl.dtmon_en").write(0)
board.getNode("timing.csr.ctrl.force_sync").write(1)
board.dispatch()
sleep(1)
board.getNode("trig.csr.ctrl.dtmon_en").write(1)
board.dispatch()
while True:
board.getNode("trig.loc.trig_force").write(1)
board.getNode("trig.loc.trig_force").write(0)
board.dispatch()
sleep(1)
b0 = board.getNode("trig.csr.evt_ctr").read()
b1 = board.getNode("trig.csr.stat").read()
b2 = board.getNode("roc.csr.stat").read()
b3 = board.getNode("roc.buf.count").read()
b4 = board.getNode("roc.csr.tot_data").read()
b5 = board.getNode("chan.csr.stat").read()
board.getNode("trig.dtmon.addr").write(0)
bb = board.getNode("trig.dtmon.data").readBlock(16)
board.dispatch()
print "Evt_ctr: %08x Trig_stat: %08x Roc_stat: %08x Buf_cnt: %08x Roc_tot: %08x Chan_stat: %08x" % (int(b0), int(b1), int(b2), int(b3), int(b4), int(b5))
print "DT: ", [hex(bb[i]) for i in range(16)]
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software/ro_dump.py 0000664 0000000 0000000 00000005642 13132146003 0030405 0 ustar 00root root 0000000 0000000 #!/usr/bin/python
import uhal
from time import sleep
import sys
import collections
def zsdot(i):
return ' ' if i == 0 else '!'
def zsfmt(i):
return "%s%s%04x %s%s%04x" % (zsdot(i & 0x8000), zsdot(i & 0x4000), i & 0x3fff,
zsdot(i & 0x80000000), zsdot(i & 0x40000000), (i & 0x3fff0000) >> 16)
def dump():
b0 = board.getNode("trig.csr.evt_ctr").read() # Event counter
b1 = board.getNode("trig.csr.stat").read() # Trigger block status
b2 = board.getNode("roc.csr.stat").read() # ROC status
b3 = board.getNode("roc.buf.count").read() # ROC buffer count
b4 = board.getNode("roc.csr.tot_data").read() # ROC total data issued
b5 = board.getNode("chan.csr.stat").read() # Channel status
b6 = board.getNode("roc.csr.wctr").read() # Debug - not important
board.dispatch()
print "Evt_ctr: %08x Trig_stat: %08x Roc_stat: %08x Buf_cnt: %08x Roc_tot: %08x Chan_stat: %08x Wctr: %08x" % (int(b0), int(b1), int(b2), int(b3), int(b4), int(b5), int(b6))
uhal.setLogLevelTo(uhal.LogLevel.ERROR)
board = uhal.getDevice("board", "ipbusudp-2.0://192.168.235.1:50001", "file://addr_table/top.xml")
#board.getClient().setTimeoutPeriod(10000)
v = board.getNode("csr.id").read()
board.dispatch()
print hex(v)
board.getNode("timing.csr.ctrl.rst").write(1) # Hold clk40 domain in reset
board.dispatch()
board.getNode("csr.ctrl.soft_rst").write(1) # Reset ipbus registers
board.dispatch()
sleep(1)
board.getNode("csr.ctrl.chan").write(0x0) # Talk to channel 0
board.getNode("chan.csr.ctrl.mode").write(0x0) # Set to normal DAQ mode
board.getNode("chan.csr.ctrl.src").write(0x3) # Set source to random number generator
board.getNode("chan.csr.ctrl.zs_thresh").write(0x2fff) # Set ZS threshold
board.getNode("chan.csr.ctrl.en_buf").write(0x1) # Enable this channel
board.getNode("csr.ctrl.chan").write(0x1) # Talk to channel 1
board.getNode("chan.csr.ctrl.mode").write(0x0)
board.getNode("chan.csr.ctrl.src").write(0x3)
board.getNode("chan.csr.ctrl.zs_thresh").write(0x1fff)
board.getNode("chan.csr.ctrl.en_buf").write(0x1)
board.getNode("trig.loc.rnd_mode").write(0x3) # Set random trigger generator to Poisson mode
board.getNode("trig.loc.rnd_div").write(0xa) # Set random trigger rate to 40MHz / 2^11 = 20kHz
board.getNode("trig.loc.trig_en").write(0x1) # Enable trigger type 0 (random trigger)
board.getNode("trig.seq.conf.addr").write(0x0) # Set sequencer table to entry 0 (trigger type 0)
board.getNode("trig.seq.conf.data").write(0x00010000) # Set offet = 0, block count = 1 for trigger type 0
board.getNode("timing.csr.ctrl.force_sync").write(1) # And... go.
board.dispatch()
sleep(1)
r = list()
evts = 0
max_evts = 100
nbuf = 0
outp = open("test.bin", "bw")
while evts < max_events:
while nbuf == 0:
nbuf = board.getNode("roc.buf.count").read() # Get the buffer data count
board.dispatch()
# dump()
b = board.getNode("roc.buf.data").readBlock(int(nbuf)) # Read the buffer contents
board.dispatch()
outp.write(bytearray(b))
evts += 1
outp.close()
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software/ro_test.py 0000775 0000000 0000000 00000011130 13132146003 0030407 0 ustar 00root root 0000000 0000000 #!/usr/bin/python
import uhal
from time import sleep
import sys
import collections
def zsdot(i):
return ' ' if i == 0 else '!'
def zsfmt(i):
return "%s%s%04x %s%s%04x" % (zsdot(i & 0x8000), zsdot(i & 0x4000), i & 0x3fff,
zsdot(i & 0x80000000), zsdot(i & 0x40000000), (i & 0x3fff0000) >> 16)
def dump():
b0 = board.getNode("trig.csr.evt_ctr").read() # Event counter
b1 = board.getNode("trig.csr.stat").read() # Trigger block status
b2 = board.getNode("roc.csr.stat").read() # ROC status
b3 = board.getNode("roc.buf.count").read() # ROC buffer count
b4 = board.getNode("roc.csr.tot_data").read() # ROC total data issued
b5 = board.getNode("chan.csr.stat").read() # Channel status
b6 = board.getNode("roc.csr.wctr").read() # Debug - not important
board.dispatch()
print "Evt_ctr: %08x Trig_stat: %08x Roc_stat: %08x Buf_cnt: %08x Roc_tot: %08x Chan_stat: %08x Wctr: %08x" % (int(b0), int(b1), int(b2), int(b3), int(b4), int(b5), int(b6))
uhal.setLogLevelTo(uhal.LogLevel.ERROR)
#board = uhal.getDevice("board", "ipbusudp-2.0://192.168.235.1:50001", "file://addrtab/top.xml")
board = uhal.getDevice("board", "ipbusudp-2.0://192.168.235.16:50001", "file://addrtab/top_sim.xml")
board.getClient().setTimeoutPeriod(10000)
v = board.getNode("csr.id").read()
board.dispatch()
print hex(v)
board.getNode("timing.csr.ctrl.rst").write(1) # Hold clk40 domain in reset
board.dispatch()
board.getNode("csr.ctrl.soft_rst").write(1) # Reset ipbus registers
board.dispatch()
sleep(1)
board.getNode("csr.ctrl.chan").write(0x0) # Talk to channel 0
board.getNode("chan.csr.ctrl.mode").write(0x0) # Set to normal DAQ mode
board.getNode("chan.csr.ctrl.src").write(0x3) # Set source to random number generator
board.getNode("chan.csr.ctrl.zs_thresh").write(0x2fff) # Set ZS threshold
board.getNode("chan.csr.ctrl.en_buf").write(0x1) # Enable this channel
board.getNode("csr.ctrl.chan").write(0x1) # Talk to channel 1
board.getNode("chan.csr.ctrl.mode").write(0x0)
board.getNode("chan.csr.ctrl.src").write(0x3)
board.getNode("chan.csr.ctrl.zs_thresh").write(0x1fff)
board.getNode("chan.csr.ctrl.en_buf").write(0x1)
board.getNode("trig.loc.rnd_mode").write(0x3) # Set random trigger generator to Poisson mode
board.getNode("trig.loc.rnd_div").write(0xa) # Set random trigger rate to 40MHz / 2^11 = 20kHz
board.getNode("trig.loc.trig_en").write(0x1) # Enable trigger type 0 (random trigger)
board.getNode("trig.seq.conf.addr").write(0x0) # Set sequencer table to entry 0 (trigger type 0)
board.getNode("trig.seq.conf.data").write(0x00010000) # Set offet = 0, block count = 1 for trigger type 0
board.getNode("timing.csr.ctrl.force_sync").write(1) # And... go.
board.dispatch()
sleep(1)
r = list()
evts = 0
max_evts = 100000
while True:
while True:
v1 = board.getNode("roc.buf.count").read() # Get the buffer data count
board.dispatch()
if v1 != 0:
break
# dump()
b = board.getNode("roc.buf.data").readBlock(int(v1)) # Read the buffer contents
board.dispatch()
r += b;
while len(r) > 0:
m = int(r.pop(0))
if (m >> 16) != 0xaa00:
print "Bad news: event header incorrect"
dump()
print "%08x" % m
for i in range(len(r)):
print "%08x" % int(r[i])
sys.exit()
l = m & 0xffff
if len(r) >= l:
w0 = int(r.pop(0))
rtype = (w0 >> 28)
print "Readout type %d Len %04x" % (rtype, l)
if rtype == 0: # A data block
bctr = w0 & 0xffffff
tstamp = int(r.pop(0)) | (int(r.pop(0)) << 32)
mask = int(r.pop(0)) | int(r.pop(0)) >> 32
for _ in range(2):
r.pop(0)
c = bin(mask).count('1')
print "\tBlock %08x Time %012x Mask %016x Chans %02x" % (bctr, tstamp, mask, c)
tcnt = 0
for i in range(c):
print "%04x" % 0,
cnt = 0
zcnt = 0
while True:
cnt += 1;
g = int(r.pop(0))
if g & 0x4000 == 0:
zcnt += 1
else:
zcnt += (g & 0x3fff)
if g & 0x8000 == 0:
if g & 0x40000000 == 0:
zcnt += 1
else:
zcnt += ((g & 0x3fff0000) >> 16)
print zsfmt(g),
if cnt % 8 == 0:
print "\n%04x" % cnt,
if g & 0x80008000 != 0:
print
break;
print "\t\tChan %02x" % i, "Len: %04x" % cnt, "Zlen: %04x" % zcnt
if zcnt != 0x100:
print "Bad news: chan %02x zcnt is %04x" % (i, zcnt)
dump()
sys.exit()
tcnt += cnt
if tcnt != l - 7:
r.pop(0)
evts += 1
if evts >= max_evts:
sys.exit()
elif rtype == 1: # A trigger block
ttype = w0 & 0x3ffff
tstamp = int(r.pop(0)) | (int(r.pop(0)) << 32)
for _ in range(5):
r.pop(0)
print "\tTbits %08x Time %012x" % (ttype, tstamp)
else:
print "Unknown readout type"
sys.exit()
else:
break
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software/si5326.txt 0000664 0000000 0000000 00000006270 13132146003 0030060 0 ustar 00root root 0000000 0000000 #HEADER
# Date: 26 January 2016 15:38
# File Version: 3
# Software Name: Precision Clock EVB Software
# Software Version: 5.1
# Software Date: July 23, 2014
# Part number: Si5326
#END_HEADER
#PROFILE
# Name: Si5326
#INPUT
# Name: CKIN
# Channel: 1
# Frequency (MHz): 125.000000
# N3: 9140
# Maximum (MHz): 136.298076
# Minimum (MHz): 116.586538
#END_INPUT
#INPUT
# Name: CKIN
# Channel: 2
# Frequency (MHz): 124.998640
# N3: 9140
# CKIN2 to CKIN1 Ratio: 1562483 / 1562500
# Maximum (MHz): 136.298076
# Minimum (MHz): 116.586538
#END_INPUT
#PLL
# Name: PLL
# Frequency (MHz): 5200.000000
# XA-XB Frequency (MHz): 125.000000
# f3 (MHz): 0.013676
# N1_HS: 5
# N2_HS: 8
# N2_LS: 47528
# Phase Offset Resolution (ns): 0.96154
# BWSEL_REG Option: Frequency (Hz)
# 3: 120
# 2: 246
# 1: 513
#END_PLL
#OUTPUT
# Name: CKOUT
# Channel: 1
# Frequency (MHz): 40.000000
# NC1_LS: 26
# CKOUT1 to CKIN1 Ratio: 8 / 25
# Maximum (MHz): 43.615384
# Minimum (MHz): 37.307692
#END_OUTPUT
#OUTPUT
# Name: CKOUT
# Channel: 2
# Frequency (MHz): 40.000000
# NC_LS: 26
# CKOUT2 to CKOUT1 Ratio: 1 / 1
# Maximum (MHz): 43.615384
# Minimum (MHz): 37.307692
#END_OUTPUT
#CONTROL_FIELD
# Register-based Controls
# FREE_RUN_EN: 0x1
# CKOUT_ALWAYS_ON: 0x0
# BYPASS_REG: 0x0
# CK_PRIOR2: 0x1
# CK_PRIOR1: 0x0
# CKSEL_REG: 0x1
# DHOLD: 0x0
# SQ_ICAL: 0x1
# BWSEL_REG: 0x3
# AUTOSEL_REG: 0x0
# HIST_DEL: 0x12
# ICMOS: 0x3
# SFOUT2_REG: 0x7
# SFOUT1_REG: 0x7
# FOSREFSEL: 0x2
# HLOG_2: 0x0
# HLOG_1: 0x0
# HIST_AVG: 0x18
# DSBL2_REG: 0x0
# DSBL1_REG: 0x0
# PD_CK2: 0x0
# PD_CK1: 0x0
# CLAT: 0x0
# FLAT: 0x0
# FLAT_VALID: 0x1
# FOS_EN: 0x0
# FOS_THR: 0x1
# VALTIME: 0x1
# LOCKT: 0x4
# CK2_BAD_PIN: 0x1
# CK1_BAD_PIN: 0x1
# LOL_PIN: 0x1
# INT_PIN: 0x0
# INCDEC_PIN: 0x1
# CK1_ACTV_PIN: 0x1
# CKSEL_PIN: 0x0
# CK_ACTV_POL: 0x1
# CK_BAD_POL: 0x1
# LOL_POL: 0x1
# INT_POL: 0x1
# LOS2_MSK: 0x1
# LOS1_MSK: 0x1
# LOSX_MSK: 0x1
# FOS2_MSK: 0x1
# FOS1_MSK: 0x1
# LOL_MSK: 0x1
# N1_HS: 0x1
# NC1_LS: 0x19
# NC2_LS: 0x19
# N2_LS: 0xB9A7
# N2_HS: 0x4
# N31: 0x23B3
# N32: 0x23B3
# CLKIN2RATE: 0x0
# CLKIN1RATE: 0x0
# LOS1_EN: 0x3
# LOS2_EN: 0x3
# FOS1_EN: 0x1
# FOS2_EN: 0x1
# INDEPENDENTSKEW1: 0x0
# INDEPENDENTSKEW2: 0x0
#END_CONTROL_FIELD
#REGISTER_MAP
0, 54h
1, E4h
2, 32h
3, 55h
4, 12h
5, EDh
6, 3Fh
7, 2Ah
8, 00h
9, C0h
10, 00h
11, 40h
16, 00h
17, 80h
18, 00h
19, 2Ch
20, 3Eh
21, FEh
22, DFh
23, 1Fh
24, 3Fh
25, 20h
31, 00h
32, 00h
33, 19h
34, 00h
35, 00h
36, 19h
40, 80h
41, B9h
42, A7h
43, 00h
44, 23h
45, B3h
46, 00h
47, 23h
48, B3h
55, 00h
131, 1Fh
132, 02h
138, 0Fh
139, FFh
142, 00h
143, 00h
136, 40h
#END_REGISTER_MAP
#END_PROFILE
euro-adc-65m-14b-40cha-gw-241d34c7b2fad944e690953ce049924c15853d31/projects/8ch/software/talk.py 0000775 0000000 0000000 00000025555 13132146003 0027703 0 ustar 00root root 0000000 0000000 #!/usr/bin/python
import uhal
import csv
from time import sleep
import sys
import random
import datetime
import StringIO
#Initialize board
def init_board(library,deviceaddress,xmlfile):
global board
uhal.setLogLevelTo(uhal.LogLevel.INFO)
board = uhal.getDevice("glib", "ipbusudp-2.0://"+deviceaddress+":50001", "file://"+xmlfile)
board.getClient().setTimeoutPeriod(10000)
nodeslist=board.getNodes()
deletelist=[]
return nodeslist
#Define global standard variables
def std_address(addr="192.168.235.0"):
global library,deviceaddress,xmlfile
library="glib"
deviceaddress=addr
xmlfile="addrtab/top.xml"
#Initialize node
def init_node(nodename):
ctrl_reg= board.getNode(nodename)
return ctrl_reg
# Check if it is possible to read and write the register
def show_permits(node):
rights=node.getPermission()
board.dispatch()
return rights
# Read register
def readreg(node):
readvalue=node.read()
board.dispatch()
return readvalue
# Write register
def writereg(node,writevalue):
node.write(writevalue)
board.dispatch()
# Write register and do not dispatch board
def writeregandwait(node,writevalue):
node.write(writevalue)
# Write register, read back and compare values
def testreg(node):
writevalue=random.randint(0,4294967295) #random uint value
writereg(node,writevalue)
readvalue=readreg(node)
if writevalue==readvalue:
failure = 0
else:
failure = 1
#print writevalue,readvalue,failure
return failure
# Create bit array
def bitfield(n,arraylength):
bitarray=[int(digit) for digit in bin(n)[2:]]
if len(bitarray)