Commit 79a80152 authored by Dave Newbold's avatar Dave Newbold

First cleanup of dep files for ipbb

parent 5a48690b
......@@ -13,8 +13,8 @@ operating system (e.g. Centos7) is required.
source ipbb-0.2.3/env.sh
ipbb init build
cd build
ipbb add git https://github.com/ipbus/ipbus-firmware.git -b tags/ipbus_2_0_v1
ipbb add git BITBUCKET-URL -b tags/v8
ipbb add git https://github.com/ipbus/ipbus-firmware.git -b ipbus_2_0_v1
ipbb add git BITBUCKET-URL -b v8
ipbb proj create vivado 64chan solid:projects/64chan_test
cd proj/64chan
ipbb vivado project
......
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
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
@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
-- 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-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;
@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
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
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
-- 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-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_a_p: inout std_logic;
sync_a_n: inout std_logic;
sync_b_p: inout std_logic;
sync_b_n: inout std_logic;
-- sync_c_p: inout std_logic;
-- sync_c_n: inout 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_a_p => sync_a_p,
sync_a_n => sync_a_n,
sync_b_p => sync_b_p,
sync_b_n => sync_b_n,
-- sync_c_p => sync_c_p,
-- sync_c_n => sync_c_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;
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 {sync_*}]
set_property PACKAGE_PIN J15 [get_ports {sync_a_p}]
set_property PACKAGE_PIN H15 [get_ports {sync_a_n}]
set_property PACKAGE_PIN G17 [get_ports {sync_b_p}]
set_property PACKAGE_PIN G18 [get_ports {sync_b_n}]
#set_property PACKAGE_PIN H17 [get_ports {sync_c_p}]
#set_property PACKAGE_PIN H18 [get_ports {sync_c_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
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
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
@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
-- 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-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;
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
@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
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
-- 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-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;
t_sync: in std_logic; -- IO via timing interface
t_trig: in std_logic;
t_busy: 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,
t_sync => t_sync,
t_trig => t_trig,
t_busy => t_busy,
adc_d_p => adc_d_p,
adc_d_n => adc_d_n
);
end rtl;
This diff is collapsed.
<node description="Frequency counter" fwinfo="endpoint;width=1">
<node id="ctrl" address="0x0">
<node id="chan_sel" mask="0xf"/>
<node id="en_crap_mode" mask="0x10"/>
</node>
<node id="freq" address="0x1">
<node id="count" mask="0xffffff"/>
<node id="valid" mask="0x1000000"/>
</node>
</node>
<node description="MP7 TTC block control registers" fwinfo="endpoint" class="TTCNode">
<node id="csr" address="0x0" description="MP7 TTC block" fwinfo="endpoint;width=3">
<node id="ctrl" address="0x0">
<node id="ttc_enable" mask="0x1"/>
<node id="err_ctr_clear" mask="0x2"/>
<node id="rst" mask="0x4"/>
<node id="int_bc0_enable" mask="0x8"/>
<node id="ctr_clear" mask="0x40"/>
<node id="l1a_force" mask="0x80"/>
<node id="throttle_en" mask="0x100"/>
<node id="b_cmd_force" mask="0x200"/>
<node id="ttc_sync_en" mask="0x400"/>
<node id="ttc_sync_bx" mask="0xfff000"/>
<node id="b_cmd" mask="0xff000000"/>
</node>
<node id="ctrl1" address="0x1">
<node id="ttc_phase" mask="0xfff"/>
<node id="ttc_phase_en" mask="0x1000"/>
<node id="c_del" mask="0x1f0000"/>
</node>
<node id="stat0" address="0x4">
<node id="bunch_ctr" mask="0xfff"/>
<node id="bc0_lock" mask="0x10000"/>
<node id="dist_lock" mask="0x20000"/>
<node id="ttc_phase_ok" mask="0x40000"/>
<node id="force_pending" mask="0x80000"/>
<node id="orb_len" mask="0xfff00000"/>
</node>
<node id="stat1" address="0x5">
<node id="evt_ctr" mask="0xffffffff"/>
</node>
<node id="stat2" address="0x6">
<node id="orb_ctr" mask="0xffffffff"/>
</node>
<node id="stat3" address="0x7">
<node id="single_biterr_ctr" mask="0xffff"/>
<node id="double_biterr_ctr" mask="0xffff0000"/>
</node>
</node>
<node id="freq" address="0x8" module="file://freq_ctr.xml"/>
<node id="l1_gen" address="0xa" description="L1A random generator" fwinfo="endpoint;width=1">
<node id="ctrl" address="0x0">
<node id="rate" mask="0x3fffffff"/>
<node id="rules_en" mask="0x80000000"/>
</node>
<node id="trig_cnt" address="0x1"/>
</node>
<node id="hist" module="file://state_history.xml" address="0xc"/>
<node id="cmd_ctrs" address="0x10" description="TTC command counters" fwinfo="endpoint;width=3">
<node id="bc0_ctr" address="0x0"/>
<node id="ec0_ctr" address="0x1"/>
<node id="resync_ctr" address="0x2"/>
<node id="oc0_ctr" address="0x3"/>
<node id="test_sync_ctr" address="0x4"/>
<node id="start_ctr" address="0x5"/>
<node id="stop_ctr" address="0x6"/>
</node>
<node id="tmt" address="0x18" description="TMT cycle control" fwinfo="endpoint;width=0">
<node id="max_phase" mask="0xf"/>
<node id="phase" mask="0xf0"/>
<node id="l1a_offset" mask="0xf00"/>
<node id="pkt_offset" mask="0xf000"/>
<node id="en" mask="0x10000"/>
</node>
</node>
<node description="State history buffer" fwinfo="endpoint" class="StateHistoryNode">
<node id="csr" address="0x0" description="State history CSR" fwinfo="endpoint;width=1">
<node id="ctrl" address="0x0">
<node id="freeze" mask="0x1"/>
<node id="rst" mask="0x2"/>
<node id="mask" mask="0xffff0000"/>
</node>
<node id="stat" address="0x1">
<node id="ptr" mask="0xffff"/>
<node id="wrap_flag" mask="0x10000"/>
</node>
</node>
<node id="buffer" address="0x2" description="History buffer" fwinfo="endpoint;width=1">
<node id="addr" address="0x0"/>
<node id="data" address="0x1" size="0x800" mode="port" permission="r"/>
</node>
</node>
src mp7_ttc.vhd ttc_clocks.vhd
include mp7_ttc_common.dep
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
src ../sim_hdl/mp7_ttc_sim.vhd ../sim_hdl/ttc_clocks_sim.vhd
include mp7_ttc_common.dep
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
This diff is collapsed.
##############################################################
#
# 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
Annotated address table for mp7_ttc
DMN, 13-07-15
<node>
<node id="ttc" address="0x0" description="MP7 TTC block" tags="slave">
This block contains the control registers for the TTC decoder block, and the various
LHC counters.
<node id="ctrl" address="0x0">
<node id="ttc_enable" mask="0x1"/>
Set to enable L1A and B-commands from the external (AMC13) TTC input.
<node id="err_ctr_clear" mask="0x2"/>
Set to clear the single and double error counters (clears on rising edge only).
<node id="l1a_send" mask="0x4"/>
Set to issue a single L1A - there is currently no way to specify the
BX on which this happens.
<node id="int_bc0_enable" mask="0x8"/>
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.
<node id="mask_hist_bc0" mask="0x10"/>
Set to prevent BC0 commands being recorded in the history buffer. All B-commands
(including BC0) are recorded by default.
<node id="fill_hist_buf" mask="0x20"/>
Set to begin filling the history buffer (begins on rising edge, stops only when full).
<node id="m_del_inc" mask="0x40"/>
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.
<node id="ctr_clear" mask="0x80"/>
Set to clear the LHC counters (clears on rising edge only).
<node id="buf_go" mask="0x100"/>
Set to fill the capture buffers (edge-sensitive).
<node id="b_send" mask="0xff0000"/>
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!).
<node id="c_del" mask="0xff000000"/>
Specifies the global delay to all external (AMC13) TTC signals in BX.
</node>
<node id="stat0" address="0x4">
<node id="bunch_ctr" mask="0xfff"/>
LHC bunch counter (0 -> 0xdeb).
<node id="del_rdy" mask="0x10000000"/>
Flag indicating that TTC sampling clock fine delay block is ready for use.
</node>
<node id="stat1" address="0x5">
<node id="evt_ctr" mask="0xffffff"/>
LHC event counter (starts at 0x1 after reset, a la CMS rules)
</node>
<node id="stat2" address="0x6">
<node id="orb_ctr" mask="0xffffff"/>
LHC orbit counter (starts at 0x0 after reset - correct or not?)
</node>
<node id="stat3" address="0x7">
<node id="single_biterr_ctr" mask="0xffff"/>
TTC decoder single bit error counter.
<node id="double_biterr_ctr" mask="0xffff0000"/>
TTC decoder double bit error counter.
</node>
</node>
<node id="ttc_freq" address="0x8" description="TTC frequency counter" tags="slave">
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).
<node id="clk40_freq" address="0x0"/>
<node id="clk240_freq" address="0x1"/>
</node>
<node id="ttc_hist_buf" address="0xa" description="TTC history buffer" tags="slave"/>
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
</node>
-- 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
--
-- 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
--
-- 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;
-- 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;
-- 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
--
-- 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
--
-- 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_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;
This diff is collapsed.
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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
--
-- 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;
This diff is collapsed.
-- 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;
<node description="I2C master controller" fwinfo="endpoint;width=3">
<node id="ps_lo" address="0x0" description="Prescale low byte"/>
<node id="ps_hi" address="0x1" description="Prescale low byte"/>
<node id="ctrl" address="0x2" description="Control"/>
<node id="data" address="0x3" description="Data"/>
<node id="cmd_stat" address="0x4" description="Command / status"/>
</node>
src ipbus_i2c_master.vhd i2c_master_top.vhd i2c_master_registers.vhd i2c_master_byte_ctrl.vhd i2c_master_bit_ctrl.vhd
addrtab opencores_i2c.xml
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
This diff is collapsed.
This diff is collapsed.
----------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<
----------------------------------------------------------------------
--///////////////////////////////////////////////////////////////////
--// ////
--// WISHBONE rev.B2 compliant I2C Master registers ////
--// ////
--// ////
--// Author: Richard Herveille ////
--// richard@asics.ws ////
--// www.asics.ws ////
--// ////
--// Downloaded from: http://www.opencores.org/projects/i2c/ ////
--// ////
--///////////////////////////////////////////////////////////////////
--// ////
--// Copyright (C) 2001 Richard Herveille ////
--// richard@asics.ws ////
--// ////
--// This source file may be used and distributed without ////
--// restriction provided that this copyright statement is not ////
--// removed from the file and that any derivative work contains ////
--// the original copyright notice and the associated disclaimer.////
--// ////
--// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
--// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
--// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
--// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
--// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
--// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
--// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
--// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
--// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
--// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
--// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
--// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
--// POSSIBILITY OF SUCH DAMAGE. ////
--// ////
--///////////////////////////////////////////////////////////////////
-- --------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-- --------------------------------------------------------------------
-- Copyright (c) 2008 - 2010 by Lattice Semiconductor Corporation
-- --------------------------------------------------------------------
--
-- Disclaimer:
--
-- This VHDL or Verilog source code is intended as a design reference
-- which illustrates how these types of functions can be implemented.
-- It is the user's responsibility to verify their design for
-- consistency and functionality through the use of formal
-- verification methods. Lattice Semiconductor provides no warranty
-- regarding the use or functionality of this code.
--
-- --------------------------------------------------------------------
--
-- Lattice Semiconductor Corporation
-- 5555 NE Moore Court
-- Hillsboro, OR 97214
-- U.S.A
--
-- TEL: 1-800-Lattice (USA and Canada)
-- 503-268-8001 (other locations)
--
-- web: http://www.latticesemi.com/
-- email: techsupport@latticesemi.com
--
-- --------------------------------------------------------------------
-- Code Revision History :
-- --------------------------------------------------------------------
-- Ver: | Author |Mod. Date |Changes Made:
-- V1.0 |K.P. | 7/09 | Initial ver for VHDL
-- | converted from LSC ref design RD1046
-- --------------------------------------------------------------------
-- --------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity i2c_master_registers is
port (
wb_clk_i : in std_logic;
rst_i : in std_logic;
wb_rst_i : in std_logic;
wb_dat_i : in std_logic_vector(7 downto 0);
wb_adr_i : in std_logic_vector(2 downto 0);
wb_wacc : in std_logic;
i2c_al : in std_logic;
i2c_busy : in std_logic;
done : in std_logic;
irxack : in std_logic;
prer : out std_logic_vector(15 downto 0); -- clock prescale register
ctr : out std_logic_vector(7 downto 0); -- control register
txr : out std_logic_vector(7 downto 0); -- transmit register
cr : out std_logic_vector(7 downto 0); -- command register
sr : out std_logic_vector(7 downto 0) -- status register
);
end;
architecture arch of i2c_master_registers is
signal ctr_int : std_logic_vector(7 downto 0);
signal cr_int : std_logic_vector(7 downto 0);
signal al : std_logic; -- status register arbitration lost bit
signal rxack : std_logic; -- received aknowledge from slave
signal tip : std_logic; -- transfer in progress
signal irq_flag : std_logic; -- interrupt pending flag
begin
-- generate prescale regisres, control registers, and transmit register
process(wb_clk_i,rst_i)
begin
if (rst_i = '0') then
prer <= (others => '1');
ctr_int <= (others => '0');
txr <= (others => '0');
elsif rising_edge(wb_clk_i) then
if (wb_rst_i = '1') then
prer <= (others => '1');
ctr_int <= (others => '0');
txr <= (others => '0');
elsif (wb_wacc = '1') then
case (wb_adr_i) is
when "000" => prer(7 downto 0) <= wb_dat_i;
when "001" => prer(15 downto 8) <= wb_dat_i;
when "010" => ctr_int <= wb_dat_i;
when "011" => txr <= wb_dat_i;
when others => NULL;
end case;
end if;
end if;
end process;
ctr <= ctr_int;
-- generate command register (special case)
process(wb_clk_i,rst_i)
begin
if (rst_i = '0') then
cr_int <= (others => '0');
elsif rising_edge(wb_clk_i) then
if (wb_rst_i = '1') then
cr_int <= (others => '0');
elsif (wb_wacc = '1') then
if ((ctr_int(7) = '1') AND (wb_adr_i = "100")) then
cr_int <= wb_dat_i;
end if;
else
if ((done = '1') OR (i2c_al = '1')) then
cr_int(7 downto 4) <= "0000"; -- clear command b
end if; -- or when aribitr
cr_int(2 downto 1) <= "00"; -- reserved bits
cr_int(0) <= '0'; -- clear IRQ_ACK b
end if;
end if;
end process;
cr <= cr_int;
-- generate status register block + interrupt request signal
-- each output will be assigned to corresponding sr register locations on top level
process(wb_clk_i,rst_i)
begin
if (rst_i = '0') then
al <= '0';
rxack <= '0';
tip <= '0';
irq_flag <= '0';
elsif rising_edge(wb_clk_i) then
if (wb_rst_i = '1') then
al <= '0';
rxack <= '0';
tip <= '0';
irq_flag <= '0';
else
al <= i2c_al OR (al AND NOT(cr_int(7)));
rxack <= irxack;
tip <= (cr_int(5) OR cr_int(4));
irq_flag <= (done OR i2c_al OR irq_flag) AND NOT(cr_int(0)); -- interrupt request flag is always generated
end if;
end if;
end process;
sr(7) <= rxack;
sr(6) <= i2c_busy;
sr(5) <= al;
sr(4 downto 2) <= "000"; -- reserved
sr(1) <= tip;
sr(0) <= irq_flag;
end arch;
This diff is collapsed.
This diff is collapsed.
<node description="SPI master controller" fwinfo="endpoint;width=3">
<node id="d0" address="0x0" description="Data reg 0"/>
<node id="d1" address="0x1" description="Data reg 1"/>
<node id="d2" address="0x2" description="Data reg 2"/>
<node id="d3" address="0x3" description="Data reg 3"/>
<node id="ctrl" address="0x4" description="Control reg"/>
<node id="divider" address="0x5" description="Clock divider reg"/>
<node id="ss" address="0x6" description="Slave select reg"/>
</node>
src ipbus_spi.vhd spi_top.v spi_clgen.v spi_shift.v spi_defines.v timescale.v
addrtab opencores_spi.xml
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<node id="chan" description="channel controls" fwinfo="endpoint">
<node id="csr" address="0x0" description="ctrl/status register" fwinfo="endpoint;width=1">
<node id="ctrl" address="0x0">
<node id="en_sync" mask="0x1"/>
<node id="en_buf" mask="0x2"/>
<node id="invert" mask="0x4"/>
<node id="mode" mask="0x30"/>
<node id="src" mask="0xc0"/>
<node id="zs_thresh" mask="0x3fff0000"/>
</node>
<node id="stat" address="0x1">
<node id="cap_full" mask="0x1"/>
<node id="buf_full" mask="0x2"/>
<node id="dr_full" mask="0x4"/>
<node id="dr_warn" mask="0x8"/>
<node id="err" mask="0x10"/>
</node>
</node>
<node id="buf" address="0x2" description="channel buffers" fwinfo="endpoint;width=1">
<node id="addr" address="0x0"/>
<node id="data" address="0x1" mode="port"/>
</node>
<node id="ptrs" address="0x4" description="buffer pointers" fwinfo="endpoint;width=1">
<node id="zs" address="0x0">
<node id="rw" mask="0xffff"/>
<node id="flags" mask="0xffff0000"/>
</node>
<node id="nzs" address="0x1">
<node id="r" mask="0xffff"/>
<node id="w" mask="0xffff0000"/>
</node>
</node>
<node id="trig_thresh" address="0x8" description="trigger thresholds" fwinfo="endpoint;width=2">
<node id="threshtrig_thresh" address="0x0"/>
<node id="neutrontrig_signal_thresh" address="0x1"/>
<node id="neutrontrig_feature_thresh" address="0x2"/>
</node>
</node>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment