Commit 79af94ca authored by Dan Saunders's avatar Dan Saunders

Merge branch 'master' of bitbucket.org:solidexperiment/solid_firmware

parents 2ac18b53 c9801c0c
......@@ -6,6 +6,7 @@
<node id="invert" mask="0x4"/>
<node id="swap" mask="0x8"/>
<node id="mode" mask="0x10"/>
<node id="suppress" mask="0x20"/>
<node id="src" mask="0xc0"/>
</node>
<node id="stat" address="0x1">
......@@ -13,7 +14,7 @@
<node id="buf_full" mask="0x2"/>
<node id="dr_full" mask="0x4"/>
<node id="dr_warn" mask="0x8"/>
<node id="err" mask="0x10"/>
<node id="state" mask="0x70"/>
<node id="slip" mask="0xff00"/>
<node id="tap" mask="0x1f0000"/>
</node>
......
......@@ -13,6 +13,7 @@
<node id="chan_cap" mask="0x4000"/>
<node id="chan_inc" mask="0x8000"/>
<node id="zs_blks" mask="0xff0000"/>
<node id="nzs_blks" mask="0xf000000"/>
</node>
<node id="stat" address="0x8">
<node id="wait_sync" mask="0x1"/>
......
......@@ -4,6 +4,7 @@
<node id="dtmon_en" mask="0x1"/>
<node id="trig_in_en" mask="0x2"/>
<node id="trig_out_force" mask="0x4"/>
<node id="coinc_mode" mask="0x8"/>
</node>
<node id="evt_ctr" address="0x2"/>
<node id="stat" address="0x3">
......
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
src sc_trig.vhd sc_local_trig.vhd sc_zs_sel_rolling.vhd sc_trig_ro_block.vhd sc_deadtime_mon.vhd
src sc_trig_gen.vhd sc_trig_gen_or.vhd sc_trig_gen_or_coinc.vhd sc_trig_stretch.vhd
include sc_seq.dep
src ipbus_decode_sc_trig.vhd
addrtab -t sc_trig.xml
......
......@@ -36,13 +36,14 @@ entity sc_chan is
sync_ctrl: in std_logic_vector(3 downto 0);
zs_sel: in std_logic_vector(1 downto 0);
sctr: in std_logic_vector(47 downto 0);
fake: in std_logic_vector(13 downto 0);
fake: in std_logic_vector(13 downto 0);
nzs_blks: in std_logic_vector(3 downto 0);
nzs_en: in std_logic;
zs_en: in std_logic;
dr_en: in std_logic;
keep: in std_logic;
flush: in std_logic;
kack: out std_logic;
err: out std_logic;
veto: out std_logic;
trig: out std_logic_vector(N_CHAN_TRG - 1 downto 0);
clk_dr: in std_logic;
q: out std_logic_vector(31 downto 0);
......@@ -60,11 +61,10 @@ architecture rtl of sc_chan is
signal ctrl: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(0 downto 0);
signal d_in, d_in_i, d_buf: std_logic_vector(15 downto 0);
signal d_c: std_logic_vector(1 downto 0);
signal slip_l, slip_h, chan_rst, cap, inc: std_logic;
signal slip_l, slip_h, cap, inc: std_logic;
signal act_slip: unsigned(7 downto 0);
signal cntout: std_logic_vector(4 downto 0);
signal ctrl_en_sync, ctrl_en_buf, ctrl_invert, ctrl_swap: std_logic;
signal ctrl_en_sync, ctrl_en_buf, ctrl_invert, ctrl_swap, ctrl_suppress: std_logic;
signal ctrl_mode: std_logic;
signal ctrl_src: std_logic_vector(1 downto 0);
signal cap_full, buf_full, dr_full, dr_warn: std_logic;
......@@ -73,8 +73,14 @@ architecture rtl of sc_chan is
signal zs_thresh: std_logic_vector(13 downto 0);
signal sctr_p: std_logic_vector(11 downto 0);
signal dr_d: std_logic_vector(31 downto 0);
signal ro_en, keep_i, flush_i, err_i, req, blkend, dr_blkend, dr_wen: std_logic;
signal ctrl_tt: std_logic;
signal blkend, dr_blkend, dr_wen: std_logic;
type state_t is (ST_DIS, ST_WAIT, ST_RUN, ST_VETO, ST_ERR);
signal state: state_t;
signal nzs_en_d, dr_empty, enb, enb_d, zs_en_i, dr_en_i: std_logic;
signal state_dec: std_logic_vector(2 downto 0);
attribute ASYNC_REG: string;
attribute ASYNC_REG of enb, enb_d: signal is "yes";
begin
......@@ -114,6 +120,7 @@ begin
ctrl_invert <= ctrl(0)(2);
ctrl_swap <= ctrl(0)(3);
ctrl_mode <= ctrl(0)(4);
ctrl_suppress <= ctrl(0)(5);
ctrl_src <= ctrl(0)(7 downto 6);
slip_l <= sync_ctrl(0) and ctrl_en_sync; -- CDC
......@@ -121,7 +128,7 @@ begin
cap <= sync_ctrl(2) and ctrl_en_sync; -- CDC
inc <= sync_ctrl(3) and ctrl_en_sync; -- CDC
stat(0) <= X"00" & "000" & cntout & std_logic_vector(act_slip) & "000" & err_i & dr_warn & dr_full & buf_full & cap_full; -- CDC
stat(0) <= X"00" & "000" & cntout & std_logic_vector(act_slip) & '0' & state_dec & dr_warn & dr_full & buf_full & cap_full; -- CDC
-- Keep track of slips and taps for debug
......@@ -167,14 +174,67 @@ begin
"0000" & sctr_p when "10",
"00" & fake when others;
-- Channel status
-- State machine
nzs_en_d <= nzs_en when rising_edge(clk40);
enb <= ctrl_en_buf when rising_edge(clk40); -- CDC, synchroniser for ctrl_en_buf
enb_d <= enb when rising_edge(clk40);
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' or enb_d = '0' then
state <= ST_DIS;
else
case state is
when ST_DIS => -- Starting state
if ctrl_mode = '0' then
state <= ST_WAIT;
end if;
when ST_WAIT => -- Wait for sync
if nzs_en = '1' and nzs_en_d = '0' then
state <= ST_RUN;
end if;
when ST_RUN => -- Normal running
if buf_full = '1' or dr_full = '1' then
state <= ST_ERR;
elsif dr_warn = '1' then
state <= ST_VETO;
end if;
when ST_VETO => -- Normal running
if buf_full = '1' or dr_full = '1' then
state <= ST_ERR;
elsif dr_empty = '1' then
state <= ST_RUN;
end if;
when ST_ERR => -- Stuck now, sucker
end case;
end if;
end if;
end process;
err <= '1' when state = ST_ERR else '0';
with state select state_dec <=
"000" when ST_DIS,
"001" when ST_WAIT,
"010" when ST_RUN,
"011" when ST_VETO,
"100" when others;
err_i <= buf_full or dr_full;
err <= err_i;
ro_en <= not (ctrl_mode or err_i) and ctrl_en_buf;
keep_i <= keep and ro_en;
flush_i <= flush and ro_en;
veto <= dr_warn or not ro_en;
zs_en_i <= '0' when state = ST_DIS else zs_en;
dr_en_i <= dr_en when state = ST_RUN else '0';
-- Veto counters
-- TBD
-- ZS thresholds
......@@ -195,7 +255,7 @@ begin
process(clk40)
begin
if rising_edge(clk40) and blkend = '1' then
if rising_edge(clk40) then
if zs_sel_i < N_ZS_THRESH then
zs_thresh <= zs_thresh_v(zs_sel_i)(13 downto 0);
else
......@@ -215,6 +275,7 @@ begin
ipb_in => ipbw(N_SLV_BUF),
ipb_out => ipbr(N_SLV_BUF),
mode => ctrl_mode,
nzs_blks => nzs_blks,
clk40 => clk40,
clk160 => clk160,
buf_rst => rst40,
......@@ -224,10 +285,12 @@ begin
cap => cap,
cap_full => cap_full,
zs_thresh => zs_thresh,
zs_en => zs_en,
zs_en => zs_en_i,
buf_full => buf_full,
keep => keep_i,
flush => flush_i,
dr_en => dr_en_i,
suppress => ctrl_suppress,
keep => keep,
kack => kack,
q => dr_d,
q_blkend => dr_blkend,
wen => dr_wen
......@@ -245,11 +308,13 @@ begin
clk_r => clk_dr,
q => q,
q_blkend => q_blkend,
empty => q_empty,
empty => dr_empty,
ren => ren,
warn => dr_warn,
full => dr_full
);
q_empty <= dr_empty;
-- Local triggers
......
......@@ -22,6 +22,7 @@ entity sc_chan_buf is
ipb_in: in ipb_wbus; -- clk dom
ipb_out: out ipb_rbus; -- clk dom
mode: in std_logic; -- buffer counter mode; clk dom
nzs_blks: in std_logic_vector(3 downto 0); -- number of blocks in NZS buffer
clk40: in std_logic;
clk160: in std_logic;
buf_rst: in std_logic; -- general reset; clk40 dom
......@@ -33,8 +34,10 @@ entity sc_chan_buf is
zs_thresh: in std_logic_vector(13 downto 0); -- ZS threshold; clk40 dom
zs_en: in std_logic; -- enable zs buffer; clk40 dom
buf_full: out std_logic; -- buffer err flag; clk40 dom
dr_en: in std_logic;
suppress: in std_logic;
keep: in std_logic; -- block transfer cmd; clk40 dom
flush: in std_logic; -- block discard cmd; clk40 dom
kack: out std_logic;
q: out std_logic_vector(31 downto 0); -- output to derand; clk40 dom
q_blkend: out std_logic;
wen: out std_logic -- derand write enable
......@@ -44,15 +47,13 @@ end sc_chan_buf;
architecture rtl of sc_chan_buf is
constant NZS_LAST_ADDR: integer := NZS_BLKS * 2 ** BLK_RADIX - 1;
constant ZS_FIRST_ADDR: integer := NZS_BLKS * 2 ** BLK_RADIX;
constant ZS_LAST_ADDR: integer := 2 ** BUF_RADIX - 1;
signal c: unsigned(1 downto 0);
signal we: std_logic;
signal d_ram, q_ram, d_nzs, q_nzs, d_zs, q_zs, q_zs_b: std_logic_vector(15 downto 0);
signal a_ram: std_logic_vector(BUF_RADIX - 1 downto 0);
signal pnz, pzw, pzr: unsigned(BUF_RADIX - 1 downto 0);
signal pnz, pzw, pzr, zs_first_addr: unsigned(BUF_RADIX - 1 downto 0);
signal cap_run, cap_done: std_logic;
signal zctr: unsigned(BLK_RADIX - 1 downto 0);
signal z0, z1: std_logic;
......@@ -61,6 +62,8 @@ architecture rtl of sc_chan_buf is
begin
zs_first_addr <= shift_left(unsigned(std_logic_vector'((BUF_RADIX - 1 downto 4 => '0') & nzs_blks)), BLK_RADIX) + ZS_DEL;
-- NZS / ZS buffer
ram: entity work.ipbus_ported_dpram
......@@ -123,9 +126,9 @@ begin
begin
if falling_edge(clk40) then
if (mode = '1' and nzen = '0') or (mode = '0' and nzen_d = '0') then
pnz <= to_unsigned(0, pnz'length);
pnz <= (others => '0');
else
if (mode = '0' and pnz = NZS_LAST_ADDR) or pnz = ZS_LAST_ADDR then
if (mode = '0' and pnz = zs_first_addr - 1) or pnz = ZS_LAST_ADDR then
pnz <= (others => '0');
else
pnz <= pnz + 1;
......@@ -141,7 +144,7 @@ begin
-- Zero suppression
z0 <= '1' when unsigned(q_ram(13 downto 0)) < unsigned(zs_thresh) and q_ram(15) = '0' else '0';
z0 <= '1' when unsigned(q_ram(13 downto 0)) < unsigned(zs_thresh) else '0';
process(clk160)
begin
......@@ -149,17 +152,17 @@ begin
if zs_en_d = '0' then
zctr <= (others => '0');
else
q_nzs <= q_ram(15) & '0' & q_ram(13 downto 0);
q_nzs <= q_ram;
z1 <= z0;
if z0 = '0' then
if z0 = '0' or q_nzs(15) = '1' then
zctr <= (others => '0');
else
elsif z1 = '1' then
zctr <= zctr + 1;
end if;
end if;
wez <= (not (z0 and z1)) and zs_en_dd and not mode and not buf_full_i;
if z1 = '1' and zctr /= 1 then
d_zs <= "01" & (13 - BLK_RADIX downto 0 => '0') & std_logic_vector(zctr);
wez <= ((not (z0 and z1)) or q_nzs(15)) and zs_en_dd and not mode and not buf_full_i;
if z1 = '1' then
d_zs <= q_nzs(15) & '1' & (13 - BLK_RADIX downto 0 => '0') & std_logic_vector(zctr);
else
d_zs <= q_nzs;
end if;
......@@ -172,19 +175,19 @@ begin
begin
if rising_edge(clk40) then
if zs_en = '0' then
pzw <= to_unsigned(ZS_FIRST_ADDR, pzw'length);
pzr <= to_unsigned(ZS_FIRST_ADDR, pzr'length);
pzw <= zs_first_addr;
pzr <= zs_first_addr;
elsif buf_full_i = '0' then
if wez = '1' then
if pzw = ZS_LAST_ADDR then
pzw <= to_unsigned(ZS_FIRST_ADDR, pzw'length);
pzw <= zs_first_addr;
else
pzw <= pzw + 1;
end if;
end if;
if rez = '1' then
if pzr = ZS_LAST_ADDR then
pzr <= to_unsigned(ZS_FIRST_ADDR, pzr'length);
pzr <= zs_first_addr;
else
pzr <= pzr + 1;
end if;
......@@ -209,8 +212,9 @@ begin
-- Readout to derand
go <= keep or flush;
go <= blkend and dr_en;
kack <= go and keep and not (q_zs_b(15) and q_zs_b(14) and suppress);
process(clk40)
begin
if rising_edge(clk40) then
......
......@@ -33,12 +33,13 @@ entity sc_channels is
zs_sel: in std_logic_vector(1 downto 0);
sctr: in std_logic_vector(47 downto 0);
fake: in std_logic_vector(13 downto 0);
nzs_blks: in std_logic_vector(3 downto 0);
nzs_en: in std_logic;
zs_en: in std_logic;
keep: in std_logic_vector(N_CHAN - 1 downto 0);
flush: in std_logic_vector(N_CHAN - 1 downto 0);
dr_en: in std_logic;
keep: in std_logic;
kack: out std_logic_vector(N_CHAN - 1 downto 0);
err: out std_logic;
veto: out std_logic_vector(N_CHAN - 1 downto 0);
trig: out sc_trig_array;
dr_chan: in std_logic_vector(7 downto 0);
clk_dr: in std_logic;
......@@ -109,12 +110,13 @@ begin
zs_sel => zs_sel,
sctr => sctr,
fake => fake,
nzs_blks => nzs_blks,
nzs_en => nzs_en,
zs_en => zs_en,
keep => keep(i),
flush => flush(i),
dr_en => dr_en,
keep => keep,
kack => kack(i),
err => chan_err(i),
veto => veto(i),
trig => ltrig,
clk_dr => clk_dr,
q => chan_q(i),
......
......@@ -47,10 +47,12 @@ architecture rtl of sc_daq is
signal clk40_i, rst40_i, clk160, clk280: std_logic;
signal sync_ctrl: std_logic_vector(3 downto 0);
signal sctr: std_logic_vector(47 downto 0);
signal trig_en, nzs_en, zs_en: std_logic;
signal trig_keep, trig_flush, trig_veto: std_logic_vector(N_CHAN - 1 downto 0);
signal dr_en, nzs_en, zs_en: std_logic;
signal trig_keep, trig_flush: std_logic;
signal trig_kack: std_logic_vector(N_CHAN - 1 downto 0);
signal fake: std_logic_vector(13 downto 0);
signal force_trig, thresh_hit: std_logic;
signal nzs_blks: std_logic_vector(3 downto 0);
signal zs_sel: std_logic_vector(1 downto 0);
signal chan_trig: sc_trig_array;
signal link_d, link_q: std_logic_vector(15 downto 0);
......@@ -98,10 +100,11 @@ begin
led => led_out,
sctr => sctr,
chan_sync_ctrl => sync_ctrl,
trig_en => trig_en,
dr_en => dr_en,
nzs_en => nzs_en,
zs_en => zs_en,
rand => rand
rand => rand,
nzs_blks => nzs_blks
);
clk40 <= clk40_i;
......@@ -155,12 +158,13 @@ begin
zs_sel => zs_sel,
sctr => sctr,
fake => fake,
nzs_blks => nzs_blks,
nzs_en => nzs_en,
zs_en => zs_en,
dr_en => dr_en,
keep => trig_keep,
flush => trig_flush,
kack => trig_kack,
err => chan_err,
veto => trig_veto,
trig => chan_trig,
dr_chan => ro_chan,
clk_dr => ipb_clk,
......@@ -181,13 +185,11 @@ begin
clk40 => clk40_i,
rst40 => rst40_i,
clk160 => clk160,
trig_en => trig_en,
trig_en => dr_en,
zs_en => zs_en,
sctr => sctr,
rand => rand,
keep => trig_keep,
flush => trig_flush,
veto => trig_veto,
kack => trig_kack,
zs_sel => zs_sel,
trig => chan_trig,
force => force_trig,
......@@ -239,7 +241,6 @@ begin
board_id => board_id,
clk40 => clk40_i,
rst40 => rst40_i,
rand => rand,
d_trig => trig_d,
blkend_trig => trig_blkend,
we_trig => trig_we,
......
......@@ -111,7 +111,7 @@ begin
process(params_freq_div)
begin
for i in mask'range loop
if i > to_integer(unsigned(params_freq_div)) then
if i >= to_integer(unsigned(params_freq_div)) then
mask(i) <= '0';
else
mask(i) <= '1';
......
......@@ -19,11 +19,11 @@ entity sc_local_trig is
clk40: in std_logic;
rst40: in std_logic;
en: in std_logic;
coinc_mode: in std_logic;
mask: in std_logic_vector(N_TRG - 1 downto 0);
hops: in std_logic_vector(31 downto 0);
mark: in std_logic;
sctr: in std_logic_vector(47 downto 0);
rand: in std_logic_vector(31 downto 0);
chan_trig: in sc_trig_array;
trig_q: out std_logic_vector(15 downto 0);
trig_valid: out std_logic;
......@@ -55,7 +55,7 @@ begin
-- Threshold trigger generator
tg0: entity work.sc_trig_gen_or
tg0: entity work.sc_trig_gen_or_coinc
generic map(
TBIT => 0,
DELAY => 2
......@@ -63,6 +63,7 @@ begin
port map(
clk => clk40,
en => en,
mode => coinc_mode,
mark => mark,
chan_trig => chan_trig,
chan_act => cact(0),
......@@ -108,7 +109,7 @@ begin
tg3: entity work.sc_trig_gen
generic map(
DELAY => 2
DELAY => 0
)
port map(
clk => clk40,
......@@ -182,7 +183,7 @@ begin
with ro_ctr select ro_q <=
X"100" & "00" & last_gasp & hoorah & (15 downto N_TRG => '0') & tc when X"00", -- Type 1
std_logic_vector(sctr(31 downto BLK_RADIX)) & (BLK_RADIX - 1 downto 0 => '0') when X"01",
std_logic_vector(unsigned(sctr(31 downto BLK_RADIX)) - 1) & (BLK_RADIX - 1 downto 0 => '0') when X"01",
X"0000" & std_logic_vector(sctr(47 downto 32)) when X"02",
X"00000000" when X"03",
b when others;
......
......@@ -27,7 +27,6 @@ entity sc_roc is
board_id: in std_logic_vector(7 downto 0);
clk40: in std_logic;
rst40: in std_logic;
rand: in std_logic_vector(31 downto 0);
d_trig: in std_logic_vector(31 downto 0);
blkend_trig: in std_logic;
we_trig: in std_logic;
......
......@@ -35,7 +35,6 @@ architecture rtl of sc_rtrig is
signal ctrl_en, ctrl_mode: std_logic;
signal ctrl_div: std_logic_vector(5 downto 0);
signal mask: std_logic_vector(23 downto 0);
signal t: std_logic;
begin
......@@ -56,12 +55,11 @@ begin
ctrl_div <= q(0)(13 downto 8);
mgen: for i in mask'range generate
mask(i) <= '0' when i > to_integer(unsigned(ctrl_div)) else '1';
mask(i) <= '0' when i >= to_integer(unsigned(ctrl_div)) else '1';
end generate;
t <= ((not ctrl_mode and not or_reduce(rand(mask'range) and mask)) or
(ctrl_mode and not or_reduce(sctr(BLK_RADIX + mask'left downto BLK_RADIX) and mask))) and ctrl_en;
force <= t;
force <= ((not ctrl_mode and not or_reduce(rand(mask'range) and mask)) or
(ctrl_mode and not or_reduce(sctr(BLK_RADIX + mask'left downto BLK_RADIX) and mask))) and
ctrl_en and not or_reduce(sctr(BLK_RADIX - 1 downto 0));
end rtl;
......@@ -35,8 +35,7 @@ entity sc_seq is
d_ext: in std_logic_vector(15 downto 0);
valid_ext: in std_logic;
ack_ext: out std_logic;
keep: out std_logic_vector(N_CHAN - 1 downto 0);
flush: out std_logic_vector(N_CHAN - 1 downto 0);
keep: out std_logic;
err: out std_logic
);
......@@ -47,7 +46,7 @@ architecture rtl of sc_seq is
signal ipbw: ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipbr: ipb_rbus_array(N_SLAVES - 1 downto 0);
signal td: std_logic_vector(15 downto 0);
signal tv, terr: std_logic;
signal tv, terr, tv_d: std_logic;
signal we: std_logic;
signal d_ram, q_ram: std_logic_vector(15 downto 0);
signal a_ram: std_logic_vector(BUF_RADIX - 1 downto 0);
......@@ -80,8 +79,9 @@ begin
td <= d_loc when valid_loc = '1' else d_ext;
tv <= (valid_loc or valid_ext) and not rseq and zs_en;
ack_loc <= valid_loc;
ack_ext <= valid_ext and not valid_loc;
tv_d <= tv and not tv_d when rising_edge(clk40);
ack_loc <= valid_loc and tv_d;
ack_ext <= valid_ext and not valid_loc and tv_d;
process(clk40)
begin
......@@ -166,7 +166,7 @@ begin
addr => a_ram
);
we <= '1' when (tv = '1' and unsigned(d_ram) > unsigned(q_ram)) or (rseq = '1' and sctr(1 downto 0) = "11") else '0';
we <= '1' when (tv_d = '1' and unsigned(d_ram) > unsigned(q_ram)) or (rseq = '1' and sctr(1 downto 0) = "11") else '0';
a_ram <= std_logic_vector(ptr + unsigned(q_s_ram(BUF_RADIX - 1 downto 0))) when rseq = '0' else std_logic_vector(ptr);
d_ram <= q_s_ram(31 downto 16) when rseq = '0' else (others => '0');
......@@ -195,7 +195,6 @@ begin
end if;
end process;
keep <= (keep'range => keep_i);
flush <= not (flush'range => keep_i);
keep <= keep_i;
end rtl;
......@@ -33,10 +33,11 @@ entity sc_timing is
led: out std_logic; -- LED flash out
sctr: out std_logic_vector(47 downto 0); -- sample counter
chan_sync_ctrl: out std_logic_vector(3 downto 0); -- Timing signals to channels
trig_en: out std_logic;
dr_en: out std_logic;
nzs_en: out std_logic;
zs_en: out std_logic;
rand: out std_logic_vector(31 downto 0)
rand: out std_logic_vector(31 downto 0);
nzs_blks: out std_logic_vector(3 downto 0)
);
end sc_timing;
......@@ -51,6 +52,7 @@ architecture rtl of sc_timing is
signal ctrl_rst_ctr, ctrl_cap_ctr, ctrl_en_sync, ctrl_force_sync, ctrl_pipeline_en, ctrl_send_sync: std_logic;
signal ctrl_chan_slip_l, ctrl_chan_slip_h, ctrl_chan_rst_buf, ctrl_chan_cap, ctrl_chan_inc: std_logic;
signal ctrl_zs_blks: std_logic_vector(7 downto 0);
signal ctrl_nzs_blks: std_logic_vector(3 downto 0);
signal sync, wait_sync, sync_err, io_err: std_logic;
signal sync_in_r, trig_in_r, trig_in_r_d: std_logic;
signal sync_ctr, trig_ctr: unsigned(31 downto 0);
......@@ -111,6 +113,7 @@ begin
ctrl_chan_cap <= ctrl(0)(14);
ctrl_chan_inc <= ctrl(0)(15);
ctrl_zs_blks <= ctrl(0)(23 downto 16);
ctrl_nzs_blks <= ctrl(0)(27 downto 24);
stat(0) <= X"0000000" & "00" & sync_err & wait_sync;
stat(1) <= std_logic_vector(sctr_s(31 downto 0));
stat(2) <= X"0000" & std_logic_vector(sctr_s(47 downto 32));
......@@ -195,12 +198,15 @@ begin
rst40 => rst40_i,
en => ctrl_pipeline_en,
zs_blks => ctrl_zs_blks,
nzs_blks => ctrl_nzs_blks,
sync => sync,
sctr => sctr_i,
nzs_en => nzs_en,
zs_en => zs_en,
trig_en => trig_en
dr_en => dr_en
);
nzs_blks <= ctrl_nzs_blks;
-- Channel sync control
......
......@@ -17,11 +17,12 @@ entity sc_timing_startup is
rst40: in std_logic;
en: in std_logic;
zs_blks: in std_logic_vector(7 downto 0);
nzs_blks: in std_logic_vector(3 downto 0);
sync: in std_logic;
sctr: in unsigned(47 downto 0);
nzs_en: out std_logic;
zs_en: out std_logic;
trig_en: out std_logic
dr_en: out std_logic
);
end sc_timing_startup;
......@@ -39,20 +40,18 @@ begin
up <= '0';
nzs_en <= '0';
zs_en <= '0';
trig_en <= '0';
dr_en <= '0';
else
if sync = '1' then
up <= '1';
end if;
if up = '1' then
if and_reduce(std_logic_vector(sctr(BLK_RADIX - 1 downto 0))) = '1' then
if unsigned(sctr(3 + BLK_RADIX downto BLK_RADIX)) = 0 then
nzs_en <= '1';
elsif unsigned(sctr(3 + BLK_RADIX downto BLK_RADIX)) = NZS_BLKS then
zs_en <= '1';
elsif unsigned(sctr(7 + BLK_RADIX downto BLK_RADIX)) = NZS_BLKS - 1 + unsigned(zs_blks) then
trig_en <= '1';
end if;
nzs_en <= '1';
elsif unsigned(sctr(3 + BLK_RADIX downto BLK_RADIX)) = unsigned(nzs_blks) + 1 and sctr(BLK_RADIX - 1 downto 0) = to_unsigned(ZS_DEL - 1, BLK_RADIX) then
zs_en <= '1';
elsif unsigned(sctr(7 + BLK_RADIX downto BLK_RADIX)) = unsigned(nzs_blks) + 1 + unsigned(zs_blks) then
dr_en <= '1';
end if;
end if;
end if;
......
......@@ -27,10 +27,8 @@ entity sc_trig is
trig_en: in std_logic;
zs_en: in std_logic;
sctr: in std_logic_vector(47 downto 0);
rand: in std_logic_vector(31 downto 0);
keep: out std_logic_vector(N_CHAN - 1 downto 0);
flush: out std_logic_vector(N_CHAN - 1 downto 0);
veto: in std_logic_vector(N_CHAN - 1 downto 0);
keep: out std_logic;
kack: in std_logic_vector(N_CHAN - 1 downto 0);
zs_sel: out std_logic_vector(1 downto 0);
trig: in sc_trig_array;
force: in std_logic;
......@@ -56,7 +54,7 @@ architecture rtl of sc_trig is
signal ctrl, ctrl_mask: ipb_reg_v(0 downto 0);
signal stat: ipb_reg_v(1 downto 0);
signal stb: std_logic_vector(0 downto 0);
signal ctrl_dtmon_en, ctrl_trig_in_en, ctrl_trig_out_force: std_logic;
signal ctrl_dtmon_en, ctrl_trig_in_en, ctrl_trig_out_force, ctrl_coinc_mode: 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 hop_cfg: std_logic_vector(31 downto 0);
......@@ -64,7 +62,7 @@ architecture rtl of sc_trig is
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 keep_i, flush_i: std_logic;
signal b_q, t_q: std_logic_vector(31 downto 0);
signal b_go, t_go, b_valid, t_valid, b_blkend, t_blkend, blkend: std_logic;
signal tctr: std_logic_vector(27 downto 0);
......@@ -109,6 +107,7 @@ begin
ctrl_dtmon_en <= ctrl(0)(0);
ctrl_trig_in_en <= ctrl(0)(1);
ctrl_trig_out_force <= ctrl(0)(2) and stb(0);
ctrl_coinc_mode <= ctrl(0)(3);
stat(0) <= X"0" & tctr;
stat(1) <= X"0000000" & "00" & rveto & err;
......@@ -183,11 +182,11 @@ begin
clk40 => clk40,
rst40 => rst40,
en => trig_en,
coinc_mode => ctrl_coinc_mode,
mask => trig_mask,
hops => hop_cfg,
mark => mark,
sctr => sctr,
rand => rand,
chan_trig => ctrig,
trig_q => lq,
trig_valid => lvalid,
......@@ -219,7 +218,7 @@ begin
q(0) => zs_cfg
);
zssel: entity work.sc_zs_sel
zssel: entity work.sc_zs_sel_rolling
port map(
clk40 => clk40,
rst40 => rst40,
......@@ -249,26 +248,10 @@ begin
valid_ext => d_valid,
ack_ext => d_ack,
keep => keep_i,
flush => flush_i,
err => err
);
-- Channel interface
veto_p <= veto or (veto'range => rveto);
keep <= keep_i and not veto_p when mark = '1' else (others => '0');
flush <= not keep_i or veto_p when mark = '1' else (others => '0');
process(clk40)
begin
if rising_edge(clk40) then
if trig_en = '0' then
veto_i <= (others => '0');
elsif mark = '1' then
veto_i <= veto_p;
end if;
end if;
end process;
keep <= keep_i;
-- Readout header to ROC
......@@ -280,7 +263,7 @@ begin
sctr => sctr,
mark => mark,
keep => keep_i,
veto => veto_i,
kack => kack,
tctr => tctr,
ro_q => b_q,
ro_valid => b_valid,
......@@ -313,21 +296,23 @@ begin
-- Deadtime monitor
dmon: entity work.sc_deadtime_mon
port map(
clk => clk,
rst => rst,
ipb_in => ipbw(N_SLV_DTMON),
ipb_out => ipbr(N_SLV_DTMON),
en => ctrl_dtmon_en,
clk40 => clk40,
rst40 => rst40,
clk160 => clk160,
mark => mark,
sctr => sctr(BLK_RADIX - 1 downto 0),
keep => keep_i,
veto => veto_i
);
-- dmon: entity work.sc_deadtime_mon
-- port map(
-- clk => clk,
-- rst => rst,
-- ipb_in => ipbw(N_SLV_DTMON),
-- ipb_out => ipbr(N_SLV_DTMON),
-- en => ctrl_dtmon_en,
-- clk40 => clk40,
-- rst40 => rst40,
-- clk160 => clk160,
-- mark => mark,
-- sctr => sctr(BLK_RADIX - 1 downto 0),
-- keep => keep_i,
-- veto => veto_i
-- );
ipbr(N_SLV_DTMON) <= IPB_RBUS_NULL;
-- Ext trigger
......
......@@ -13,7 +13,7 @@ use work.top_decl.all;
entity sc_trig_gen is
generic(
DELAY: positive := 1
DELAY: natural := 0
);
port(
clk: in std_logic;
......
......@@ -15,7 +15,7 @@ use work.top_decl.all;
entity sc_trig_gen_or is
generic(
TBIT: natural := 0;
DELAY: positive := 1
DELAY: natural := 0
);
port(
clk: in std_logic;
......
-- sc_trig_gen_or_coinc
--
-- Local trigger module for simple 'ored' threshold triggers
-- This trigger will fire if any channel has a high bit in a given block
-- Can be set up to require a coincidence between X and Y channels
--
-- Dave Newbold, March 2018
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_trig_gen_or_coinc is
generic(
TBIT: natural := 0;
DELAY: positive := 1
);
port(
clk: in std_logic;
en: in std_logic;
mode: in std_logic;
mark: in std_logic;
chan_trig: in sc_trig_array;
hit: out std_logic;
chan_act: out std_logic_vector(N_CHAN - 1 downto 0);
valid: out std_logic;
ack: in std_logic
);
end sc_trig_gen_or_coinc;
architecture rtl of sc_trig_gen_or_coinc is
signal y_or, x_or, y_or_s, x_or_s: std_logic;
signal t, m, tc, v: std_logic;
signal mark_del: std_logic_vector(DELAY downto 0);
signal c: std_logic_vector(N_CHAN - 1 downto 0);
begin
-- Define the trigger condition
process(chan_trig)
variable y, x: std_logic;
begin
y := '0';
x := '0';
for i in N_CHAN / 4 - 1 downto 0 loop
y := y or chan_trig(TBIT)(SC_CH_Y0(i)) or chan_trig(TBIT)(SC_CH_Y1(i));
x := x or chan_trig(TBIT)(SC_CH_X0(i)) or chan_trig(TBIT)(SC_CH_X1(i));
end loop;
y_or <= y;
x_or <= x;
end process;
stretch: entity work.sc_trig_stretch
generic map(
WIDTH => 2
)
port map(
clk => clk,
del => "0011", -- Fixed four-sample window for now
d(0) => y_or,
d(1) => x_or,
q(0) => y_or_s,
q(1) => x_or_s
);
t <= (y_or_s and x_or_s) when mode = '1' else or_reduce(chan_trig(TBIT));
-- Define the block boundary
mark_del <= mark_del(DELAY - 1 downto 0) & mark when rising_edge(clk);
m <= mark_del(DELAY);
-- Catch a trigger feature with the block
process(clk)
begin
if rising_edge(clk) then
if en = '0' then
tc <= '0';
c <= (others => '0');
elsif t = '1' then
tc <= '1';
if m = '0' then
c <= c or chan_trig(TBIT);
else
c <= chan_trig(TBIT);
end if;
elsif m = '1' then
tc <= '0';
c <= (others => '0');
end if;
end if;
end process;
-- Trigger request output
hit <= t;
v <= (v or (tc and m)) and not (mark or ack or not en) when rising_edge(clk);
valid <= v;
chan_act <= c when m = '1' and rising_edge(clk);
end rtl;
......@@ -19,8 +19,8 @@ entity sc_trig_ro_block is
trig_en: in std_logic;
sctr: in std_logic_vector(47 downto 0);
mark: in std_logic;
keep: in std_logic_vector(N_CHAN - 1 downto 0);
veto: in std_logic_vector(N_CHAN - 1 downto 0);
keep: in std_logic;
kack: in std_logic_vector(N_CHAN - 1 downto 0);
tctr: out std_logic_vector(27 downto 0);
ro_q: out std_logic_vector(31 downto 0);
ro_valid: out std_logic;
......@@ -37,6 +37,7 @@ architecture rtl of sc_trig_ro_block is
signal tctr_i: unsigned(27 downto 0);
signal go, blkend: std_logic;
signal chen, keep_c: std_logic_vector(63 downto 0);
signal bctr: unsigned(31 - BLK_RADIX downto 0);
begin
......@@ -46,8 +47,8 @@ begin
begin
if rising_edge(clk40) then
if trig_en = '0' then
tctr_i <= (others => '0');
elsif mark = '1' and or_reduce(keep) = '1' then
tctr_i <= (others => '1');
elsif mark = '1' and keep = '1' then
tctr_i <= tctr_i + 1;
end if;
end if;
......@@ -57,21 +58,31 @@ begin
-- Block data to ROC
chen <= (63 downto N_CHAN => '0') & (keep and not veto); -- Assumption on 64 channels max here...
keep_c <= (63 downto N_CHAN => '0') & keep;
keep_c <= (63 downto N_CHAN => '0') & kack when mark = '1' and rising_edge(clk40);
go <= (go or (ro_go and or_reduce(keep) and not rveto)) and not blkend and trig_en when rising_edge(clk40);
blkend <= '1' when ro_ctr = X"06" else '0';
go <= (go or (ro_go and keep and not rveto)) and not blkend and trig_en when rising_edge(clk40);
blkend <= '1' when ro_ctr = X"04" else '0';
ro_valid <= go;
ro_blkend <= blkend;
-- Block counter
process(clk40)
begin
if rising_edge(clk40) then
if trig_en = '0' then
bctr <= (others => '0');
elsif mark = '1' then
bctr <= bctr + 1;
end if;
end if;
end process;
with ro_ctr select ro_q <=
X"0" & std_logic_vector(tctr_i) when X"00", -- Type 0
std_logic_vector(unsigned(sctr(31 downto 1) & '0')) when X"01", -- Hack so that counter is taken at start-of-block
std_logic_vector(bctr) & (BLK_RADIX - 1 downto 0 => '0') when X"01",
X"0000" & std_logic_vector(sctr(47 downto 32)) when X"02",
chen(31 downto 0) when X"03", -- Corresponds to CH_WORD = 3 in sc_roc
chen(63 downto 32) when X"04",
keep_c(31 downto 0) when X"05",
keep_c(31 downto 0) when X"03",
keep_c(63 downto 32) when others;
end rtl;
-- sc_trig_stretch
--
-- Pulse stretcher for trigger coincidence
--
-- Dave Newbold, March 2018
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity sc_trig_stretch is
generic(
WIDTH: positive := 1
);
port(
clk: in std_logic;
del: in std_logic_vector(3 downto 0);
d: in std_logic_vector(WIDTH - 1 downto 0);
q: out std_logic_vector(WIDTH - 1 downto 0)
);
end sc_trig_stretch;
architecture rtl of sc_trig_stretch is
type r_t is array(2 ** del'length - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0);
signal r: r_t;
begin
r(0) <= d;
r(r'left downto 1) <= r(r'left - 1 downto 0) when rising_edge(clk);
q <= r(to_integer(unsigned(del)));
end rtl;
-- sc_zs_sel
--
-- Random and external trigger generator
-- Zero suppression threshold select logic - triggered block only
--
-- Dave Newbold, August 2016
......
-- sc_zs_sel
--
-- Zero suppression threshold select logic - range of blocks
--
-- zscfg is eight bits for each trigger type
-- b7-4: blocks for change threshold for (from start of nzs buffer)
-- b1-0: ZS threshold ID for this trigger
--
-- Dave Newbold, August 2016
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
use work.top_decl.all;
entity sc_zs_sel_rolling is
port(
clk40: in std_logic;
rst40: in std_logic;
mark: in std_logic;
zscfg: in std_logic_vector(31 downto 0);
trig: in std_logic_vector(15 downto 0);
trig_valid: in std_logic;
sel: out std_logic_vector(1 downto 0)
);
end sc_zs_sel_rolling;
architecture rtl of sc_zs_sel_rolling is
signal ti: integer range 15 downto 0 := 0;
signal zs_cnt: std_logic_vector(3 downto 0);
type cnt_t is array(N_TRG - 1 downto 0) of unsigned(3 downto 0);
signal cnt: cnt_t;
signal ts: std_logic_vector(1 downto 0);
signal scnt: unsigned(3 downto 0);
begin
ti <= to_integer(unsigned(trig(3 downto 0)));
zs_cnt <= zscfg(ti * 8 + 7 downto ti * 8 + 4);
-- Rolling block counters
process(clk40)
begin
if rising_edge(clk40) then
if rst40 = '1' then
cnt <= (others => (others => '0'));
else
for i in N_TRG - 1 downto 0 loop
if i = ti and trig_valid = '1' then
cnt(i) <= unsigned(zs_cnt);
elsif mark = '1' and cnt(i) /= 0 then
cnt(i) <= cnt(i) - 1;
end if;
end loop;
end if;
end if;
end process;
-- Select highest-numbered ZS threshold of active triggers
process(cnt)
variable t, k: unsigned(1 downto 0);
begin
t := "00";
for i in N_TRG - 1 downto 0 loop
k := unsigned(zscfg(i * 8 + 1 downto i * 8));
if cnt(i) /= 0 and k > t then
t := k;
end if;
end loop;
ts <= std_logic_vector(t);
end process;
-- Pipelining; send new ZS threshold choice at correct time
process(clk40)
begin
if rising_edge(clk40) then
if mark = '1' then
scnt <= (others => '0');
elsif and_reduce(std_logic_vector(scnt)) = '0' then
scnt <= scnt + 1;
end if;
if scnt = to_unsigned(ZS_DEL - 1, scnt'length) then
sel <= ts;
end if;
end if;
end process;
end rtl;
......@@ -10,9 +10,8 @@ use IEEE.STD_LOGIC_1164.ALL;
entity sc_trig_mgt_wrapper is
port(
sysclk: in std_logic; -- DRP clock
en: in std_logic;
tx_rst: in std_logic;
rx_rst: in std_logic;
tx_en: in std_logic;
rx_en: in std_logic;
tx_good: out std_logic;
rx_good: out std_logic;
tx_stat: out std_logic_vector(1 downto 0);
......@@ -33,8 +32,8 @@ architecture rtl of sc_trig_mgt_wrapper is
begin
tx_good <= en;
rx_good <= en;
tx_good <= tx_en;
rx_good <= rx_en;
tx_stat <= "00";
rx_stat <= "000";
rxd <= txd when rising_edge(clk125);
......
......@@ -11,18 +11,25 @@ package top_decl is
constant MAC_ADDR: std_logic_vector(47 downto 0) := X"020ddba11500"; -- last byte from local addr
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb00"; -- last byte from local addr
constant FW_REV: std_logic_vector(15 downto 0) := X"0012";
constant FW_REV: std_logic_vector(15 downto 0) := X"0017";
constant N_CHAN: integer := 64;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant BUF_RADIX: integer := 12; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant ZS_DEL: integer := 8;
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ch_array_t is array(N_CHAN / 4 - 1 downto 0) of integer;
constant SC_CH_Y0: sc_ch_array_t := (24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7);
constant SC_CH_Y1: sc_ch_array_t := (39, 38, 37, 36, 35, 34, 33, 32, 63, 62, 61, 60, 59, 58, 57, 56);
constant SC_CH_X0: sc_ch_array_t := (23, 22, 21, 20, 19, 18, 17, 16, 47, 46, 45, 44, 43, 42, 41, 40);
constant SC_CH_X1: sc_ch_array_t := (8, 9, 10, 11, 12, 13, 14, 15, 48, 49, 50, 51, 52, 53, 54, 55);
end top_decl;
......@@ -11,7 +11,7 @@ package top_decl is
constant MAC_ADDR: std_logic_vector(47 downto 0) := X"020ddba11503";
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb00";
constant FW_REV: std_logic_vector(15 downto 0) := X"0012";
constant FW_REV: std_logic_vector(15 downto 0) := X"0017";
constant N_CHAN: integer := 8;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
......@@ -19,10 +19,17 @@ package top_decl is
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant ZS_DEL: integer := 8;
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ch_array_t is array(N_CHAN / 4 - 1 downto 0) of integer;
constant SC_CH_Y0: sc_ch_array_t := (0, 1);
constant SC_CH_Y1: sc_ch_array_t := (2, 3);
constant SC_CH_X0: sc_ch_array_t := (4, 5);
constant SC_CH_X1: sc_ch_array_t := (6, 7);
end top_decl;
......@@ -13,16 +13,23 @@ package top_decl is
constant IP_ADDR: std_logic_vector(31 downto 0) := X"c0a8eb10";
constant FW_REV: std_logic_vector(15 downto 0) := X"010d";
constant N_CHAN: integer := 2;
constant N_CHAN: integer := 4;
constant BLK_RADIX: integer := 8; -- 256 sample blocks
constant BUF_RADIX: integer := 11; -- One BRAM for NZS / ZS buffer
constant NZS_BLKS: integer := 2; -- Reserve two blocks of space for NZS buffer
constant N_TRG: integer := 4; -- Number of trigger types
constant N_ZS_THRESH: integer := 4; -- Number of ZS thresholds
constant ZS_DEL: integer := 8;
constant N_CHAN_TRG: integer := 3; -- Number of channel trigger bits
constant FIFO_RADIX: integer := 3; -- 8 FIFO blocks in readout buffer
type sc_trig_array is array(N_CHAN_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ltrig_array is array(N_TRG - 1 downto 0) of std_logic_vector(N_CHAN - 1 downto 0);
type sc_ch_array_t is array(N_CHAN / 4 - 1 downto 0) of integer;
constant SC_CH_Y0: sc_ch_array_t := (0 => 0);
constant SC_CH_Y1: sc_ch_array_t := (0 => 1);
constant SC_CH_X0: sc_ch_array_t := (0 => 2);
constant SC_CH_X1: sc_ch_array_t := (0 => 3);
end top_decl;
Startup procedure step 1 (from cold start, i.e power-on)
Timing board (master first, then slaves)
- Reset registers (csr.ctrl.soft_rst)
- Set board layer (csr.ctrl.layer)
- Reset PLL (csr.ctrl.pll_rst)
- Program PLL
- Different program for layer 0 and layer 1 boards
- Check frequency (freq_ctr)
Planes
- Reset registers (csr.ctrl.soft_rst)
- Disable MMCM (set csr.ctrl.rst_mmcm)
- Reset idelayctrl (csr.ctrl.rst_idelayctrl)
- Check that idelayctrl is locked (csr.stat.idelayctrl_rdy)
- Reset PLL (io.csr.ctrl.clkgen_rst)
- Program PLL
- Check for PLL lock (io.csr.stat.clkgen_lol)
- Check frequency (io.freq_ctr)
- Enable MMCM (unset csr.ctrl.rst_mmcm)
- Check MMCM lock (csr.stat.mmcm_locked)
- {Do setup for channels, triggers, thresholds, sequencer, etc}
Startup procedure step 2 (from warm start, or following step 1)
Planes
- Enable external sync (set daq.timing.csr.ctrl.en_ext_sync)
- Enable pipeline (set daq.timing.csr.ctrl.pipeline_en)
- Enable readout buffer (set daq.roc.csr.ctrl.en)
Timing board (master)
- Issue the sync (set sync_ctrl.en_sync)
Planes
- {do all the board-by-board trigger link enabling stuff, and check status}
Starting a run
Planes
- {Enable triggers}
Stopping a run
Planes
- {Disable triggers}
- {Wait for buffers to empty}
Shutdown procedure step 1
Planes
- Disable pipeline (unset daq.timing.csr.ctrl.pipeline_en)
- Disable buffer (unset daq.roc.csr.ctrl.en)
[At this point, you can change settings and re-start from startup procedure step 2]
Shutdown procedure step 2 (if you really want to start over without power cycling)
All boards
- Nuke the suckers (csr.ctrl.nuke for timing, csr.ctrl.nuke for planes)
......@@ -72,20 +72,10 @@ architecture rtl of payload is
signal trig_in_ds, trig_i,trig_i_masked: std_logic_vector(9 downto 0);
signal trig_ir: std_logic;
signal ctr: unsigned(BLK_RADIX - 1 downto 0);
signal sync_out_ctr, trig_out_ctr , trig_in_ctr : unsigned(31 downto 0) := ( others => '0' );
signal trig_ir_d1 , trig_ir_d2 : std_logic := '0';
signal rst_counters : std_logic := '0';
signal sync_out_ctr, trig_out_ctr , trig_in_ctr : unsigned(31 downto 0) := ( others => '0' );
signal trig_ir_d1 , trig_ir_d2 : std_logic := '0';
signal rst_counters : std_logic := '0';
-- mark signals for debugging
attribute mark_debug : string;
attribute mark_debug of trig_in_ds: signal is "true";
attribute mark_debug of trig_i_masked: signal is "true";
attribute mark_debug of trig_out_us: signal is "true";
attribute mark_debug of trig_out_ds: signal is "true";
attribute mark_debug of sync_in_us: signal is "true";
attribute mark_debug of sync_out_ds: signal is "true";
attribute mark_debug of ctrl_force_trig_out: signal is "true";
attribute mark_debug of ctrl_en_trig_out: signal is "true";
begin
-- ipbus address decode
......@@ -126,40 +116,34 @@ begin
ctrl_layer <= ctrl(0)(4);
ctrl_trig_in_mask <= ctrl(0)(15 downto 6);
-- Status registers
stat(0) <= X"a753" & FW_REV;
stat(1) <= std_logic_vector(sync_out_ctr);
stat(2) <= std_logic_vector(trig_out_ctr);
stat(3) <= std_logic_vector(trig_in_ctr);
stat(0) <= X"a753" & FW_REV;
stat(1) <= std_logic_vector(sync_out_ctr);
stat(2) <= std_logic_vector(trig_out_ctr);
stat(3) <= std_logic_vector(trig_in_ctr);
-- trigger and sync Counters
process(clki)
begin
if rising_edge(clki) then
if rst_counters = '1' then
sync_out_ctr <= (others => '0');
trig_out_ctr <= (others => '0');
trig_in_ctr <= (others => '0');
else
if sync_out_ds = '1' then
sync_out_ctr <= sync_out_ctr + 1;
end if;
if trig_out_ds = '1' then
trig_out_ctr <= trig_out_ctr + 1;
end if;
-- look for rising edge of incoming trigger
if trig_ir_d1 = '1' and trig_ir_d2 = '0' then
trig_in_ctr <= trig_in_ctr + 1;
end if;
end if;
trig_ir_d1 <= or_reduce(trig_i and ctrl_trig_in_mask);
trig_ir_d2 <= trig_ir_d1;
end if;
process(clki)
begin
if rising_edge(clki) then
if rst_counters = '1' then
sync_out_ctr <= (others => '0');
trig_out_ctr <= (others => '0');
trig_in_ctr <= (others => '0');
else
if sync_out_ds = '1' then
sync_out_ctr <= sync_out_ctr + 1;
end if;
if trig_out_ds = '1' then
trig_out_ctr <= trig_out_ctr + 1;
end if;
if trig_ir_d1 = '1' and trig_ir_d2 = '0' then
trig_in_ctr <= trig_in_ctr + 1;
end if;
end if;
trig_ir_d1 <= or_reduce(trig_i and ctrl_trig_in_mask);
trig_ir_d2 <= trig_ir_d1;
end if;
end process;
-- Sync ctrl
......@@ -182,7 +166,7 @@ begin
ctrl_en_sync <= sync_ctrl(0)(0);
ctrl_en_trig_out <= sync_ctrl(0)(1);
ctrl_force_trig_out <= sync_ctrl(0)(2) and stb(0);
rst_counters <= sync_ctrl(0)(3) and stb(0);
rst_counters <= sync_ctrl(0)(3) and stb(0);
-- General IO
......@@ -214,8 +198,9 @@ begin
end if;
end process;
-- ctrl_layer =0 --> sync,trig are controlled by local FPGA.
-- ctrl_layer=1 --> sync,trig are conrolled from upstream HDMI
-- ctrl_layer =0 --> sync,trig are controlled by local FPGA.
-- ctrl_layer=1 --> sync,trig are conrolled from upstream HDMI
sync_sel <= not ctrl_layer; -- Set sync_sel=1 for output sync to be
-- driven by FPGA. Set sync_sel=0 to be
-- driven from upstream
......
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