--- /dev/null
+-- taken from www.stefanvhdl.com/vhdl/vhdl/txt_util.vhd\r
+\r
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use std.textio.all;\r
+\r
+\r
+package txt_util is\r
+\r
+ -- prints a message to the screen\r
+ procedure print(text: string);\r
+\r
+ -- prints the message when active\r
+ -- useful for debug switches\r
+ procedure print(active: boolean; text: string);\r
+\r
+ -- converts std_logic into a character\r
+ function chr(sl: std_logic) return character;\r
+\r
+ -- converts std_logic into a string (1 to 1)\r
+ function str(sl: std_logic) return string;\r
+\r
+ -- converts std_logic_vector into a string (binary base)\r
+ function str(slv: std_logic_vector) return string;\r
+\r
+ -- converts boolean into a string\r
+ function str(b: boolean) return string;\r
+\r
+ -- converts an integer into a single character\r
+ -- (can also be used for hex conversion and other bases)\r
+ function chr(int: integer) return character;\r
+\r
+ -- converts integer into string using specified base\r
+ function str(int: integer; base: integer) return string;\r
+\r
+ -- converts integer to string, using base 10\r
+ function str(int: integer) return string;\r
+\r
+ -- convert std_logic_vector into a string in hex format\r
+ function hstr(slv: std_logic_vector) return string;\r
+\r
+\r
+ -- functions to manipulate strings\r
+ -----------------------------------\r
+\r
+ -- convert a character to upper case\r
+ function to_upper(c: character) return character;\r
+\r
+ -- convert a character to lower case\r
+ function to_lower(c: character) return character;\r
+\r
+ -- convert a string to upper case\r
+ function to_upper(s: string) return string;\r
+\r
+ -- convert a string to lower case\r
+ function to_lower(s: string) return string;\r
+\r
+ \r
+ \r
+ -- functions to convert strings into other formats\r
+ --------------------------------------------------\r
+ \r
+ -- converts a character into std_logic\r
+ function to_std_logic(c: character) return std_logic; \r
+ \r
+ -- converts a string into std_logic_vector\r
+ function to_std_logic_vector(s: string) return std_logic_vector; \r
+\r
+\r
+ \r
+ -- file I/O\r
+ -----------\r
+ \r
+ -- read variable length string from input file\r
+ procedure str_read(file in_file: TEXT; \r
+ res_string: out string);\r
+ \r
+ -- print string to a file and start new line\r
+ procedure print(file out_file: TEXT;\r
+ new_string: in string);\r
+ \r
+ -- print character to a file and start new line\r
+ procedure print(file out_file: TEXT;\r
+ char: in character);\r
+ \r
+end txt_util;\r
+\r
+\r
+\r
+\r
+package body txt_util is\r
+\r
+\r
+\r
+\r
+ -- prints text to the screen\r
+\r
+ procedure print(text: string) is\r
+ variable msg_line: line;\r
+ begin\r
+ write(msg_line, text);\r
+ writeline(output, msg_line);\r
+ end print;\r
+\r
+\r
+\r
+\r
+ -- prints text to the screen when active\r
+\r
+ procedure print(active: boolean; text: string) is\r
+ begin\r
+ if active then\r
+ print(text);\r
+ end if;\r
+ end print;\r
+\r
+\r
+ -- converts std_logic into a character\r
+\r
+ function chr(sl: std_logic) return character is\r
+ variable c: character;\r
+ begin\r
+ case sl is\r
+ when 'U' => c:= 'U';\r
+ when 'X' => c:= 'X';\r
+ when '0' => c:= '0';\r
+ when '1' => c:= '1';\r
+ when 'Z' => c:= 'Z';\r
+ when 'W' => c:= 'W';\r
+ when 'L' => c:= 'L';\r
+ when 'H' => c:= 'H';\r
+ when '-' => c:= '-';\r
+ end case;\r
+ return c;\r
+ end chr;\r
+\r
+\r
+\r
+ -- converts std_logic into a string (1 to 1)\r
+\r
+ function str(sl: std_logic) return string is\r
+ variable s: string(1 to 1);\r
+ begin\r
+ s(1) := chr(sl);\r
+ return s;\r
+ end str;\r
+\r
+\r
+\r
+ -- converts std_logic_vector into a string (binary base)\r
+ -- (this also takes care of the fact that the range of\r
+ -- a string is natural while a std_logic_vector may\r
+ -- have an integer range)\r
+\r
+ function str(slv: std_logic_vector) return string is\r
+ variable result : string (1 to slv'length);\r
+ variable r : integer;\r
+ begin\r
+ r := 1;\r
+ for i in slv'range loop\r
+ result(r) := chr(slv(i));\r
+ r := r + 1;\r
+ end loop;\r
+ return result;\r
+ end str;\r
+\r
+\r
+ function str(b: boolean) return string is\r
+\r
+ begin\r
+ if b then\r
+ return "true";\r
+ else\r
+ return "false";\r
+ end if;\r
+ end str;\r
+\r
+\r
+ -- converts an integer into a character\r
+ -- for 0 to 9 the obvious mapping is used, higher\r
+ -- values are mapped to the characters A-Z\r
+ -- (this is usefull for systems with base > 10)\r
+ -- (adapted from Steve Vogwell's posting in comp.lang.vhdl)\r
+\r
+ function chr(int: integer) return character is\r
+ variable c: character;\r
+ begin\r
+ case int is\r
+ when 0 => c := '0';\r
+ when 1 => c := '1';\r
+ when 2 => c := '2';\r
+ when 3 => c := '3';\r
+ when 4 => c := '4';\r
+ when 5 => c := '5';\r
+ when 6 => c := '6';\r
+ when 7 => c := '7';\r
+ when 8 => c := '8';\r
+ when 9 => c := '9';\r
+ when 10 => c := 'A';\r
+ when 11 => c := 'B';\r
+ when 12 => c := 'C';\r
+ when 13 => c := 'D';\r
+ when 14 => c := 'E';\r
+ when 15 => c := 'F';\r
+ when 16 => c := 'G';\r
+ when 17 => c := 'H';\r
+ when 18 => c := 'I';\r
+ when 19 => c := 'J';\r
+ when 20 => c := 'K';\r
+ when 21 => c := 'L';\r
+ when 22 => c := 'M';\r
+ when 23 => c := 'N';\r
+ when 24 => c := 'O';\r
+ when 25 => c := 'P';\r
+ when 26 => c := 'Q';\r
+ when 27 => c := 'R';\r
+ when 28 => c := 'S';\r
+ when 29 => c := 'T';\r
+ when 30 => c := 'U';\r
+ when 31 => c := 'V';\r
+ when 32 => c := 'W';\r
+ when 33 => c := 'X';\r
+ when 34 => c := 'Y';\r
+ when 35 => c := 'Z';\r
+ when others => c := '?';\r
+ end case;\r
+ return c;\r
+ end chr;\r
+\r
+\r
+\r
+ -- convert integer to string using specified base\r
+ -- (adapted from Steve Vogwell's posting in comp.lang.vhdl)\r
+\r
+ function str(int: integer; base: integer) return string is\r
+\r
+ variable temp: string(1 to 10);\r
+ variable num: integer;\r
+ variable abs_int: integer;\r
+ variable len: integer := 1;\r
+ variable power: integer := 1;\r
+\r
+ begin\r
+\r
+ -- bug fix for negative numbers\r
+ abs_int := abs(int);\r
+\r
+ num := abs_int;\r
+\r
+ while num >= base loop -- Determine how many\r
+ len := len + 1; -- characters required\r
+ num := num / base; -- to represent the\r
+ end loop ; -- number.\r
+\r
+ for i in len downto 1 loop -- Convert the number to\r
+ temp(i) := chr(abs_int/power mod base); -- a string starting\r
+ power := power * base; -- with the right hand\r
+ end loop ; -- side.\r
+\r
+ -- return result and add sign if required\r
+ if int < 0 then\r
+ return '-'& temp(1 to len);\r
+ else\r
+ return temp(1 to len);\r
+ end if;\r
+\r
+ end str;\r
+\r
+\r
+ -- convert integer to string, using base 10\r
+ function str(int: integer) return string is\r
+\r
+ begin\r
+\r
+ return str(int, 10) ;\r
+\r
+ end str;\r
+\r
+\r
+\r
+ -- converts a std_logic_vector into a hex string.\r
+ function hstr(slv: std_logic_vector) return string is\r
+ variable hexlen: integer;\r
+ variable longslv : std_logic_vector(67 downto 0) := (others => '0');\r
+ variable hex : string(1 to 16);\r
+ variable fourbit : std_logic_vector(3 downto 0);\r
+ begin\r
+ hexlen := (slv'left+1)/4;\r
+ if (slv'left+1) mod 4 /= 0 then\r
+ hexlen := hexlen + 1;\r
+ end if;\r
+ longslv(slv'left downto 0) := slv;\r
+ for i in (hexlen -1) downto 0 loop\r
+ fourbit := longslv(((i*4)+3) downto (i*4));\r
+ case fourbit is\r
+ when "0000" => hex(hexlen -I) := '0';\r
+ when "0001" => hex(hexlen -I) := '1';\r
+ when "0010" => hex(hexlen -I) := '2';\r
+ when "0011" => hex(hexlen -I) := '3';\r
+ when "0100" => hex(hexlen -I) := '4';\r
+ when "0101" => hex(hexlen -I) := '5';\r
+ when "0110" => hex(hexlen -I) := '6';\r
+ when "0111" => hex(hexlen -I) := '7';\r
+ when "1000" => hex(hexlen -I) := '8';\r
+ when "1001" => hex(hexlen -I) := '9';\r
+ when "1010" => hex(hexlen -I) := 'A';\r
+ when "1011" => hex(hexlen -I) := 'B';\r
+ when "1100" => hex(hexlen -I) := 'C';\r
+ when "1101" => hex(hexlen -I) := 'D';\r
+ when "1110" => hex(hexlen -I) := 'E';\r
+ when "1111" => hex(hexlen -I) := 'F';\r
+ when "ZZZZ" => hex(hexlen -I) := 'z';\r
+ when "UUUU" => hex(hexlen -I) := 'u';\r
+ when "XXXX" => hex(hexlen -I) := 'x';\r
+ when others => hex(hexlen -I) := '?';\r
+ end case;\r
+ end loop;\r
+ return hex(1 to hexlen);\r
+ end hstr;\r
+\r
+\r
+\r
+ -- functions to manipulate strings\r
+ -----------------------------------\r
+\r
+\r
+ -- convert a character to upper case\r
+\r
+ function to_upper(c: character) return character is\r
+\r
+ variable u: character;\r
+\r
+ begin\r
+\r
+ case c is\r
+ when 'a' => u := 'A';\r
+ when 'b' => u := 'B';\r
+ when 'c' => u := 'C';\r
+ when 'd' => u := 'D';\r
+ when 'e' => u := 'E';\r
+ when 'f' => u := 'F';\r
+ when 'g' => u := 'G';\r
+ when 'h' => u := 'H';\r
+ when 'i' => u := 'I';\r
+ when 'j' => u := 'J';\r
+ when 'k' => u := 'K';\r
+ when 'l' => u := 'L';\r
+ when 'm' => u := 'M';\r
+ when 'n' => u := 'N';\r
+ when 'o' => u := 'O';\r
+ when 'p' => u := 'P';\r
+ when 'q' => u := 'Q';\r
+ when 'r' => u := 'R';\r
+ when 's' => u := 'S';\r
+ when 't' => u := 'T';\r
+ when 'u' => u := 'U';\r
+ when 'v' => u := 'V';\r
+ when 'w' => u := 'W';\r
+ when 'x' => u := 'X';\r
+ when 'y' => u := 'Y';\r
+ when 'z' => u := 'Z';\r
+ when others => u := c;\r
+ end case;\r
+\r
+ return u;\r
+\r
+ end to_upper;\r
+\r
+\r
+ -- convert a character to lower case\r
+\r
+ function to_lower(c: character) return character is\r
+\r
+ variable l: character;\r
+\r
+ begin\r
+\r
+ case c is\r
+ when 'A' => l := 'a';\r
+ when 'B' => l := 'b';\r
+ when 'C' => l := 'c';\r
+ when 'D' => l := 'd';\r
+ when 'E' => l := 'e';\r
+ when 'F' => l := 'f';\r
+ when 'G' => l := 'g';\r
+ when 'H' => l := 'h';\r
+ when 'I' => l := 'i';\r
+ when 'J' => l := 'j';\r
+ when 'K' => l := 'k';\r
+ when 'L' => l := 'l';\r
+ when 'M' => l := 'm';\r
+ when 'N' => l := 'n';\r
+ when 'O' => l := 'o';\r
+ when 'P' => l := 'p';\r
+ when 'Q' => l := 'q';\r
+ when 'R' => l := 'r';\r
+ when 'S' => l := 's';\r
+ when 'T' => l := 't';\r
+ when 'U' => l := 'u';\r
+ when 'V' => l := 'v';\r
+ when 'W' => l := 'w';\r
+ when 'X' => l := 'x';\r
+ when 'Y' => l := 'y';\r
+ when 'Z' => l := 'z';\r
+ when others => l := c;\r
+ end case;\r
+\r
+ return l;\r
+\r
+ end to_lower;\r
+\r
+\r
+\r
+ -- convert a string to upper case\r
+\r
+ function to_upper(s: string) return string is\r
+\r
+ variable uppercase: string (s'range);\r
+\r
+ begin\r
+\r
+ for i in s'range loop\r
+ uppercase(i):= to_upper(s(i));\r
+ end loop;\r
+ return uppercase;\r
+\r
+ end to_upper;\r
+\r
+\r
+\r
+ -- convert a string to lower case\r
+\r
+ function to_lower(s: string) return string is\r
+\r
+ variable lowercase: string (s'range);\r
+\r
+ begin\r
+\r
+ for i in s'range loop\r
+ lowercase(i):= to_lower(s(i));\r
+ end loop;\r
+ return lowercase;\r
+\r
+ end to_lower;\r
+\r
+\r
+\r
+-- functions to convert strings into other types\r
+\r
+\r
+-- converts a character into a std_logic\r
+\r
+function to_std_logic(c: character) return std_logic is \r
+ variable sl: std_logic;\r
+ begin\r
+ case c is\r
+ when 'U' => \r
+ sl := 'U'; \r
+ when 'X' =>\r
+ sl := 'X';\r
+ when '0' => \r
+ sl := '0';\r
+ when '1' => \r
+ sl := '1';\r
+ when 'Z' => \r
+ sl := 'Z';\r
+ when 'W' => \r
+ sl := 'W';\r
+ when 'L' => \r
+ sl := 'L';\r
+ when 'H' => \r
+ sl := 'H';\r
+ when '-' => \r
+ sl := '-';\r
+ when others =>\r
+ sl := 'X'; \r
+ end case;\r
+ return sl;\r
+ end to_std_logic;\r
+\r
+\r
+-- converts a string into std_logic_vector\r
+\r
+function to_std_logic_vector(s: string) return std_logic_vector is \r
+ variable slv: std_logic_vector(s'high-s'low downto 0);\r
+ variable k: integer;\r
+begin\r
+ k := s'high-s'low;\r
+ for i in s'range loop\r
+ slv(k) := to_std_logic(s(i));\r
+ k := k - 1;\r
+ end loop;\r
+ return slv;\r
+end to_std_logic_vector; \r
+ \r
+ \r
+ \r
+ \r
+ \r
+ \r
+----------------\r
+-- file I/O --\r
+----------------\r
+\r
+\r
+\r
+-- read variable length string from input file\r
+ \r
+procedure str_read(file in_file: TEXT; \r
+ res_string: out string) is\r
+ \r
+ variable l: line;\r
+ variable c: character;\r
+ variable is_string: boolean;\r
+ \r
+ begin\r
+ \r
+ readline(in_file, l);\r
+ -- clear the contents of the result string\r
+ for i in res_string'range loop\r
+ res_string(i) := ' ';\r
+ end loop; \r
+ -- read all characters of the line, up to the length \r
+ -- of the results string\r
+ for i in res_string'range loop\r
+ read(l, c, is_string);\r
+ res_string(i) := c;\r
+ if not is_string then -- found end of line\r
+ exit;\r
+ end if; \r
+ end loop; \r
+ \r
+end str_read;\r
+\r
+\r
+-- print string to a file\r
+procedure print(file out_file: TEXT;\r
+ new_string: in string) is\r
+ \r
+ variable l: line;\r
+ \r
+ begin\r
+ \r
+ write(l, new_string);\r
+ writeline(out_file, l);\r
+ \r
+end print;\r
+\r
+\r
+-- print character to a file and start new line\r
+procedure print(file out_file: TEXT;\r
+ char: in character) is\r
+ \r
+ variable l: line;\r
+ \r
+ begin\r
+ \r
+ write(l, char);\r
+ writeline(out_file, l);\r
+ \r
+end print;\r
+\r
+\r
+\r
+-- appends contents of a string to a file until line feed occurs\r
+-- (LF is considered to be the end of the string)\r
+\r
+procedure str_write(file out_file: TEXT; \r
+ new_string: in string) is\r
+ begin\r
+ \r
+ for i in new_string'range loop\r
+ print(out_file, new_string(i));\r
+ if new_string(i) = LF then -- end of string\r
+ exit;\r
+ end if;\r
+ end loop; \r
+ \r
+end str_write;\r
+\r
+\r
+\r
+\r
+end txt_util;\r
+\r
+\r
+\r
+\r
FILLED_IN : in std_logic;
FILLED_OUT : out std_logic
);
+ end component;
+
+ component pos_edge_strech_sync is
+ generic (
+ LENGTH : positive := 2
+ );
+ port (
+ IN_CLK_IN : std_logic;
+ DATA_IN : std_logic;
+ OUT_CLK_IN : std_logic;
+ DATA_OUT : std_logic
+ );
+ end component;
+
+ component cbmnet_sync_module is
+ port(
+ -- TRB
+ TRB_CLK_IN : in std_logic;
+ TRB_RESET_IN : in std_logic;
+ TRB_TRIGGER_OUT: out std_logic;
+
+ --data output for read-out
+ TRB_TRIGGER_IN : in std_logic;
+ TRB_RDO_VALID_IN : in std_logic;
+ TRB_RDO_DATA_OUT : out std_logic_vector(31 downto 0);
+ TRB_RDO_WRITE_OUT : out std_logic;
+ TRB_RDO_STATUSBIT_OUT: out std_logic_vector(31 downto 0);
+ TRB_RDO_FINISHED_OUT : out std_logic;
+
+ -- reg io
+ TRB_REGIO_ADDR_IN : in std_logic_vector(15 downto 0);
+ TRB_REGIO_DATA_IN : in std_logic_vector(31 downto 0);
+ TRB_REGIO_READ_ENABLE_IN : in std_logic;
+ TRB_REGIO_WRITE_ENABLE_IN : in std_logic;
+ TRB_REGIO_DATA_OUT : out std_logic_vector(31 downto 0);
+ TRB_REGIO_DATAREADY_OUT : out std_logic;
+ TRB_REGIO_WRITE_ACK_OUT : out std_logic;
+ TRB_REGIO_UNKNOWN_ADDR_OUT : out std_logic;
+
+ -- CBMNET
+ CBM_CLK_IN : in std_logic;
+ CBM_RESET_IN : in std_logic;
+ CBM_PHY_BARREL_SHIFTER_POS_IN : in std_logic_vector(3 downto 0);
+
+ -- DLM port
+ CBM_DLM_REC_IN : in std_logic_vector(3 downto 0);
+ CBM_DLM_REC_VALID_IN : in std_logic;
+ CBM_DLM_SENSE_OUT : out std_logic;
+ CBM_PULSER_OUT : out std_logic; -- connect to TDC
+
+ -- Ctrl port
+ CBM_CTRL_DATA_IN : in std_logic_vector(15 downto 0);
+ CBM_CTRL_DATA_START_IN : in std_logic;
+ CBM_CTRL_DATA_END_IN : in std_logic;
+ CBM_CTRL_DATA_STOP_OUT : out std_logic;
+
+ DEBUG_OUT : out std_logic_vector(31 downto 0)
+ );
end component;
end package cbmnet_interface_pkg;
CTRL_OP : in std_logic_vector ( 15 downto 0) := (others => '0');
DEBUG_OUT : out std_logic_vector (511 downto 0) := (others => '0')
);
+
+ attribute BLOCKNET : boolean;
+ attribute BLOCKNET of DEBUG_OUT : signal is true;
end entity;
architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is
-- Placer Directives
- attribute HGROUP : string;
- -- for whole architecture
- attribute HGROUP of cbmnet_phy_ecp3_arch : architecture is "cbmnet_phy_group";
-
- attribute syn_hier: string;
- attribute syn_hier of cbmnet_phy_ecp3_arch : architecture is "hard";
-
-
- attribute syn_sharing : string;
- attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off";
+-- attribute syn_hier: string;
+-- attribute syn_hier of cbmnet_phy_ecp3_arch : architecture is "hard";
+--
+--
+-- attribute syn_sharing : string;
+-- attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off";
constant WA_FIXATION : integer := c_YES;
signal DETERMINISTIC_LATENCY_C : std_logic;
end entity;
architecture CBMNET_PHY_RX_GEAR_ARCH of CBMNET_PHY_RX_GEAR is
- attribute HGROUP : string;
- attribute HGROUP of CBMNET_PHY_RX_GEAR_ARCH : architecture is "cbmnet_phy_rx_gear";
+-- attribute HGROUP : string;
+-- attribute HGROUP of CBMNET_PHY_RX_GEAR_ARCH : architecture is "cbmnet_phy_rx_gear";
type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_LOCK_WAIT1, FSM_LOCK_WAIT2, FSM_LOCK_WAIT3, FSM_RESET, FSM_LOCKED);
signal data_in_buf_i : std_logic_vector( 8 downto 0);
-
+ signal delay_clock_x_i : std_logic;
+
signal delay_clock_buf_i : std_logic;
signal delay_clock_buf1_i : std_logic;
signal last_delay_clock_i : std_logic := '0';
RESET_OUT <= '1';
reset_timer_i <= '0';
delay_clock_i <= '0';
+ delay_clock_x_i <= delay_clock_i;
case (fsm_i) is
when FSM_START =>
-- Implement the 2:1 gearing and clock down-sampling
--delay_clock_buf1_i <= delay_clock_i when rising_edge(CLK_250_IN);
- delay_clock_buf_i <= delay_clock_i when rising_edge(CLK_250_IN);
+ delay_clock_buf_i <= delay_clock_x_i when rising_edge(CLK_250_IN);
proc_ctrl_gear: process
CLK_125_OUT <= clk_125_i; -- when rising_edge(CLK_250_IN);
DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i);
- DEBUG_OUT(4) <= delay_clock_i;
+ --DEBUG_OUT(4) <= delay_clock_i;
DEBUG_OUT(5) <= indi_alignment_i;
DEBUG_OUT(6) <= indi_misalignment_i;
end entity;
architecture CBMNET_PHY_TX_GEAR_ARCH of CBMNET_PHY_TX_GEAR is
- attribute HGROUP : string;
- attribute HGROUP of CBMNET_PHY_TX_GEAR_ARCH : architecture is "cbmnet_phy_tx_gear";
+-- attribute HGROUP : string;
+-- attribute HGROUP of CBMNET_PHY_TX_GEAR_ARCH : architecture is "cbmnet_phy_tx_gear";
- type FSM_STATES is (FSM_HIGH, FSM_LOW);
+ type FSM_STATES is (FSM_LOCKING, FSM_HIGH, FSM_LOW);
signal fsm_i : FSM_STATES;
signal data_in_buf125_i : std_logic_vector(17 downto 0);
+ signal data_in_buf125_0_i : std_logic_vector(17 downto 0);
signal data_in_buf250_i : std_logic_vector(17 downto 0);
signal data_in_buf250_0_i : std_logic_vector(17 downto 0);
process is begin
wait until rising_edge(CLK_250_IN);
- if RESET_IN='1' then
- delay_counter_i <= TO_UNSIGNED(0,16);
- end if;
-
data_in_buf250_0_i <= data_in_buf125_i;
data_in_buf250_i <= data_in_buf250_0_i;
- clk_125_xfer_buf_i <= clk_125_xfer_i;
+ clk_125_xfer_buf_i <= CLK_125_IN;
clk_125_xfer_del_i <= clk_125_xfer_buf_i;
CLK_125_OUT <= '0';
-- end if;
- when others =>
+ when FSM_LOW =>
DATA_OUT <= delay_data_i;
fsm_i <= FSM_HIGH;
+
+ when others =>
+ if clk_125_xfer_del_i = '0' and clk_125_xfer_buf_i = '1' then
+ fsm_i <= FSM_HIGH;
+ end if;
end case;
+
+ if RESET_IN='1' then
+ fsm_i <= FSM_LOCKING;
+ end if;
end process;
TX_READY_OUT <= not RESET_IN;
process is begin
wait until rising_edge(CLK_125_IN);
-
- data_in_buf125_i <= DATA_IN;
- clk_125_xfer_i <= not clk_125_xfer_i;
+ data_in_buf125_0_i <= DATA_IN;
+ data_in_buf125_i <= data_in_buf125_0_i;
end process;
DEBUG_OUT <= (others => '0'); -- x"0000" & STD_LOGIC_VECTOR( delay_counter_i );
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+
+entity CBMNET_READOUT_EVENT_PACKER is
+ port (
+ -- TrbNet
+ CLK_IN : in std_logic;
+ RESET_IN : in std_logic;
+
+ -- connect to hub
+ HUB_CTS_NUMBER_IN : in std_logic_vector (15 downto 0);
+ HUB_CTS_CODE_IN : in std_logic_vector (7 downto 0);
+ HUB_CTS_INFORMATION_IN : in std_logic_vector (7 downto 0);
+ HUB_CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0);
+ GBE_CTS_STATUS_BITS_IN : in std_logic_vector (31 downto 0);
+
+
+ -- connect to decoder
+ DEC_EVT_INFO_IN : in std_logic_vector(31 downto 0);
+ DEC_LENGTH_IN : in std_logic_vector(15 downto 0);
+ DEC_SOURCE_IN : in std_logic_vector(15 downto 0);
+ DEC_DATA_IN : in std_logic_vector(15 downto 0);
+ DEC_DATA_READY_IN : in std_logic;
+ DEC_ACTIVE_IN : in std_logic;
+ DEC_ERROR_IN : in std_logic;
+
+ DEC_DATA_READ_OUT : out std_logic;
+ DEC_RESET_OUT : out std_logic;
+
+ -- connect to fifo
+ WADDR_STORE_OUT : out std_logic;
+ WADDR_RESTORE_OUT: out std_logic;
+ WDATA_OUT : out std_logic_vector(17 downto 0);
+ WENQUEUE_OUT : out std_logic;
+ WPACKET_COMPLETE_OUT: out std_logic;
+ WFULL_IN : in std_logic;
+
+ DEBUG_OUT : out std_logic_vector(31 downto 0)
+ );
+end entity;
+
+architecture cbmnet_readout_event_packer_arch of CBMNET_READOUT_EVENT_PACKER is
+ type FSM_STATES_T is (
+ WAIT_FOR_IDLE, IDLE,
+ HDR_SIZE_H, HDR_SIZE_L,
+ HDR_DECODING_H, HDR_DECODING_L,
+ HDR_ID_H, HDR_ID_L,
+ HDR_NUMBER_H, HDR_NUMBER_L,
+ PAYLOAD,
+ TRL_TRAILER_H, TRL_TRAILER_L,
+ TRL_STATUS_H, TRL_STATUS_L
+ );
+
+ type FSM_STATES_ENC_T is array(FSM_STATES_T) of std_logic_vector(3 downto 0);
+ constant fsm_states_enc_c : FSM_STATES_ENC_T := (
+ WAIT_FOR_IDLE => x"0",
+ IDLE => x"1",
+ HDR_SIZE_H => x"2",
+ HDR_SIZE_L => x"3",
+ HDR_DECODING_H=> x"4",
+ HDR_DECODING_L=> x"5",
+ HDR_ID_H => x"6",
+ HDR_ID_L => x"7",
+ HDR_NUMBER_H => x"8",
+ HDR_NUMBER_L => x"9",
+ PAYLOAD => x"a",
+ TRL_TRAILER_H => x"b",
+ TRL_TRAILER_L => x"c",
+ TRL_STATUS_H => x"d",
+ TRL_STATUS_L => x"e"
+ );
+
+ signal fsm_i : FSM_STATES_T;
+ signal header_data_i : std_logic_vector(15 downto 0);
+ signal header_enqueue_i : std_logic;
+ signal header_token_i : std_logic_vector(1 downto 0);
+
+ signal copy_payload_i : std_logic;
+
+ signal data_read_i, data_read_delayed_i : std_logic;
+
+-- local buffers
+ signal wenqueue_i : std_logic;
+ signal wpacket_complete_i : std_logic;
+ signal waddr_restore_i : std_logic;
+ signal waddr_store_i : std_logic;
+begin
+ THE_PACKER: process is
+ begin
+ wait until rising_edge(CLK_IN);
+
+ waddr_store_i <= '0';
+ waddr_restore_i <= '0';
+ DEC_RESET_OUT <= '0';
+ copy_payload_i <= '0';
+ header_data_i <= (others => '-');
+ header_enqueue_i <= '0';
+ wpacket_complete_i <= '0';
+ header_token_i <= "00";
+
+ if RESET_IN='1' then
+ fsm_i <= WAIT_FOR_IDLE;
+
+ elsif fsm_i /= IDLE and (DEC_ERROR_IN = '1' or WFULL_IN = '1') then
+ waddr_restore_i <= '1';
+ DEC_RESET_OUT <= '1';
+ fsm_i <= WAIT_FOR_IDLE;
+
+ else
+ case(fsm_i) is
+ when WAIT_FOR_IDLE =>
+ if DEC_ACTIVE_IN='0' then
+ fsm_i <= IDLE;
+ end if;
+
+ when IDLE =>
+ if DEC_ACTIVE_IN='1' then
+ waddr_store_i <= '1';
+ fsm_i <= HDR_SIZE_H;
+ end if;
+
+ when HDR_SIZE_H =>
+ header_token_i <= "01";
+ header_data_i <= x"0000";
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_SIZE_L;
+
+ when HDR_SIZE_L =>
+ header_token_i <= "10";
+
+ header_data_i <= STD_LOGIC_VECTOR(UNSIGNED(DEC_LENGTH_IN) + TO_UNSIGNED(16+8, 16)); -- 8 words of SE-Hdr and 4 words for SE-trailer
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_DECODING_H;
+
+ when HDR_DECODING_H =>
+ header_data_i <= x"0002";
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_DECODING_L;
+ when HDR_DECODING_L =>
+ header_data_i <= x"00" & HUB_CTS_READOUT_TYPE_IN & x"1";
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_ID_H;
+
+ when HDR_ID_H =>
+ header_data_i <= x"0000";
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_ID_L;
+ when HDR_ID_L =>
+ header_data_i <= x"beaf";
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_NUMBER_H;
+
+ when HDR_NUMBER_H =>
+ header_data_i <= x"00" & HUB_CTS_NUMBER_IN(15 downto 8);
+ header_enqueue_i <= '1';
+ fsm_i <= HDR_NUMBER_L;
+ when HDR_NUMBER_L =>
+ header_data_i <= HUB_CTS_NUMBER_IN(7 downto 0) & HUB_CTS_CODE_IN;
+ header_enqueue_i <= '1';
+ fsm_i <= PAYLOAD;
+
+ when PAYLOAD =>
+ if DEC_ACTIVE_IN = '0' then
+ fsm_i <= TRL_TRAILER_H;
+ else
+ copy_payload_i <= '1';
+ end if;
+
+ when TRL_TRAILER_H =>
+ header_data_i <= x"0001";
+ header_enqueue_i <= '1';
+ fsm_i <= TRL_TRAILER_L;
+ when TRL_TRAILER_L =>
+ header_data_i <= x"5555";
+ header_enqueue_i <= '1';
+ fsm_i <= TRL_STATUS_H;
+
+ when TRL_STATUS_H =>
+ header_data_i <= GBE_CTS_STATUS_BITS_IN(31 downto 16);
+ header_enqueue_i <= '1';
+ fsm_i <= TRL_STATUS_L;
+ when TRL_STATUS_L =>
+ header_token_i <= "11";
+ header_data_i <= GBE_CTS_STATUS_BITS_IN(15 downto 0);
+ header_enqueue_i <= '1';
+ wpacket_complete_i <= '1';
+ fsm_i <= IDLE;
+
+ end case;
+ end if;
+ end process;
+
+ WDATA_OUT(17 downto 0) <= "00" & DEC_DATA_IN when copy_payload_i='1' else header_token_i & header_data_i;
+ wenqueue_i <= header_enqueue_i or data_read_i;
+
+ data_read_i <= copy_payload_i and DEC_DATA_READY_IN;
+ DEC_DATA_READ_OUT <= data_read_i;
+ data_read_delayed_i <= data_read_i when rising_edge(CLK_IN);
+
+-- Outputs
+ WADDR_STORE_OUT <= waddr_store_i;
+ WADDR_RESTORE_OUT <= waddr_restore_i;
+ WENQUEUE_OUT <= wenqueue_i;
+ WPACKET_COMPLETE_OUT <= wpacket_complete_i;
+
+-- Debug
+ DEBUG_OUT( 3 downto 0) <= fsm_states_enc_c(fsm_i);
+ DEBUG_OUT( 7 downto 4) <= DEC_DATA_READY_IN & DEC_ACTIVE_IN & DEC_ERROR_IN & data_read_i;
+ DEBUG_OUT(11 downto 8) <= wpacket_complete_i & waddr_restore_i & waddr_store_i & wenqueue_i;
+ DEBUG_OUT(15 downto 12) <= "000" & WFULL_IN;
+end architecture;
\ No newline at end of file
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+ use work.cbmnet_interface_pkg.all;
+
+entity cbmnet_sync_module is
+ port(
+ -- TRB
+ TRB_CLK_IN : in std_logic;
+ TRB_RESET_IN : in std_logic;
+ TRB_TRIGGER_OUT: out std_logic;
+
+ --data output for read-out
+ TRB_TRIGGER_IN : in std_logic;
+ TRB_RDO_VALID_IN : in std_logic;
+ TRB_RDO_DATA_OUT : out std_logic_vector(31 downto 0);
+ TRB_RDO_WRITE_OUT : out std_logic;
+ TRB_RDO_STATUSBIT_OUT: out std_logic_vector(31 downto 0);
+ TRB_RDO_FINISHED_OUT : out std_logic;
+
+ -- reg io
+ TRB_REGIO_ADDR_IN : in std_logic_vector(15 downto 0);
+ TRB_REGIO_DATA_IN : in std_logic_vector(31 downto 0);
+ TRB_REGIO_READ_ENABLE_IN : in std_logic;
+ TRB_REGIO_WRITE_ENABLE_IN : in std_logic;
+ TRB_REGIO_DATA_OUT : out std_logic_vector(31 downto 0);
+ TRB_REGIO_DATAREADY_OUT : out std_logic;
+ TRB_REGIO_WRITE_ACK_OUT : out std_logic;
+ TRB_REGIO_UNKNOWN_ADDR_OUT : out std_logic;
+
+ -- CBMNET
+ CBM_CLK_IN : in std_logic;
+ CBM_RESET_IN : in std_logic;
+ CBM_PHY_BARREL_SHIFTER_POS_IN : in std_logic_vector(3 downto 0);
+
+ -- DLM port
+ CBM_DLM_REC_IN : in std_logic_vector(3 downto 0);
+ CBM_DLM_REC_VALID_IN : in std_logic;
+ CBM_DLM_SENSE_OUT : out std_logic;
+ CBM_PULSER_OUT : out std_logic; -- connect to TDC
+
+ -- Ctrl port
+ CBM_CTRL_DATA_IN : in std_logic_vector(15 downto 0);
+ CBM_CTRL_DATA_START_IN : in std_logic;
+ CBM_CTRL_DATA_END_IN : in std_logic;
+ CBM_CTRL_DATA_STOP_OUT : out std_logic;
+
+ DEBUG_OUT : out std_logic_vector(31 downto 0)
+ );
+end entity;
+
+architecture cbmnet_sync_module_arch of cbmnet_sync_module is
+-- DETECT DLMs
+ signal trb_dlm_sense_mask_i : std_logic_vector(15 downto 0);
+ signal cbm_crs_trb_dlm_sense_mask_i : std_logic_vector(15 downto 0);
+
+ signal cbm_dlm_sensed_i : std_logic;
+ signal trb_crs_cbm_dlm_sensed_i : std_logic;
+
+-- EPOCH
+ signal cbm_crs_trb_epoch_update_scheme_i : std_logic_vector(1 downto 0);
+
+ signal cbm_current_epoch_i : std_logic_vector(31 downto 0);
+ signal cbm_current_epoch_updated_i : std_logic;
+
+ signal trb_next_epoch_i : std_logic_vector(31 downto 0);
+ signal trb_next_epoch_updated_i : std_logic;
+
+ signal cbm_next_epoch_i : std_logic_vector(31 downto 0);
+ signal cbm_next_epoch_updated_i : std_logic;
+
+
+ signal cbm_crs_trb_next_epoch_i : std_logic_vector(31 downto 0);
+ signal cbm_crs_trb_next_epoch_updated_i : std_logic;
+ signal trb_crs_cbm_current_epoch_i : std_logic_vector(31 downto 0);
+ signal trb_crs_cbm_current_epoch_updated_i : std_logic;
+
+-- PULSER
+ signal trb_pulser_threshold_i : std_logic_vector(31 downto 0);
+ signal cbm_crs_trb_pulser_threshold_i : unsigned(31 downto 0);
+ signal cbm_pulser_i : unsigned(31 downto 0);
+ signal cbm_pulse_i : std_logic;
+ signal trb_crs_cbm_pulse_i : std_logic;
+
+-- TIMESTAMPS
+ signal trb_timestamp_i : unsigned(31 downto 0);
+ signal trb_timestamp_last_dlm_i : unsigned(31 downto 0);
+ signal trb_timestamp_last_pulse_i : unsigned(31 downto 0);
+ signal trb_reset_counter_i : unsigned(15 downto 0);
+
+ signal cbm_timestamp_i : unsigned(31 downto 0);
+ signal cbm_timestamp_last_dlm_i : unsigned(31 downto 0);
+ signal cbm_timestamp_last_pulse_i : unsigned(31 downto 0);
+ signal cbm_reset_counter_i : unsigned(15 downto 0);
+ signal cbm_dlm_counter_i : unsigned(31 downto 0);
+ signal cbm_pulser_counter_i : unsigned(31 downto 0);
+ signal cbm_epoch_i : std_logic_vector(31 downto 0);
+
+ -- same signals as above, but in trbnet clock domain
+ signal trb_crs_cbm_timestamp_i : unsigned(31 downto 0);
+ signal trb_crs_cbm_timestamp_last_dlm_i : unsigned(31 downto 0);
+ signal trb_crs_cbm_timestamp_last_pulse_i : unsigned(31 downto 0);
+ signal trb_crs_cbm_reset_counter_i : unsigned(15 downto 0);
+ signal trb_crs_cbm_dlm_counter_i : unsigned(31 downto 0);
+ signal trb_crs_cbm_pulser_counter_i : unsigned(31 downto 0);
+
+
+-- CBMNET slow control
+ signal cbm_next_epoch_half_buf_i : std_logic_vector(15 downto 0);
+ type CBM_SLOW_CTRL_FSM_T is (WAIT_FOR_START, SHIFT_LOW_WORD);
+ signal cbm_slow_ctrl_fsm_i : CBM_SLOW_CTRL_FSM_T;
+
+-- TrbNet slow control
+ constant trb_sync_lowest_address_c : integer := 3;
+
+ type TRB_SYNC_BUFFER_T is array (trb_sync_lowest_address_c+1 to trb_sync_lowest_address_c+9) of std_logic_vector(31 downto 0);
+ signal trb_sync_buffer_i : TRB_SYNC_BUFFER_T;
+ signal trb_regio_addr_i : integer range 0 to 15;
+ signal trb_epoch_update_scheme_i : std_logic_vector(1 downto 0);
+
+-- TrbNet read-out
+ type TRB_RDO_BUFFER_T is array (0 to 10) of std_logic_vector(31 downto 0);
+ signal trb_rdo_buffer_i : TRB_RDO_BUFFER_T;
+ type TRB_RDO_FSM_T is (WAIT_FOR_TRIGGER, WAIT_FOR_VALID, COPY_DATA, FINISH);
+ signal trb_rdo_fsm_i : TRB_RDO_FSM_T;
+ signal trb_rdo_fsm_state_i : std_logic_vector(3 downto 0);
+ signal trb_rdo_counter_i : integer range 0 to 16;
+
+
+begin
+-- TRBNet read-out
+ TRBNET_READOUT_PROC: process is
+ variable header_v : std_logic_vector(31 downto 0);
+ begin
+ wait until rising_edge(TRB_CLK_IN);
+ header_v := (others => '0'); -- prevent storage
+
+ TRB_RDO_WRITE_OUT <= '0';
+ TRB_RDO_STATUSBIT_OUT <= (others => '0');
+ TRB_RDO_FINISHED_OUT <= '0';
+ trb_rdo_counter_i <= 0;
+
+ if TRB_RESET_IN='1' then
+ trb_rdo_fsm_i <= WAIT_FOR_TRIGGER;
+ else
+ case (trb_rdo_fsm_i) is
+ when WAIT_FOR_TRIGGER =>
+ trb_rdo_fsm_state_i <= x"0";
+ if TRB_TRIGGER_IN = '1' then
+ -- store data
+ header_v(31 downto 28) := x"1"; -- version
+ header_v(23 downto 8) := trb_pulser_threshold_i(15 downto 0);
+ header_v( 7 downto 4) := CBM_PHY_BARREL_SHIFTER_POS_IN;
+ header_v( 3 downto 0) := trb_crs_cbm_current_epoch_updated_i & "0" & trb_epoch_update_scheme_i;
+
+ trb_rdo_buffer_i( 0) <= header_v;
+ trb_rdo_buffer_i( 1) <= trb_crs_cbm_current_epoch_i;
+ trb_rdo_buffer_i( 2) <= trb_crs_cbm_timestamp_i;
+ trb_rdo_buffer_i( 3) <= trb_crs_cbm_timestamp_last_dlm_i;
+ trb_rdo_buffer_i( 4) <= trb_crs_cbm_timestamp_last_pulse_i;
+ trb_rdo_buffer_i( 5) <= trb_timestamp_i;
+ trb_rdo_buffer_i( 6) <= trb_timestamp_last_dlm_i;
+ trb_rdo_buffer_i( 7) <= trb_timestamp_last_pulse_i;
+ trb_rdo_buffer_i( 8) <= trb_crs_cbm_dlm_counter_i;
+ trb_rdo_buffer_i( 9) <= trb_crs_cbm_pulser_counter_i;
+ trb_rdo_buffer_i(10) <= STD_LOGIC_VECTOR(trb_reset_counter_i) & STD_LOGIC_VECTOR(trb_crs_cbm_reset_counter_i);
+
+ -- fsm
+ trb_rdo_fsm_i <= WAIT_FOR_VALID;
+ elsif TRB_RDO_VALID_IN = '1' then
+ trb_rdo_fsm_i <= FINISH;
+
+ end if;
+
+ when WAIT_FOR_VALID =>
+ trb_rdo_fsm_state_i <= x"1";
+ if TRB_RDO_VALID_IN = '1' then
+ trb_rdo_fsm_i <= COPY_DATA;
+ end if;
+
+ when COPY_DATA =>
+ trb_rdo_fsm_state_i <= x"2";
+ TRB_RDO_DATA_OUT <= trb_rdo_buffer_i(trb_rdo_counter_i);
+ TRB_RDO_WRITE_OUT <= '1';
+
+ if trb_rdo_counter_i = TRB_RDO_DATA_OUT'high then
+ trb_rdo_fsm_i <= FINISH;
+ end if;
+ trb_rdo_counter_i <= trb_rdo_counter_i + 1;
+
+ when FINISH =>
+ trb_rdo_fsm_state_i <= x"3";
+ TRB_RDO_FINISHED_OUT <= '1';
+ trb_rdo_fsm_i <= WAIT_FOR_TRIGGER;
+
+
+ end case;
+ end if;
+ end process;
+
+-- TRBNet slow control
+ trb_regio_addr_i <= to_integer(UNSIGNED(TRB_REGIO_ADDR_IN(3 downto 0)));
+
+ TRB_SLOW_CTRL_PROC: process is
+ begin
+ wait until rising_edge(TRB_CLK_IN);
+
+ TRB_REGIO_DATAREADY_OUT <= TRB_REGIO_READ_ENABLE_IN;
+ TRB_REGIO_WRITE_ACK_OUT <= TRB_REGIO_WRITE_ENABLE_IN;
+ TRB_REGIO_UNKNOWN_ADDR_OUT <= '0';
+ TRB_REGIO_DATA_OUT <= (others => '0');
+
+ if trb_crs_cbm_dlm_sensed_i = '1' then
+ trb_next_epoch_updated_i <= '0';
+ end if;
+
+ if TRB_RESET_IN = '1' then
+ trb_dlm_sense_mask_i <= x"0000";
+ trb_epoch_update_scheme_i <= "00";
+ trb_pulser_threshold_i <= (others => '0');
+
+ trb_next_epoch_updated_i <= '0';
+ trb_next_epoch_i <= x"deadc0de";
+
+ else
+ case (trb_regio_addr_i) is
+ when 0 =>
+ TRB_REGIO_DATA_OUT(31 downto 16) <= trb_dlm_sense_mask_i;
+ TRB_REGIO_DATA_OUT(11 downto 8) <= trb_rdo_fsm_state_i;
+ TRB_REGIO_DATA_OUT(4) <= trb_crs_cbm_current_epoch_updated_i;
+ TRB_REGIO_DATA_OUT( 3 downto 0) <= "00" & trb_epoch_update_scheme_i;
+
+ when 1 =>
+ TRB_REGIO_DATA_OUT <= trb_pulser_threshold_i;
+
+ when 2 =>
+ TRB_REGIO_DATA_OUT <= trb_next_epoch_i;
+
+ when trb_sync_lowest_address_c =>
+ TRB_REGIO_DATA_OUT <= trb_crs_cbm_current_epoch_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+1) <= trb_crs_cbm_timestamp_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+2) <= trb_crs_cbm_timestamp_last_dlm_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+3) <= trb_crs_cbm_timestamp_last_pulse_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+4) <= trb_timestamp_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+5) <= trb_timestamp_last_dlm_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+6) <= trb_timestamp_last_pulse_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+7) <= trb_crs_cbm_dlm_counter_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+8) <= trb_crs_cbm_pulser_counter_i;
+ trb_sync_buffer_i(trb_sync_lowest_address_c+9) <= STD_LOGIC_VECTOR(trb_reset_counter_i) & STD_LOGIC_VECTOR(trb_crs_cbm_reset_counter_i);
+
+ when trb_sync_lowest_address_c + 1 to trb_sync_lowest_address_c + trb_sync_buffer_i'high =>
+ TRB_REGIO_DATA_OUT <= trb_sync_buffer_i(trb_regio_addr_i);
+
+ when others =>
+ TRB_REGIO_UNKNOWN_ADDR_OUT <= TRB_REGIO_READ_ENABLE_IN or TRB_REGIO_WRITE_ENABLE_IN;
+
+ end case;
+
+ if TRB_REGIO_WRITE_ENABLE_IN = '1' then
+ case (trb_regio_addr_i) is
+ when 0 =>
+ trb_dlm_sense_mask_i <= TRB_REGIO_DATA_IN(31 downto 16);
+ trb_epoch_update_scheme_i <= TRB_REGIO_DATA_IN(1 downto 0);
+
+ when 1 =>
+ trb_pulser_threshold_i <= TRB_REGIO_DATA_IN;
+
+ when 2 =>
+ trb_next_epoch_i <= TRB_REGIO_DATA_IN;
+ trb_next_epoch_updated_i <= '1';
+
+ when others =>
+ TRB_REGIO_UNKNOWN_ADDR_OUT <= '1';
+ end case;
+ end if;
+ end if;
+ end process;
+
+-- CBMNet slow control
+ CBMNET_SLOW_CTRL_PROC: process is
+ begin
+ wait until rising_edge(CBM_CLK_IN);
+
+ if CBM_RESET_IN = '1' then
+ CBM_CTRL_DATA_STOP_OUT <= '1';
+ cbm_next_epoch_updated_i <= '0';
+ cbm_slow_ctrl_fsm_i <= WAIT_FOR_START;
+
+ else
+ CBM_CTRL_DATA_STOP_OUT <= '0';
+ case cbm_slow_ctrl_fsm_i is
+ when WAIT_FOR_START =>
+ if CBM_CTRL_DATA_START_IN = '1' then
+ cbm_next_epoch_half_buf_i <= CBM_CTRL_DATA_IN;
+ cbm_slow_ctrl_fsm_i <= SHIFT_LOW_WORD;
+ end if;
+
+ when SHIFT_LOW_WORD =>
+ cbm_slow_ctrl_fsm_i <= WAIT_FOR_START;
+ if CBM_CTRL_DATA_END_IN = '1' then
+ cbm_next_epoch_i <= cbm_next_epoch_half_buf_i & CBM_CTRL_DATA_IN;
+ cbm_next_epoch_updated_i <= '1';
+ end if;
+ end case;
+
+ if cbm_dlm_sensed_i = '1' then
+ cbm_next_epoch_updated_i <= '0';
+ end if;
+ end if;
+ end process;
+
+-- CBMNet DLM selection
+ CBM_DLM_SENSE_PROC: process is
+ variable dlm_v : integer range 0 to 15;
+ variable sensed_v : std_logic;
+ begin
+ wait until rising_edge(CBM_CLK_IN);
+
+ dlm_v := to_integer(UNSIGNED(CBM_DLM_REC_IN));
+ sensed_v := cbm_crs_trb_dlm_sense_mask_i(dlm_v) and CBM_DLM_REC_VALID_IN;
+ cbm_dlm_sensed_i <= sensed_v;
+
+ if CBM_RESET_IN='1' then
+ cbm_dlm_counter_i <= 0;
+ elsif sensed_v='1' then
+ cbm_dlm_counter_i <= cbm_dlm_counter_i + 1;
+ end if;
+ end process;
+
+ CBM_DLM_SENSE_OUT <= cbm_dlm_sensed_i;
+
+ CBM_EPOCH_PROC: process is
+ begin
+ wait until rising_edge(CBM_CLK_IN);
+
+ if CBM_RESET_IN = '1' then
+ cbm_current_epoch_updated_i <= '0';
+ cbm_current_epoch_i <= (others => '0');
+
+ elsif cbm_dlm_sensed_i = '1' then
+ case cbm_crs_trb_epoch_update_scheme_i is
+ when "01" => -- TRB defined
+ cbm_current_epoch_i <= cbm_crs_trb_next_epoch_i;
+ cbm_current_epoch_updated_i <= cbm_crs_trb_next_epoch_updated_i;
+
+ when "10" => -- CBM defined
+ cbm_current_epoch_i <= cbm_next_epoch_i;
+ cbm_current_epoch_updated_i <= cbm_next_epoch_updated_i;
+
+ when others =>
+ cbm_current_epoch_i <= STD_LOGIC_VECTOR(UNSIGNED(cbm_current_epoch_i) + TO_UNSIGNED(1,32));
+ cbm_current_epoch_updated_i <= '1';
+
+ end case;
+ end if;
+ end process;
+
+-- TIMESTAMPS
+ CBM_CLOCK_PROC: process is
+ variable last_reset_v : std_logic := '1';
+ begin
+ wait until rising_edge(CBM_CLK_IN);
+ if CBM_RESET_IN='1' then
+ cbm_timestamp_i <= (others => '0');
+ if last_reset_v = '0' then
+ cbm_reset_counter_i <= cbm_reset_counter_i + 1;
+ end if;
+ else
+ if cbm_dlm_sensed_i = '1' then
+ cbm_timestamp_last_dlm_i <= cbm_timestamp_i;
+ end if;
+
+ cbm_timestamp_i <= cbm_timestamp_i + 1;
+ end if;
+ last_reset_v := CBM_RESET_IN;
+ end process;
+
+ CBM_PULSER_PROC: process is
+ begin
+ wait until rising_edge(CBM_CLK_IN);
+
+ cbm_crs_trb_pulser_threshold_i <= trb_pulser_threshold_i;
+ cbm_pulse_i <= '0';
+
+ if CBM_RESET_IN='1' then
+ cbm_pulser_counter_i <= 0;
+ end if;
+
+
+ if CBM_RESET_IN='1' or cbm_crs_trb_pulser_threshold_i=x"00000000" then
+ cbm_pulser_i <= 0;
+
+ elsif cbm_pulser_i = cbm_crs_trb_pulser_threshold_i then
+ cbm_pulser_i <= 0;
+ cbm_pulser_counter_i <= cbm_pulser_counter_i + 1;
+ cbm_timestamp_last_pulse_i <= cbm_timestamp_i;
+ cbm_pulse_i <= '1';
+
+ elsif cbm_pulser_i > cbm_crs_trb_pulser_threshold_i then
+ cbm_pulser_i <= 0;
+
+ else
+ cbm_pulser_i <= cbm_pulser_i + 1;
+
+ end if;
+ end process;
+ CBM_PULSER_OUT <= cbm_pulse_i;
+
+ TRB_CLOCK_PROC: process is
+ variable last_reset_v : std_logic := '1';
+ begin
+ wait until rising_edge(TRB_CLK_IN);
+ if TRB_RESET_IN='1' then
+ trb_timestamp_i <= (others => '0');
+ if last_reset_v = '0' then
+ trb_reset_counter_i <= trb_reset_counter_i + 1;
+ end if;
+ else
+ if trb_crs_cbm_dlm_sensed_i = '1' then
+ trb_timestamp_last_dlm_i <= trb_timestamp_i;
+ end if;
+
+ if trb_crs_cbm_pulse_i = '1' then
+ trb_timestamp_last_pulse_i <= trb_timestamp_i;
+ end if;
+
+ trb_timestamp_i <= trb_timestamp_i + 1;
+ end if;
+ last_reset_v := TRB_RESET_IN;
+ end process;
+
+-- Clock Domain Crossing CBM -> TRB
+ THE_PULSE_SYNC: pos_edge_strech_sync port map (
+ IN_CLK_IN => CBM_CLK_IN, OUT_CLK_IN => TRB_CLK_IN,
+ DATA_IN => cbm_pulse_i,
+ DATA_OUT => trb_crs_cbm_pulse_i
+ );
+
+ THE_DLM_SENSE_SYNC: pos_edge_strech_sync port map (
+ IN_CLK_IN => CBM_CLK_IN, OUT_CLK_IN => TRB_CLK_IN,
+ DATA_IN => cbm_dlm_sensed_i,
+ DATA_OUT => trb_crs_cbm_dlm_sensed_i
+ );
+
+ trb_crs_cbm_timestamp_i <= cbm_timestamp_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_timestamp_last_dlm_i <= cbm_timestamp_last_dlm_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_reset_counter_i <= cbm_reset_counter_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_dlm_counter_i <= cbm_dlm_counter_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_pulser_counter_i <= cbm_pulser_counter_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_timestamp_last_pulse_i <= cbm_timestamp_last_pulse_i when rising_edge(TRB_CLK_IN);
+
+ trb_crs_cbm_current_epoch_i <= cbm_current_epoch_i when rising_edge(TRB_CLK_IN);
+ trb_crs_cbm_current_epoch_updated_i <= cbm_current_epoch_updated_i when rising_edge(TRB_CLK_IN);
+
+-- Clock Domain Crossing TRB -> CBM
+ cbm_crs_trb_epoch_update_scheme_i <= trb_epoch_update_scheme_i when rising_edge(CBM_CLK_IN);
+ cbm_crs_trb_next_epoch_i <= trb_next_epoch_i when rising_edge(CBM_CLK_IN);
+ cbm_crs_trb_next_epoch_updated_i <= trb_next_epoch_updated_i when rising_edge(CBM_CLK_IN);
+ cbm_crs_trb_dlm_sense_mask_i <= trb_dlm_sense_mask_i when rising_edge(CBM_CLK_IN);
+
+
+end architecture;
\ No newline at end of file
--- /dev/null
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.numeric_std.all;
+ use work.trb_net_std.all;
+
+entity pos_edge_strech_sync is
+ generic (
+ LENGTH : positive := 2
+ );
+ port (
+ IN_CLK_IN : std_logic;
+ DATA_IN : std_logic;
+ OUT_CLK_IN : std_logic;
+ DATA_OUT : std_logic
+ );
+end entity;
+
+architecture RTL of pos_edge_strech_sync is
+ signal in_buffer_i : std_logic_vector(LENGTH - 1 downto 0);
+ signal in_buffer_aggr_i : std_logic;
+ signal out_buffer_i : std_logic;
+begin
+ in_buffer_i <= in_buffer_i(LENGTH-2 downto 0) & DATA_IN when rising_edge(OUT_CLK_IN);
+ in_buffer_aggr_i <= OR_ALL(in_buffer_i);
+
+ out_buffer_i <= not out_buffer_i and in_buffer_aggr_i when rising_edge(OUT_CLK_IN);
+end architecture;
\ No newline at end of file