Commit 02b0e7c2 authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

Add configurable pulse counter generation and timestamp logic

- added g_with_pulse_cnt
- added g_with_pulse_timetag
- added SR.PMISSE bit for each of the six channels
- made logic more customizable for g_nr_chans < 6
- doc: added reminder to treat board switches in Overview section
parent 108561a8
......@@ -197,6 +197,8 @@ the conversion between the two interfaces.
\caption{\label{fig:block-diagram} Block diagram of common gateware}
\end{figure}
\textcolor{red}{\textbf{SWITCHES CONVENTION}}
%==============================================================================
% SEC: Clocking
%==============================================================================
......
......@@ -46,8 +46,8 @@ entity conv_regs is
reg_sr_i2c_err_i : in std_logic;
reg_sr_i2c_err_load_o : out std_logic;
-- Ports for BIT field: 'Pulse missed error' in reg: 'SR'
reg_sr_pmisse_o : out std_logic;
reg_sr_pmisse_i : in std_logic;
reg_sr_pmisse_o : out std_logic_vector(5 downto 0);
reg_sr_pmisse_i : in std_logic_vector(5 downto 0);
reg_sr_pmisse_load_o : out std_logic;
-- Ports for BIT field: 'Reset unlock bit' in reg: 'CR'
reg_cr_rst_unlock_o : out std_logic;
......@@ -270,12 +270,7 @@ begin
rddata_reg(22) <= reg_sr_i2c_wdto_i;
rddata_reg(23) <= reg_sr_wrpres_i;
rddata_reg(24) <= reg_sr_i2c_err_i;
rddata_reg(25) <= reg_sr_pmisse_i;
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(30 downto 25) <= reg_sr_pmisse_i;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
......@@ -1024,7 +1019,7 @@ begin
-- I2C communication error
reg_sr_i2c_err_o <= wrdata_reg(24);
-- Pulse missed error
reg_sr_pmisse_o <= wrdata_reg(25);
reg_sr_pmisse_o <= wrdata_reg(30 downto 25);
-- Reset unlock bit
reg_cr_rst_unlock_o <= wrdata_reg(0);
-- Reset bit
......
......@@ -131,9 +131,13 @@ peripheral {
name = "Pulse missed error";
description = "1 -- pulse arrived during pulse rejection phase \
0 -- idle \
This bit can be cleared by writing a '1' to it";
Bit 0 -- CH1 \
Bit 1 -- CH2 \
etc. \
Each bit can be cleared by writing a '1' to it";
prefix = "pmisse";
type = BIT;
type = SLV;
size = 6;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
......
......@@ -62,27 +62,33 @@ entity conv_common_gw is
generic
(
-- Number of repeater channels
g_nr_chans : integer := 6;
g_nr_chans : integer := 6;
-- Board ID -- 4-letter ASCII string indicating the board ID
-- see [1] for example
g_board_id : std_logic_vector(31 downto 0);
g_board_id : std_logic_vector(31 downto 0);
-- Gateware version
g_gwvers : std_logic_vector(7 downto 0);
g_gwvers : std_logic_vector(7 downto 0);
-- Generate pulse repetition logic with fixed output pulse width
g_pgen_fixed_width : boolean;
g_pgen_fixed_width : boolean;
-- Pulse width at pulse generator output (valid with fixed output pulse width)
g_pgen_pwidth : natural range 20 to 40 := 24;
g_pgen_pwidth : natural range 20 to 40 := 24;
-- Duty cycle divider ratio for pulse generator
-- output pulse will be limited to 1/g_pgen_duty_cycle_div
g_pgen_duty_cycle_div : natural := 5;
g_pgen_duty_cycle_div : natural := 5;
-- Pulse generator glitch filter length in number of clk_20_i cycles
g_pgen_gf_len : integer := 4;
g_pgen_gf_len : integer := 4;
-- Generate logic with pulse counters
g_with_pulse_cnt : boolean;
-- Generate logic with pulse counters
g_with_pulse_timetag : boolean;
-- Bicolor LED controller signals
g_bicolor_led_columns : integer := 6;
g_bicolor_led_lines : integer := 2
g_bicolor_led_columns : integer := 6;
g_bicolor_led_lines : integer := 2
);
port
(
......@@ -126,6 +132,7 @@ entity conv_common_gw is
led_i2c_err_o : out std_logic;
-- VME interface
vme_sysreset_n_i : in std_logic;
vme_ga_i : in std_logic_vector(4 downto 0);
vme_gap_i : in std_logic;
......@@ -182,9 +189,10 @@ architecture arch of conv_common_gw is
--============================================================================
-- Type declarations
--============================================================================
type t_pulse_led_cnt is array(0 to g_nr_chans-1) of unsigned(18 downto 0);
type t_pulse_cnt is array(0 to g_nr_chans-1) of unsigned(31 downto 0);
type t_ch_pcr is array(0 to g_nr_chans-1) of std_logic_vector(31 downto 0);
-- Max. channel count of 6 enforced here:
type t_pulse_led_cnt is array(5 downto 0) of unsigned(18 downto 0);
type t_pulse_cnt is array(5 downto 0) of unsigned(31 downto 0);
type t_ch_pcr is array(5 downto 0) of std_logic_vector(31 downto 0);
--============================================================================
-- Constant declarations
......@@ -211,6 +219,12 @@ architecture arch of conv_common_gw is
c_slv_multiboot => f_sdb_embed_device(c_xwb_xil_multiboot_sdb, c_addr_multiboot)
);
-- Tag bufferdata width: 40 -- TAI
-- 28 -- cycles
-- 1 -- WRPRES bit
-- xx -- channel mask
constant c_tagbuff_data_width : positive := 40 + 28 + 1 + g_nr_chans;
--============================================================================
-- Signal declarations
--============================================================================
......@@ -218,6 +232,7 @@ architecture arch of conv_common_gw is
signal clk_125 : std_logic;
signal rst_125_n : std_logic;
signal rst_20_n : std_logic;
signal rst_ext : std_logic;
-- Pulse logic signals
signal trig_a : std_logic_vector(g_nr_chans-1 downto 0);
......@@ -229,6 +244,7 @@ architecture arch of conv_common_gw is
signal pulse_outp : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_d0 : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_redge_p : std_logic_vector(g_nr_chans-1 downto 0);
signal pmisse_p : std_logic_vector(g_nr_chans-1 downto 0);
-- Output enable signals
signal global_oen : std_logic;
......@@ -254,8 +270,8 @@ architecture arch of conv_common_gw is
signal i2c_wdto_bit : std_logic;
signal i2c_wdto_bit_rst : std_logic;
signal i2c_wdto_bit_rst_ld : std_logic;
signal pmisse_bit : std_logic;
signal pmisse_bit_rst : std_logic;
signal pmisse_bit : std_logic_vector(5 downto 0);
signal pmisse_bit_rst : std_logic_vector(5 downto 0);
signal pmisse_bit_rst_ld : std_logic;
signal pulse_cnt : t_pulse_cnt;
signal ch_pcr : t_ch_pcr;
......@@ -270,6 +286,9 @@ architecture arch of conv_common_gw is
signal i2c_err_bit : std_logic;
signal i2c_err_bit_rst : std_logic;
signal i2c_err_bit_rst_ld : std_logic;
signal line_front : std_logic_vector(5 downto 0);
signal line_rear : std_logic_vector(5 downto 0);
signal line_rear_fs : std_logic_vector(5 downto 0);
-- LED signals
signal led_pulse : std_logic_vector(g_nr_chans-1 downto 0);
......@@ -285,14 +304,49 @@ architecture arch of conv_common_gw is
signal xbar_master_in : t_wishbone_master_in_array (c_nr_slaves-1 downto 0);
signal xbar_master_out : t_wishbone_master_out_array(c_nr_slaves-1 downto 0);
-- Time-tagging component signals
signal tm_cycles : std_logic_vector(27 downto 0);
signal tm_tai : std_logic_vector(39 downto 0);
signal buf_wr_req_p : std_logic;
signal buf_rd_req_p : std_logic;
signal buf_count : std_logic_vector(f_log2_size(128)-1 downto 0);
signal buf_full : std_logic;
signal buf_empty : std_logic;
signal buf_chan : std_logic_vector(g_nr_chans-1 downto 0);
signal buf_wrtag : std_logic;
signal buf_clr_bit : std_logic;
signal buf_clr_bit_ld : std_logic;
signal buf_clr_p : std_logic;
signal buf_dat_in : std_logic_vector(c_tagbuff_data_width-1 downto 0);
signal buf_dat_out : std_logic_vector(c_tagbuff_data_width-1 downto 0);
--==============================================================================
-- architecture begin
--==============================================================================
begin
--============================================================================
-- Differential input buffer for 125 MHz clock
--============================================================================
cmp_clk_125_buf : IBUFGDS
generic map (
DIFF_TERM => true, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting
-- for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map (
O => clk_125,
I => clk_125_p_i,
IB => clk_125_n_i
);
--============================================================================
-- Internal and external reset generation
--============================================================================
-- External reset input to reset generator
rst_ext <= rst_fr_reg or (not vme_sysreset_n_i);
-- Configure reset generator for 100ms power-on reset
cmp_reset_gen : conv_reset_gen
generic map
......@@ -303,13 +357,27 @@ begin
port map
(
clk_i => clk_20_i,
rst_i => rst_fr_reg,
rst_i => rst_ext,
rst_n_o => rst_20_n
);
-- Output reset signal is synchronous to the 20 MHz clock
rst_n_o <= rst_20_n;
-- And synchronize the 20 MHz domain reset into the 125 MHz domain
cmp_sync_rst : gc_sync_ffs
generic map
(
g_sync_edge => "positive"
)
port map
(
clk_i => clk_125,
rst_n_i => '1',
data_i => rst_20_n,
synced_o => rst_125_n
);
--============================================================================
-- Output enable logic
--============================================================================
......@@ -345,137 +413,219 @@ begin
--============================================================================
trig_a <= pulse_i;
gen_pulse_chan_logic : for i in 0 to g_nr_chans-1 generate
-- Synchronize the asynchronous trigger input into the 20 MHz clock
-- domain before passing it to the glitch filter
--
-- Reset value is '1' to avoid pulses being counted by pulse counter on
-- startup, when the board is in TTL-BAR repetition mode.
cmp_trig_sync : gc_sync_ffs
generic map
(
g_sync_edge => "positive"
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
data_i => trig_a(i),
synced_o => trig_synced(i)
);
gen_pulse_timetag : if (g_with_pulse_timetag = true) generate
cmp_pulse_timetag : conv_pulse_timetag
generic map
(
-- Frequency in Hz of the clk_i signal
g_clk_rate => 125000000,
-- Number of repetition channels
g_nr_chan => g_nr_chans
)
port map
(
-- Clock and active-low reset
clk_i => clk_125,
rst_n_i => rst_125_n,
-- Asynchronous pulse input
pulse_a_i => trig_chan,
-- Time inputs from White Rabbit
wr_tm_cycles_i => (others => '0'),
wr_tm_tai_i => (others => '0'),
wr_tm_valid_i => '0',
-- Timing inputs from Wishbone-mapped registers
wb_tm_tai_l_i => tvlr,
wb_tm_tai_l_ld_i => tvlr_ld,
wb_tm_tai_h_i => tvhr,
wb_tm_tai_h_ld_i => tvhr_ld,
-- Timing outputs
tm_cycles_o => tm_cycles,
tm_tai_o => tm_tai,
tm_wrpres_o => buf_wrtag,
chan_o => buf_chan,
-- Ring buffer I/O
buf_wr_req_p_o => buf_wr_req_p
);
-- Deglitch synchronized trigger signal
--
-- Reset value is '1' to avoid pulses being counted by pulse counter on
-- startup, when the board is in TTL-BAR repetition mode.
cmp_inp_glitch_filt : gc_glitch_filt
generic map
(
g_len => g_pgen_gf_len
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
dat_i => trig_synced(i),
dat_o => trig_degl(i)
);
-- Assign ring buffer component inputs
buf_dat_in( 5 downto 0) <= buf_chan;
buf_dat_in( 6) <= buf_wrtag;
buf_dat_in(34 downto 7) <= tm_cycles;
buf_dat_in(74 downto 35) <= tm_tai;
-- Now that we have a deglitched signal, generate the MUX to select between
-- deglitched and direct channel input
trig_chan(i) <= trig_a(i) when (gf_en_n_i = '1') else
trig_degl(i);
-- Now, sync this channel trigger signal before passing it to the counters
--
-- The pulse counter is triggered only by a pulse that actually makes it
-- to the pulse generator.
--
-- NOTE: glitch-filtered signal is also synced in 20MHz clock domain, but
-- another sync chain here avoids extra logic complication and shoudl have
-- no influence on the correctness of the pulse counter value
cmp_sync_ffs : gc_sync_ffs
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
data_i => trig_chan(i),
ppulse_o => trig_chan_redge_p(i)
);
-- Instantiate the ring buffer
cmp_ring_buf : conv_ring_buf
generic map
(
g_data_width => c_tagbuff_data_width,
g_size => 128
)
port map
(
-- Clocks and reset
clk_rd_i => clk_20_i,
clk_wr_i => clk_125,
rst_n_a_i => rst_20_n,
-- Buffer inputs
buf_dat_i => buf_dat_in,
buf_rd_req_i => buf_rd_req_p,
buf_wr_req_i => buf_wr_req_p,
buf_clr_i => buf_clr_p,
-- Buffer outputs
buf_dat_o => buf_dat_out,
buf_full_o => buf_full,
buf_empty_o => buf_empty,
buf_count_o => buf_count
);
end generate gen_pulse_timetag;
-- Then, generate the input pulse counters
p_pulse_cnt : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
pulse_cnt(i) <= (others => '0');
elsif (ch_pcr_ld(i) = '1') then
pulse_cnt(i) <= unsigned(ch_pcr(i));
elsif (trig_chan_redge_p(i) = '1') then
pulse_cnt(i) <= pulse_cnt(i) + 1;
end if;
gen_pulse_chan_logic : for i in 0 to g_nr_chans-1 generate
-- Synchronize the asynchronous trigger input into the 20 MHz clock
-- domain before passing it to the glitch filter
--
-- Reset value is '1' to avoid pulses being counted by pulse counter on
-- startup, when the board is in TTL-BAR repetition mode.
cmp_trig_sync : gc_sync_ffs
generic map
(
g_sync_edge => "positive"
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
data_i => trig_a(i),
synced_o => trig_synced(i)
);
-- Deglitch synchronized trigger signal
--
-- Reset value is '1' to avoid pulses being counted by pulse counter on
-- startup, when the board is in TTL-BAR repetition mode.
cmp_inp_glitch_filt : gc_glitch_filt
generic map
(
g_len => g_pgen_gf_len
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
dat_i => trig_synced(i),
dat_o => trig_degl(i)
);
-- Now that we have a deglitched signal, generate the MUX to select between
-- deglitched and direct channel input
trig_chan(i) <= trig_a(i) when (gf_en_n_i = '1') else
trig_degl(i);
-- Now, sync this channel trigger signal before passing it to the counters
--
-- The pulse counter is triggered only by a pulse that actually makes it
-- to the pulse generator.
--
-- NOTE: glitch-filtered signal is also synced in 20MHz clock domain, but
-- another sync chain here avoids extra logic complication and shoudl have
-- no influence on the correctness of the pulse counter value
cmp_sync_ffs : gc_sync_ffs
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
data_i => trig_chan(i),
ppulse_o => trig_chan_redge_p(i)
);
gen_pulse_cnt : if (g_with_pulse_cnt = true) generate
-- First, the pulse counters for the used channes (up to g_nr_chans)
p_pulse_cnt : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
pulse_cnt(i) <= (others => '0');
elsif (ch_pcr_ld(i) = '1') then
pulse_cnt(i) <= unsigned(ch_pcr(i));
elsif (trig_chan_redge_p(i) = '1') then
pulse_cnt(i) <= pulse_cnt(i) + 1;
end if;
end process p_pulse_cnt;
end if;
end process p_pulse_cnt;
-- The trigger to the pulse generator is either manual OR from the channel input
trig_pgen(i) <= trig_chan(i);
-- Connect pulse counter values for unused channels to all zeroes
gen_pulse_cnt_unused_chans : if (g_nr_chans < 6) generate
pulse_cnt(5 downto g_nr_chans) <= (others => (others => '0'));
end generate gen_pulse_cnt_unused_chans;
-- Instantiate pulse generator block for the channel
cmp_pulse_gen : conv_pulse_gen
generic map
(
g_with_fixed_pwidth => g_pgen_fixed_width,
g_pwidth => g_pgen_pwidth,
g_duty_cycle_div => g_pgen_duty_cycle_div
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
end generate gen_pulse_cnt;
-- The trigger to the pulse generator is either manual OR from the channel input
trig_pgen(i) <= trig_chan(i);
-- Instantiate pulse generator block for the channel
cmp_pulse_gen : conv_pulse_gen
generic map
(
g_with_fixed_pwidth => g_pgen_fixed_width,
g_pwidth => g_pgen_pwidth,
g_duty_cycle_div => g_pgen_duty_cycle_div
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
gf_en_n_i => gf_en_n_i,
gf_en_n_i => gf_en_n_i,
en_i => '1',
en_i => '1',
trig_a_i => trig_pgen(i),
trig_a_i => trig_pgen(i),
pulse_err_p_o => open,
pulse_err_p_o => pmisse_p(i),
pulse_o => pulse_outp(i)
);
pulse_o => pulse_outp(i)
);
-- Process to flash pulse LED when a pulse is output
-- LED flash length: 26 ms
p_pulse_led : process (clk_20_i) is
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
pulse_outp_d0(i) <= '0';
pulse_outp_redge_p(i) <= '0';
led_pulse_cnt(i) <= (others => '0');
led_pulse(i) <= '0';
else
pulse_outp_d0(i) <= pulse_outp(i);
pulse_outp_redge_p(i) <= pulse_outp(i) and (not pulse_outp_d0(i));
case led_pulse(i) is
when '0' =>
if (pulse_outp_redge_p(i) = '1') then
led_pulse(i) <= '1';
end if;
when '1' =>
led_pulse_cnt(i) <= led_pulse_cnt(i) + 1;
if (led_pulse_cnt(i) = (led_pulse_cnt(i)'range => '1')) then
led_pulse(i) <= '0';
end if;
when others =>
-- Process to flash pulse LED when a pulse is output
-- LED flash length: 26 ms
p_pulse_led : process (clk_20_i) is
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
pulse_outp_d0(i) <= '0';
pulse_outp_redge_p(i) <= '0';
led_pulse_cnt(i) <= (others => '0');
led_pulse(i) <= '0';
else
pulse_outp_d0(i) <= pulse_outp(i);
pulse_outp_redge_p(i) <= pulse_outp(i) and (not pulse_outp_d0(i));
case led_pulse(i) is
when '0' =>
if (pulse_outp_redge_p(i) = '1') then
led_pulse(i) <= '1';
end if;
when '1' =>
led_pulse_cnt(i) <= led_pulse_cnt(i) + 1;
if (led_pulse_cnt(i) = (led_pulse_cnt(i)'range => '1')) then
led_pulse(i) <= '0';
end case;
end if;
end if;
when others =>
led_pulse(i) <= '0';
end case;
end if;
end process p_pulse_led;
end if;
end process p_pulse_led;
end generate gen_pulse_chan_logic;
end generate gen_pulse_chan_logic;
-- Channel output assignments
pulse_o <= pulse_outp;
......@@ -640,6 +790,104 @@ begin
-- RTM lines combo
rtm_lines <= rtmp_i & rtmm_i;
-- Adapt line status regs according to number of channels (MAX. 6)
gen_line : if (g_nr_chans = 6) generate
line_front <= line_front_i;
line_rear <= line_rear_i;
line_rear_fs <= line_rear_fs_i;
end generate gen_line;
gen_line_unused_chans : if (g_nr_chans < 6) generate
line_front(g_nr_chans-1 downto 0) <= line_front_i;
line_front(5 downto g_nr_chans) <= (others => '0');
line_rear(g_nr_chans-1 downto 0) <= line_rear_i;
line_rear(5 downto g_nr_chans) <= (others => '0');
line_rear_fs(g_nr_chans-1 downto 0) <= line_rear_fs_i;
line_rear_fs(5 downto g_nr_chans) <= (others => '0');
end generate gen_line_unused_chans;
-- Implement the RST_UNLOCK bit
p_rst_unlock : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
rst_unlock <= '0';
elsif (rst_unlock_bit_ld = '1') then
if (rst_unlock_bit = '1') then
rst_unlock <= '1';
else
rst_unlock <= '0';
end if;
end if;
end if;
end process p_rst_unlock;
-- Implement the reset bit register
-- The register can only be set when the RST_UNLOCK bit is '1'.
p_rst_fr_reg : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
rst_fr_reg <= '0';
elsif (rst_bit_ld = '1') and (rst_bit = '1') and (rst_unlock = '1') then
rst_fr_reg <= '1';
else
rst_fr_reg <= '0';
end if;
end if;
end process p_rst_fr_reg;
-- Register for the PMISSE bits in the SR, set when a channel misses a pulse
-- Each bit is cleared by writing a '1' to it
p_sr_pmisse_bit : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
for i in 0 to g_nr_chans-1 loop
if (rst_20_n = '0') then
pmisse_bit(i) <= '0';
elsif (pmisse_p(i) = '1') then
pmisse_bit(i) <= '1';
elsif (pmisse_bit_rst_ld = '1') and (pmisse_bit_rst(i) = '1') then
pmisse_bit(i) <= '0';
end if;
end loop;
end if;
end process p_sr_pmisse_bit;
-- Set the rest of the PMISSE bits to zero when g_nr_chans < 6
gen_pmisse_unused_chans : if (g_nr_chans < 6) generate
pmisse_bit(5 downto g_nr_chans) <= (others => '0');
end generate;
-- Synchronize WR valid signal to implement the WRPRES bit
cmp_wrpres_sync : gc_sync_ffs
generic map
(
g_sync_edge => "positive"
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
data_i => buf_wrtag,
synced_o => wrpres
);
-- Implement the TBCSR.CLR bit
p_tbcsr_clr : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
buf_clr_p <= '0';
else
buf_clr_p <= '0';
if (buf_clr_bit_ld = '1') and (buf_clr_bit = '1') then
buf_clr_p <= '1';
end if;
end if;
end if;
end process p_tbcsr_clr;
-- Then, instantiate the component
cmp_conv_regs : conv_regs
port map (
......@@ -668,9 +916,9 @@ begin
reg_sr_i2c_err_o => i2c_err_bit_rst,
reg_sr_i2c_err_i => i2c_err_bit,
reg_sr_i2c_err_load_o => i2c_err_bit_rst_ld,
reg_sr_pmisse_o => open,
reg_sr_pmisse_i => '0',
reg_sr_pmisse_load_o => open,
reg_sr_pmisse_o => pmisse_bit_rst,
reg_sr_pmisse_i => pmisse_bit,
reg_sr_pmisse_load_o => pmisse_bit_rst_ld,
reg_cr_rst_unlock_o => rst_unlock_bit,
reg_cr_rst_unlock_i => rst_unlock,
......@@ -700,25 +948,25 @@ begin
reg_ch6pcr_i => std_logic_vector(pulse_cnt(5)),
reg_ch6pcr_load_o => ch_pcr_ld(5),
reg_tvlr_o => open,
reg_tvlr_i => (others => '0'),
reg_tvlr_load_o => open,
reg_tvhr_o => open,
reg_tvhr_i => (others => '0'),
reg_tvhr_load_o => open,
reg_tbmr_chan_i => (others => '0'),
reg_tbmr_wrtag_i => '0',
reg_tb_rd_req_p_o => open,
reg_tbcyr_i => (others => '0'),
reg_tbtlr_i => (others => '0'),
reg_tbthr_i => (others => '0'),
reg_tbcsr_clr_o => open,
reg_tvlr_o => tvlr,
reg_tvlr_i => tm_tai(31 downto 0),
reg_tvlr_load_o => tvlr_ld,
reg_tvhr_o => tvhr,
reg_tvhr_i => tm_tai(39 downto 32),
reg_tvhr_load_o => tvhr_ld,
reg_tbmr_chan_i => buf_dat_out( 5 downto 0),
reg_tbmr_wrtag_i => buf_dat_out( 6),
reg_tb_rd_req_p_o => buf_rd_req_p,
reg_tbcyr_i => buf_dat_out(34 downto 7),
reg_tbtlr_i => buf_dat_out(66 downto 35),
reg_tbthr_i => buf_dat_out(74 downto 67),
reg_tbcsr_clr_o => buf_clr_bit,
reg_tbcsr_clr_i => '0',
reg_tbcsr_clr_load_o => open,
reg_tbcsr_usedw_i => (others => '0'),
reg_tbcsr_full_i => '0',
reg_tbcsr_empty_i => '0',
reg_tbcsr_clr_load_o => buf_clr_bit_ld,
reg_tbcsr_usedw_i => buf_count,
reg_tbcsr_full_i => buf_full,
reg_tbcsr_empty_i => buf_empty,
reg_ch1ltstlr_i => (others => '0'),
reg_ch1ltsthr_tai_i => (others => '0'),
......@@ -739,45 +987,14 @@ begin
reg_ch6ltsthr_tai_i => (others => '0'),
reg_ch6ltsthr_wrtag_i => '0',
reg_lsr_front_ttl_i => line_front_i,
reg_lsr_front_ttl_i => line_front,
reg_lsr_front_invttl_i => line_inv_i,
reg_lsr_rear_i => line_rear_i,
reg_lsr_fs_i => line_rear_fs_i,
reg_lsr_rear_i => line_rear,
reg_lsr_fs_i => line_rear_fs,
reg_mswr_bit_i => sw_multicast_i
);
-- Implement the RST_UNLOCK bit
p_rst_unlock : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
rst_unlock <= '0';
elsif (rst_unlock_bit_ld = '1') then
if (rst_unlock_bit = '1') then
rst_unlock <= '1';
else
rst_unlock <= '0';
end if;
end if;
end if;
end process p_rst_unlock;
-- Implement the reset bit register
-- The register can only be set when the RST_UNLOCK bit is '1'.
p_rst_fr_reg : process (clk_20_i)
begin
if rising_edge(clk_20_i) then
if (rst_20_n = '0') then
rst_fr_reg <= '0';
elsif (rst_bit_ld = '1') and (rst_bit = '1') and (rst_unlock = '1') then
rst_fr_reg <= '1';
else
rst_fr_reg <= '0';
end if;
end if;
end process p_rst_fr_reg;
--============================================================================
-- Instantiate Xilinx MultiBoot module
--============================================================================
......
......@@ -39,6 +39,7 @@ use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.genram_pkg.all;
package conv_common_gw_pkg is
......@@ -70,6 +71,12 @@ package conv_common_gw_pkg is
-- Pulse generator glitch filter length in number of clk_20_i cycles
g_pgen_gf_len : integer := 4;
-- Generate logic with pulse counters
g_with_pulse_cnt : boolean;
-- Generate logic with pulse counters
g_with_pulse_timetag : boolean;
-- Bicolor LED controller signals
g_bicolor_led_columns : integer := 6;
g_bicolor_led_lines : integer := 2
......@@ -116,6 +123,7 @@ package conv_common_gw_pkg is
led_i2c_err_o : out std_logic;
-- VME interface
vme_sysreset_n_i : in std_logic;
vme_ga_i : in std_logic_vector(4 downto 0);
vme_gap_i : in std_logic;
......@@ -266,8 +274,8 @@ package conv_common_gw_pkg is
reg_sr_i2c_err_i : in std_logic;
reg_sr_i2c_err_load_o : out std_logic;
-- Ports for BIT field: 'Pulse missed error' in reg: 'SR'
reg_sr_pmisse_o : out std_logic;
reg_sr_pmisse_i : in std_logic;
reg_sr_pmisse_o : out std_logic_vector(5 downto 0);
reg_sr_pmisse_i : in std_logic_vector(5 downto 0);
reg_sr_pmisse_load_o : out std_logic;
-- Ports for BIT field: 'Reset unlock bit' in reg: 'CR'
reg_cr_rst_unlock_o : out std_logic;
......@@ -400,5 +408,79 @@ package conv_common_gw_pkg is
date => x"20140731",
name => "conv_regs ")));
------------------------------------------------------------------------------
-- Pulse time-tagging component
------------------------------------------------------------------------------
component conv_pulse_timetag is
generic
(
-- Frequency in Hz of the clk_i signal
g_clk_rate : positive := 125000000;
-- Number of repetition channels
g_nr_chan : positive := 6
);
port
(
-- Clock and active-low reset
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Asynchronous pulse input
pulse_a_i : in std_logic_vector(g_nr_chan downto 1);
-- Time inputs from White Rabbit
wr_tm_cycles_i : in std_logic_vector(27 downto 0);
wr_tm_tai_i : in std_logic_vector(39 downto 0);
wr_tm_valid_i : in std_logic;
-- Timing inputs from Wishbone-mapped registers
wb_tm_tai_l_i : in std_logic_vector(31 downto 0);
wb_tm_tai_l_ld_i : in std_logic;
wb_tm_tai_h_i : in std_logic_vector( 7 downto 0);
wb_tm_tai_h_ld_i : in std_logic;
-- Timing outputs
tm_cycles_o : out std_logic_vector(27 downto 0);
tm_tai_o : out std_logic_vector(39 downto 0);
tm_wrpres_o : out std_logic;
chan_o : out std_logic_vector(g_nr_chan downto 1);
-- Ring buffer I/O
buf_wr_req_p_o : out std_logic
);
end component conv_pulse_timetag;
------------------------------------------------------------------------------
-- Ring buffer component
-- use: buffer time stamps generated by the conv_pulse_timetag component
------------------------------------------------------------------------------
component conv_ring_buf is
generic
(
g_data_width : positive;
g_size : positive
);
port
(
-- Clocks and reset
clk_rd_i : in std_logic;
clk_wr_i : in std_logic;
rst_n_a_i : in std_logic;
-- Buffer inputs
buf_dat_i : in std_logic_vector(g_data_width-1 downto 0);
buf_rd_req_i : in std_logic;
buf_wr_req_i : in std_logic;
buf_clr_i : in std_logic;
-- Buffer outputs
buf_dat_o : out std_logic_vector(g_data_width-1 downto 0);
buf_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
buf_full_o : out std_logic;
buf_empty_o : out std_logic
);
end component conv_ring_buf;
end package conv_common_gw_pkg;
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