Commit 26205456 authored by Dave Newbold's avatar Dave Newbold

Adding timing board design

parent c9108da9
......@@ -9,8 +9,8 @@
<node id="rveto" mask="0x2"/>
</node>
</node>
<node id="loc_mask" address="0x4" description="local trigger generator" fwinfo="endpoint;width=0">
</node>
<node id="loc_mask" address="0x4" description="local trigger generator" fwinfo="endpoint;width=0"/>
<node id="zs_cfg" address="0x5" description="ZS threshold selection" fwinfo="endpoint;width=0"/>
<node id="dtmon" address="0x6" description="deadtime monitor buffer" fwinfo="endpoint;width=1">
<node id="addr" address="0x0"/>
<node id="data" address="0x1" mode="port"/>
......
src sc_trig.vhd sc_local_trig.vhd sc_trig_ro_block.vhd sc_deadtime_mon.vhd
src sc_trig.vhd sc_local_trig.vhd sc_zs_sel.vhd sc_trig_ro_block.vhd sc_deadtime_mon.vhd
src sc_trig_gen.vhd sc_trig_gen_or.vhd
include sc_seq.dep
src ipbus_decode_sc_trig.vhd
......
......@@ -12,20 +12,14 @@ use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.top_decl.all;
entity sc_local_trig is
port(
clk: in std_logic; -- ipbus clock (nominally ~30MHz) & reset
rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
clk40: in std_logic;
rst40: in std_logic;
trig_en: in std_logic;
en: in std_logic;
mask: in std_logic(N_TRG - 1 downto 0);
mark: in std_logic;
sctr: in std_logic_vector(47 downto 0);
rand: in std_logic_vector(31 downto 0);
......@@ -47,34 +41,16 @@ end sc_local_trig;
architecture rtl of sc_local_trig is
signal ctrl: ipb_reg_v(0 downto 0);
signal ctrl_trig_en: std_logic_vector(N_TRG - 1 downto 0);
signal tv, te, ta, tc: std_logic_vector(N_TRG - 1 downto 0);
signal s: integer range N_TRG - 1 downto 0;
signal ch: integer range 2 ** ro_ctr'length - 1 downto 0;
signal ch_i: integer range N_CHAN - 1 downto 0 := 0;
signal cact: sc_ltrig_array;
signal go, blkend, rveto_d, last_gasp, hoorah: std_logic;
signal bi: std_logic_vector(63 downto 0);
signal b: std_logic_vector(31 downto 0);
begin
-- Control register
csr: 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) => (N_TRG - 1 downto 0 => '1', others => '0')
);
ctrl_trig_en <= ctrl(0)(N_TRG - 1 downto 0);
-- Threshold trigger generator
......@@ -85,10 +61,11 @@ begin
)
port map(
clk => clk40,
en => trig_en,
en => en,
mark => mark,
chan_trig => chan_trig,
hit => thresh_hit,
chan_act => cact(0),
valid => tv(0),
ack => ta(0)
);
......@@ -102,9 +79,10 @@ begin
)
port map(
clk => clk40,
en => trig_en,
en => en,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(1),
valid => tv(1),
ack => ta(1)
);
......@@ -118,9 +96,10 @@ begin
)
port map(
clk => clk40,
en => trig_en,
en => en,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(2),
valid => tv(2),
ack => ta(2)
);
......@@ -133,18 +112,20 @@ begin
)
port map(
clk => clk40,
en => trig_en,
en => en,
mark => mark,
trig => force,
valid => tv(3),
ack => ta(3)
);
cact(3) <= (others => '0');
-- Add more trigger generators here...
-- Priority encoder
te <= tv and ctrl_trig_en(tv'range);
te <= tv and mask;
process(te)
begin
......@@ -173,7 +154,7 @@ begin
process(clk40)
begin
if rising_edge(clk40) then
if trig_en = '0' or blkend = '1' then
if en = '0' or blkend = '1' then
tc <= (others => '0');
else
tc <= tc or ta;
......@@ -183,20 +164,20 @@ begin
-- Last gasp message flag
rveto_d <= rveto and trig_en when rising_edge(clk40) and mark = '1';
rveto_d <= rveto and en when rising_edge(clk40) and mark = '1';
last_gasp <= rveto and not rveto_d;
hoorah <= rveto_d and not rveto;
-- Trigger data to readout
go <= (go or (ro_go and ((or_reduce(tc) and not rveto) or last_gasp or hoorah))) and not blkend and trig_en and not rst40 when rising_edge(clk40);
go <= (go or (ro_go and ((or_reduce(tc) and not rveto) or last_gasp or hoorah))) and not blkend and en and not rst40 when rising_edge(clk40);
blkend <= '1' when unsigned(ro_ctr) = 3 + 2 * N_CHAN_TRG else '0';
ro_valid <= go;
ro_blkend <= blkend;
ch <= to_integer(unsigned(ro_ctr(ro_ctr'length - 1 downto 1)));
ch_i <= ch - 2 when ch > 1 and ch < N_CHAN_TRG else 0;
bi <= (63 downto N_CHAN => '0') & chan_trig(ch_i);
bi <= (63 downto N_CHAN => '0') & cact(ch_i);
b <= bi(63 downto 32) when ro_ctr(0) = '1' else bi(31 downto 0);
with ro_ctr select ro_q <=
......
-- sc_trig_timing
-- sc_timing_startup
--
-- Controls various enables to set up data flow through buffers, etc
--
......
......@@ -56,9 +56,11 @@ architecture rtl of sc_trig is
signal stat: ipb_reg_v(1 downto 0);
signal ctrl_dtmon_en: std_logic;
signal masks: ipb_reg_v(N_CHAN_TRG * 2 - 1 downto 0);
signal trig_mask: std_logic_vector(N_TRG - 1 downto 0);
signal ctrig: sc_trig_array;
signal lq: std_logic_vector(15 downto 0);
signal rveto, lvalid, lack, mark, err: std_logic;
signal zs_cfg: std_logic_vector(31 downto 0);
signal veto_p, veto_i, keep_i, flush_i: std_logic_vector(N_CHAN - 1 downto 0);
signal b_q, t_q: std_logic_vector(31 downto 0);
signal b_go, t_go, b_valid, t_valid, b_blkend, t_blkend, blkend: std_logic;
......@@ -142,15 +144,25 @@ begin
-- Local trigger logic
ltrig: entity work.sc_local_trig
ltrig_reg: entity work.ipbus_reg_v
generic map(
N_REG => 1
)
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_LOC_MASK),
ipb_out => ipbr(N_SLV_LOC_MASK),
reset => rst,
ipbus_in => ipbw(N_SLV_LOC_MASK),
ipbus_out => ipbr(N_SLV_LOC_MASK),
q => trig_mask,
qmask(0) => (N_TRG - 1 downto 0 => '1', others => '0')
);
ltrig: entity work.sc_local_trig
port map(
clk40 => clk40,
rst40 => rst40,
trig_en => trig_en,
en => trig_en,
mask => trig_mask,
mark => mark,
sctr => sctr,
rand => rand,
......@@ -173,7 +185,28 @@ begin
-- ZS threshold select
zs_sel <= "00";
zsreg: entity work.ipbus_reg_v
generic map(
N_REG => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipbw(N_SLV_ZS_CFG),
ipbus_out => ipbr(N_SLV_ZS_CFG),
q(0) => zs_cfg
);
zssel: entity work.sc_zs_sel
port map(
clk40 => clk40,
rst40 => rst40,
mark => mark,
zscfg => zs_cfg,
trig => lq,
trig_valid => lvalid,
sel => zs_sel
);
-- Readout sequencer
......
......@@ -23,6 +23,7 @@ entity sc_trig_gen_or is
mark: in std_logic;
chan_trig: in sc_trig_array;
hit: out std_logic;
chan_act: out std_logic_vector(N_CHAN - 1 downto 0);
valid: out std_logic;
ack: in std_logic
);
......@@ -33,6 +34,7 @@ architecture rtl of sc_trig_gen_or is
signal t, m, tc, v: std_logic;
signal mark_del: std_logic_vector(DELAY - 1 downto 0);
signal c: std_logic_vector(N_CHAN - 1 downto 0);
begin
......@@ -49,10 +51,17 @@ begin
if rising_edge(clk) then
if en = '0' then
tc <= '0';
c <= (others => '0');
elsif t = '1' then
tc <= '1';
if m = '0' then
c <= c or chan_trig(TBIT);
else
c <= chan_trig(TBIT);
end if;
elsif m = '1' then
tc <= '0';
c <= (others => '0')
end if;
end if;
end process;
......@@ -62,5 +71,6 @@ begin
hit <= t;
v <= (v or (tc and m)) and not (mark or ack or not en) when rising_edge(clk);
valid <= v;
chan_act <= c when m = '1' and rising_edge(clk);
end rtl;
......@@ -19,13 +19,13 @@ package top_decl is
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 0; -- Additional samples to form channel trigger
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
subtype sc_trig_t is std_logic_vector(N_CHAN - 1 downto 0);
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of sc_trig_t;
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
......@@ -19,13 +19,13 @@ package top_decl is
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 0; -- Additional samples to form channel trigger
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
subtype sc_trig_t is std_logic_vector(N_CHAN - 1 downto 0);
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of sc_trig_t;
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
......@@ -19,13 +19,13 @@ package top_decl is
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant ZS_BLKS: integer := 2; -- Time window for ZS buffer
constant ZS_DEL: integer := 0; -- Additional samples to form channel trigger
constant ZS_DEL: integer := 8; -- Additional samples to form channel trigger
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
subtype sc_trig_t is std_logic_vector(N_CHAN - 1 downto 0);
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of sc_trig_t;
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
end top_decl;
<node id="TOP">
<node id="io" address="0x0" module="file://pdts_fmc_io.xml"/>
<node id="master" address="0x200" module="file://master.xml"/>
</node>
src top_enclustra_ax3_pm3.vhd
src -c components/pdts --cd ../ucf pc053_ax3_pm3.tcl
include -c ipbus-firmware:boards/enclustra_ax3_pm3/base_fw/synth a35.dep
include -c ipbus-firmware:boards/enclustra_ax3_pm3/base_fw/synth enclustra_ax3_pm3.dep
src payload.vhd
src ipbus_decode_top.vhd
addrtab -t top.xml
src -c ipbus-firmware:components/ipbus_core ipbus_fabric_sel.vhd
include -c components/pdts pdts_fmc_io.dep
src -c components/pdts pdts_rx_div_mmcm.vhd
src -c components/pdts pdts_synchro.vhd
include master_top.dep
src -c ipbus-firmware:components/ipbus_core ipbus_package.vhd
include enclustra_ax3_pm3_a35.dep
include payload.dep
-- master
--
-- Interface to timing FMC v1 for PDTS master block
--
-- Dave Newbold, February 2017
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
use work.ipbus_decode_top.all;
entity payload is
port(
ipb_clk: in std_logic;
ipb_rst: in std_logic;
ipb_in: in ipb_wbus;
ipb_out: out ipb_rbus;
nuke: out std_logic;
soft_rst: out std_logic;
userled: out std_logic;
clk125: in std_logic;
fmc_clk_p: in std_logic;
fmc_clk_n: in std_logic;
rec_clk_p: in std_logic;
rec_clk_n: in std_logic;
rec_d_p: in std_logic;
rec_d_n: in std_logic;
clk_out_p: out std_logic;
clk_out_n: out std_logic;
rj45_din_p: in std_logic;
rj45_din_n: in std_logic;
rj45_dout_p: out std_logic;
rj45_dout_n: out std_logic;
sfp_dout_p: out std_logic;
sfp_dout_n: out std_logic;
cdr_lol: in std_logic;
cdr_los: in std_logic;
sfp_los: in std_logic;
sfp_tx_dis: out std_logic;
sfp_flt: in std_logic;
uid_scl: out std_logic;
uid_sda: inout std_logic;
sfp_scl: out std_logic;
sfp_sda: inout std_logic;
pll_scl: out std_logic;
pll_sda: inout std_logic;
pll_rstn: out std_logic;
gpin_0_p: in std_logic;
gpin_0_n: in std_logic;
gpout_0_p: out std_logic;
gpout_0_n: out std_logic;
gpout_1_p: out std_logic;
gpout_1_n: out std_logic
);
end payload;
architecture rtl of payload is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal fmc_clk, rec_clk, rec_d, sfp_dout, rst_io, rsti, clk, stb, rst, locked: std_logic;
attribute IOB: string;
attribute IOB of sfp_dout: signal is "TRUE";
begin
-- ipbus address decode
fabric: entity work.ipbus_fabric_sel
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_top(ipb_in.ipb_addr),
ipb_to_slaves => ipbw,
ipb_from_slaves => ipbr
);
-- IO
io: entity work.pdts_fmc_io
port map(
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipbw(N_SLV_IO),
ipb_out => ipbr(N_SLV_IO),
soft_rst => soft_rst,
nuke => nuke,
rst => rst_io,
locked => locked,
cdr_lol => cdr_lol,
cdr_los => cdr_los,
sfp_los => sfp_los,
sfp_tx_dis => sfp_tx_dis,
sfp_flt => sfp_flt,
userled => userled,
fmc_clk_p => fmc_clk_p,
fmc_clk_n => fmc_clk_n,
fmc_clk => fmc_clk,
rec_clk_p => rec_clk_p,
rec_clk_n => rec_clk_n,
rec_clk => rec_clk,
rec_d_p => rec_d_p,
rec_d_n => rec_d_n,
rec_d => rec_d,
clk_out_p => clk_out_p,
clk_out_n => clk_out_n,
rj45_din_p => rj45_din_p,
rj45_din_n => rj45_din_n,
rj45_dout_p => rj45_dout_p,
rj45_dout_n => rj45_dout_n,
sfp_dout => sfp_dout,
sfp_dout_p => sfp_dout_p,
sfp_dout_n => sfp_dout_n,
uid_scl => uid_scl,
uid_sda => uid_sda,
sfp_scl => sfp_scl,
sfp_sda => sfp_sda,
pll_scl => pll_scl,
pll_sda => pll_sda,
pll_rstn => pll_rstn,
gpin_0_p => gpin_0_p,
gpin_0_n => gpin_0_n,
gpout_0_p => gpout_0_p,
gpout_0_n => gpout_0_n,
gpout_1_p => gpout_1_p,
gpout_1_n => gpout_1_n
);
-- Clock divider
clkgen: entity work.pdts_rx_div_mmcm
port map(
sclk => fmc_clk,
clk => clk,
phase_rst => rst_io,
phase_locked => locked
);
rsti <= rst_io or not locked;
synchro: entity work.pdts_synchro
generic map(
N => 1
)
port map(
clk => ipb_clk,
clks => clk,
d(0) => rsti,
q(0) => rst
);
-- master block
master: entity work.master
port map(
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipbw(N_SLV_MASTER),
ipb_out => ipbr(N_SLV_MASTER),
mclk => fmc_clk,
clk => clk,
rst => rst,
q => sfp_dout
);
end rtl;
-- Top-level design for ipbus demo
--
-- This version is for Enclustra AX3 module, using the RGMII PHY on the PM3 baseboard
--
-- You must edit this file to set the IP and MAC addresses
--
-- Dave Newbold, 4/10/16
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.ALL;
entity top is port(
sysclk: in std_logic;
leds: out std_logic_vector(3 downto 0); -- status LEDs
cfg: in std_logic_vector(3 downto 0); -- switches
rgmii_txd: out std_logic_vector(3 downto 0);
rgmii_tx_ctl: out std_logic;
rgmii_txc: out std_logic;
rgmii_rxd: in std_logic_vector(3 downto 0);
rgmii_rx_ctl: in std_logic;
rgmii_rxc: in std_logic;
phy_rstn: out std_logic;
fmc_clk_p: in std_logic;
fmc_clk_n: in std_logic;
rec_clk_p: in std_logic;
rec_clk_n: in std_logic;
rec_d_p: in std_logic;
rec_d_n: in std_logic;
clk_out_p: out std_logic;
clk_out_n: out std_logic;
rj45_din_p: in std_logic;
rj45_din_n: in std_logic;
rj45_dout_p: out std_logic;
rj45_dout_n: out std_logic;
sfp_dout_p: out std_logic;
sfp_dout_n: out std_logic;
pll_rstn: out std_logic;
cdr_lol: in std_logic;
cdr_los: in std_logic;
sfp_los: in std_logic;
sfp_tx_dis: out std_logic;
sfp_flt: in std_logic;
uid_scl: out std_logic;
uid_sda: inout std_logic;
sfp_scl: out std_logic;
sfp_sda: inout std_logic;
pll_scl: out std_logic;
pll_sda: inout std_logic;
gpin_0_p: in std_logic;
gpin_0_n: in std_logic;
gpout_0_p: out std_logic;
gpout_0_n: out std_logic;
gpout_1_p: out std_logic;
gpout_1_n: out std_logic
);
end top;
architecture rtl of top is
signal clk_ipb, rst_ipb, nuke, soft_rst, phy_rst_e, userled, clk125: std_logic;
signal mac_addr: std_logic_vector(47 downto 0);
signal ip_addr: std_logic_vector(31 downto 0);
signal ipb_out: ipb_wbus;
signal ipb_in: ipb_rbus;
signal inf_leds: std_logic_vector(1 downto 0);
begin
-- Infrastructure
infra: entity work.enclustra_ax3_pm3_infra
port map(
sysclk => sysclk,
clk_ipb_o => clk_ipb,
rst_ipb_o => rst_ipb,
clk125_o => clk125,
rst125_o => phy_rst_e,
nuke => nuke,
soft_rst => soft_rst,
leds => inf_leds,
rgmii_txd => rgmii_txd,
rgmii_tx_ctl => rgmii_tx_ctl,
rgmii_txc => rgmii_txc,
rgmii_rxd => rgmii_rxd,
rgmii_rx_ctl => rgmii_rx_ctl,
rgmii_rxc => rgmii_rxc,
mac_addr => mac_addr,
ip_addr => ip_addr,
ipb_in => ipb_in,
ipb_out => ipb_out
);
leds <= not ('0' & userled & inf_leds);
phy_rstn <= not phy_rst_e;
mac_addr <= X"020ddba1151" & not cfg; -- Careful here, arbitrary addresses do not always work
ip_addr <= X"c0a8c81" & not cfg; -- 192.168.200.16+n
-- ipbus slaves live in the entity below, and can expose top-level ports
-- The ipbus fabric is instantiated within.
slaves: entity work.payload
port map(
ipb_clk => clk_ipb,
ipb_rst => rst_ipb,
ipb_in => ipb_out,
ipb_out => ipb_in,
nuke => nuke,
soft_rst => soft_rst,
userled => userled,
clk125 => clk125,
fmc_clk_p => fmc_clk_p,
fmc_clk_n => fmc_clk_n,
rec_clk_p => rec_clk_p,
rec_clk_n => rec_clk_n,
rec_d_p => rec_d_p,
rec_d_n => rec_d_n,
clk_out_p => clk_out_p,
clk_out_n => clk_out_n,
rj45_din_p => rj45_din_p,
rj45_din_n => rj45_din_n,
rj45_dout_p => rj45_dout_p,
rj45_dout_n => rj45_dout_n,
sfp_dout_p => sfp_dout_p,
sfp_dout_n => sfp_dout_n,
cdr_lol => cdr_lol,
cdr_los => cdr_los,
sfp_los => sfp_los,
sfp_tx_dis => sfp_tx_dis,
sfp_flt => sfp_flt,
uid_scl => uid_scl,
uid_sda => uid_sda,
sfp_scl => sfp_scl,
sfp_sda => sfp_sda,
pll_scl => pll_scl,
pll_sda => pll_sda,
pll_rstn => pll_rstn,
gpin_0_p => gpin_0_p,
gpin_0_n => gpin_0_n,
gpout_0_p => gpout_0_p,
gpout_0_n => gpout_0_n,
gpout_1_p => gpout_1_p,
gpout_1_n => gpout_1_n
);
end rtl;
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