--- /dev/null
+
+
+--Event data
+-- 0: timestamp lower 32 Bit
+-- 1: timestamp upper 32 Bit
+-- 2: empty word
+-- 3: status flags
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.numeric_std.All;
+
+library work;
+use work.rataser_records.all;
+use work.rataser_sym24word8_util;
+
+entity r3b_timestamp_recv is
+ port(
+ CLK : in std_logic;
+ CLK_SENDER : in std_logic;
+ RESET_IN : in std_logic;
+
+ SERIAL_IN : in std_logic;
+ SERIAL_OUT : out std_logic;
+ TRG_SYNC_OUT : out std_logic;
+
+ --data output for read-out
+ TRIGGER_IN : in std_logic;
+ DATA_OUT : out std_logic_vector(31 downto 0);
+ WRITE_OUT : out std_logic;
+ STATUSBIT_OUT : out std_logic_vector(31 downto 0);
+ FINISHED_OUT : out std_logic;
+ HEADER_REG_OUT : out std_logic_vector( 1 downto 0);
+ --Registers / Debug
+ CONTROL_REG_IN : in std_logic_vector(31 downto 0);
+ STATUS_REG_OUT : out std_logic_vector(31 downto 0) := (others => '0');
+ DEBUG : out std_logic_vector(31 downto 0)
+ );
+end entity;
+
+
+
+architecture arch of r3b_timestamp_recv is
+
+ type state_readout is (RDO_IDLE, RDO_WRITE1, RDO_WRITE2, RDO_WRITE3, RDO_WRITE4, RDO_FINISH);
+ signal rdostate : state_readout := RDO_IDLE;
+
+
+ signal timestamp_i : std_logic_vector(63 downto 0);
+ signal time_since_timestamp : unsigned(31 downto 0);
+ signal status_i : std_logic_vector(31 downto 0);
+
+ signal CONF_time_offset : std_logic_vector(15 downto 0);
+ signal CONF_clear_status_i : std_logic;
+ signal CONF_loopback : std_logic;
+ signal serial_in_i : std_logic;
+ signal serial_out_i : std_logic;
+ signal aux_sigs_i : std_logic_vector(4 downto 0);
+ signal sync_status_i : std_logic_vector(2 downto 0);
+ signal sync_lost_i : std_logic_vector(2 downto 0);
+ signal bad_signals_i : std_logic_vector(4 downto 0);
+ signal sender_timestamp : unsigned(63 downto 0);
+ signal sender_timestamp_upper_enable : std_logic;
+
+ component rataser_clock_recv is
+ generic(
+ period_bits: integer;
+ num_last_edges: integer;
+ pipeline_sym24_diff_in : boolean := true;
+ pipeline_sym24_diff_1 : boolean := false;
+ pipeline_sym24_diff_2 : boolean := false;
+ pipeline_sym24_diff_out : boolean := true;
+ pipeline_sym24_match_out : boolean := false;
+ pipeline_sym24_pick : boolean := false;
+ pipeline_sym24_out : boolean := false;
+ pipeline_hamming_parity : boolean := true;
+ pipeline_hamming_dual : boolean := true);
+ port (
+ clk: in std_logic;
+ clk90: in std_logic;
+ receive: in std_logic;
+ eight_slot: in std_logic;
+ expect_edge: in std_logic_vector(1 downto 0);
+ last_edges: out std_logic_vector(num_last_edges*2-1 downto 0);
+ use_auto_edge: in std_logic;
+ auto_edge: out std_logic_vector(1 downto 0);
+ receive_delay_ns: in std_logic_vector(15 downto 0);
+ tick_ns_lo: out std_logic_vector(31 downto 0);
+ tick_ns_hi: out std_logic_vector(63 downto 32);
+ aux_sigs: out std_logic_vector(4 downto 0);
+ info_bit: out std_logic;
+ msg_strobe: out std_logic;
+ sync_status: out std_logic_vector(2 downto 0);
+ sync_lost: out std_logic_vector(2 downto 0);
+ bad_signals: out std_logic_vector(4 downto 0);
+ clear_status: in std_logic;
+ pulse_period_clks: in std_logic_vector(period_bits-1 downto 0);
+ clk_period_ns: in std_logic_vector(9 downto 0);
+ sym8_debug: out rataser_sym8word1_debug
+ );
+ end component;
+
+ component rataser_clock_send is
+ generic(-- Number of bits for pulse period.
+ period_bits: integer
+ );
+ port (
+ clk: in std_logic;
+ -- Absolute time (the timestamp that is sent).
+ tick_ns: in std_logic_vector(63 downto 0);
+ -- Auxiliary signals.
+ aux_sigs: in std_logic_vector(4 downto 0);
+ -- Auxiliary information.
+ info_bit: in std_logic;
+ -- Pulse period (in clk cycles, controls sender).
+ pulse_period_clks: in std_logic_vector(period_bits-1 downto 0);
+ -- Minimum duty cycle of pulse pause (remaining length after long).
+ duty_low_min_clks: in std_logic_vector(period_bits-1 downto 0);
+ -- Maximum duty cycle of pulse pause (remaining length after short).
+ duty_low_max_clks: in std_logic_vector(period_bits-1 downto 0);
+ -- Use 8 pulses to encode 1 raw bit (for PLL reception).
+ eight_slot: in std_logic;
+ -- Pulse period (in ns, encoded in message).
+ pulse_period_ns: in std_logic_vector(9 downto 0);
+ -- Message delay (in ns, added to time in message).
+ message_delay_ns: in std_logic_vector(21 downto 0);
+ -- Output message.
+ transmit: out std_logic := '0';
+ -- Oscilloscope sync signal for message.
+ transmit_sync: out std_logic := '0'
+ );
+ end component;
+
+
+begin
+
+---------------------------------------------------------------------------
+-- I/O
+---------------------------------------------------------------------------
+serial_in_i <= SERIAL_IN when CONF_loopback = '0' else serial_out_i;
+SERIAL_OUT <= serial_out_i;
+
+
+---------------------------------------------------------------------------
+-- Receiver
+---------------------------------------------------------------------------
+
+THE_RATASER_CLOCK : rataser_clock_recv
+ generic map(
+ period_bits => 1, -- Number of bits for pulse period.
+ num_last_edges => 1 -- Number of edges to report
+ )
+ port map(
+ clk => CLK,
+ clk90 => '0', -- 90 degree phase shifted clock (only needed for eight_slot/4phase).
+
+ receive => serial_in_i, -- Input serial signal.
+
+ eight_slot => '0', -- Use 8 pulses to decode 1 raw bit (for PLL reception).
+ -- The two following only used for 4phase_sample / eight_slot:
+ expect_edge => "00", -- Where is the edge expected?
+ last_edges => open, -- Sequence of edges seen most recently. (For monitoring/setup.), two bits for each edge, most recent in 1 downto 0.
+ use_auto_edge => '0', -- Use routine to automatically lock onto edge. NOTE! This is *NOT* repeatable when signal is at clock edge!
+ auto_edge => open, -- The edge currently determined by the edge tracker.
+
+ receive_delay_ns => CONF_time_offset, -- Reception delay (in ns, added to timestamp).
+
+ tick_ns_lo => timestamp_i(31 downto 0), -- Output timestamp, low 32 bits.
+ tick_ns_hi => timestamp_i(63 downto 32), -- High 32 bits of timestamp, latch one cycle later than low word.
+
+ aux_sigs => aux_sigs_i, -- Aux signals.
+ info_bit => open, -- Auxiliary information.
+ msg_strobe => TRG_SYNC_OUT, -- Strobe signal that we have decoded a new info bit message.
+ sync_status => sync_status_i, -- Report current sync status (0 = pulse, 1 = 24-slot, 2 = time).
+ sync_lost => sync_lost_i, -- Report if any sync status has been lost since clear.
+ bad_signals => bad_signals_i, -- Report different kinds of protocol issues since clear.
+ clear_status => CONF_clear_status_i,
+ pulse_period_clks=> (others => '0'), -- When operated behind a PLL, the pulse length (in clock cycles)
+ clk_period_ns => (others => '0'), -- When operated behind a PLL, the frequency must be given.
+
+ sym8_debug => open
+ );
+
+---------------------------------------------------------------------------
+-- Event data output
+---------------------------------------------------------------------------
+ PROC_RDO : process begin
+ wait until rising_edge(CLK);
+ WRITE_OUT <= '0';
+ FINISHED_OUT <= '0';
+ STATUSBIT_OUT <= (others => '0');--(23 => data_status_reg(0), others => '0');
+ DATA_OUT <= x"00000000";
+ case rdostate is
+ when RDO_IDLE =>
+ DATA_OUT <= x"00000000";
+ if TRIGGER_IN = '1' then
+ rdostate <= RDO_WRITE1;
+ end if;
+ when RDO_WRITE1 =>
+ rdostate <= RDO_WRITE2;
+ DATA_OUT <= timestamp_i(31 downto 0);
+ WRITE_OUT <= '1';
+ when RDO_WRITE2 =>
+ rdostate <= RDO_WRITE3;
+ DATA_OUT <= timestamp_i(63 downto 32);
+ WRITE_OUT <= '1';
+ when RDO_WRITE3 =>
+ rdostate <= RDO_WRITE4;
+ DATA_OUT <= (others => '0');
+ WRITE_OUT <= '1';
+ when RDO_WRITE4 =>
+ rdostate <= RDO_FINISH;
+ DATA_OUT <= status_i;
+ WRITE_OUT <= '1';
+ when RDO_FINISH =>
+ FINISHED_OUT <= '1';
+ rdostate <= RDO_IDLE;
+ end case;
+ end process;
+
+
+---------------------------------------------------------------------------
+-- Registers
+---------------------------------------------------------------------------
+ status_i <= "000" & aux_sigs_i
+ & "00000" & sync_status_i
+ & "00000" & sync_lost_i
+ & "000" & bad_signals_i when rising_edge(CLK);
+
+ STATUS_REG_OUT <= status_i;
+
+ CONF_time_offset <= CONTROL_REG_IN(15 downto 0) when rising_edge(CLK);
+ CONF_clear_status_i <= CONTROL_REG_IN(16) when rising_edge(CLK);
+ CONF_loopback <= CONTROL_REG_IN(31) when rising_edge(CLK);
+
+ DEBUG <= x"00000000";
+
+ HEADER_REG_OUT <= b"10"; -- send four words on DATA_OUT
+
+
+---------------------------------------------------------------------------
+-- Dummy timestamp sender
+---------------------------------------------------------------------------
+THE_SENDER: rataser_clock_send
+ generic map(
+ period_bits => 6
+ )
+ port map(
+ clk => CLK,
+ tick_ns => std_logic_vector(sender_timestamp),
+ aux_sigs => "00000",
+ info_bit => '0',
+
+ pulse_period_clks => "100000",
+ duty_low_min_clks => "001000",
+ duty_low_max_clks => "010000",
+ eight_slot => '0',
+
+ pulse_period_ns => 320,
+ message_delay_ns => (others => '0'),
+
+ transmit => serial_out_i,
+ transmit_sync => open
+ );
+
+
+PROC_TIMESTAMP : process begin
+ wait until rising_edge(CLK);
+
+ sender_timestamp(31 downto 0) <= sender_timestamp(31 downto 0) + 10;
+
+ if sender_timestamp_upper_enable = '1' then
+ sender_timestamp(63 downto 32) <= sender_timestamp(63 downto 32) + 1;
+ end if;
+
+ sender_timestamp_upper_enable <= '0';
+ if sender_timestamp(31 downto 0) < 10 then
+ sender_timestamp_upper_enable <= '1';
+ end if;
+
+end process;
+
+
+end architecture;